summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2015-04-11 22:03:59 +0200
committerYves-Alexis Perez <corsac@debian.org>2015-04-11 22:30:17 +0200
commit8404fb0212f9fb77bc53b23004b829b488430700 (patch)
tree23876c7540d138f58a6a7d90793ccf9004f6afd2 /src
parent1b7c683a32c62b6e08ad7bf5af39b9f4edd634f3 (diff)
downloadvyos-strongswan-8404fb0212f9fb77bc53b23004b829b488430700.tar.gz
vyos-strongswan-8404fb0212f9fb77bc53b23004b829b488430700.zip
Imported Upstream version 5.3.0
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile.in13
-rw-r--r--src/_copyright/Makefile.in5
-rw-r--r--src/_updown/Makefile.am1
-rw-r--r--src/_updown/Makefile.in76
-rw-r--r--src/_updown/_updown.816
-rw-r--r--src/_updown/_updown.in201
-rw-r--r--src/_updown_espmark/Makefile.am2
-rw-r--r--src/_updown_espmark/_updown_espmark438
-rw-r--r--src/_updown_espmark/_updown_espmark.815
-rw-r--r--src/aikgen/Makefile.in5
-rw-r--r--src/charon-cmd/Makefile.in5
-rw-r--r--src/charon-nm/Makefile.in5
-rw-r--r--src/charon-nm/nm/nm_backend.c6
-rw-r--r--src/charon-nm/nm/nm_handler.c5
-rw-r--r--src/charon-svc/Makefile.in5
-rw-r--r--src/charon-systemd/Makefile.in5
-rw-r--r--src/charon-systemd/charon-systemd.c28
-rw-r--r--src/charon-tkm/Makefile.in5
-rw-r--r--src/charon-tkm/src/charon-tkm.c4
-rw-r--r--src/charon-tkm/src/ees/ees_callbacks.c22
-rw-r--r--src/charon-tkm/src/tkm/tkm.c4
-rw-r--r--src/charon-tkm/src/tkm/tkm.h8
-rw-r--r--src/charon-tkm/src/tkm/tkm_diffie_hellman.c15
-rw-r--r--src/charon-tkm/src/tkm/tkm_id_manager.c2
-rw-r--r--src/charon-tkm/src/tkm/tkm_kernel_ipsec.c39
-rw-r--r--src/charon-tkm/src/tkm/tkm_kernel_sad.c66
-rw-r--r--src/charon-tkm/src/tkm/tkm_kernel_sad.h19
-rw-r--r--src/charon-tkm/src/tkm/tkm_keymat.c29
-rw-r--r--src/charon-tkm/src/tkm/tkm_listener.c20
-rw-r--r--src/charon-tkm/tests/diffie_hellman_tests.c2
-rw-r--r--src/charon-tkm/tests/kernel_sad_tests.c40
-rw-r--r--src/charon-tkm/tests/keymat_tests.c4
-rw-r--r--src/charon-tkm/tests/tests.c4
-rw-r--r--src/charon/Makefile.in5
-rw-r--r--src/checksum/Makefile.in5
-rw-r--r--src/conftest/Makefile.in5
-rw-r--r--src/conftest/actions.c16
-rw-r--r--src/dumm/Makefile.in5
-rw-r--r--src/dumm/ext/dumm.c4
-rw-r--r--src/include/Makefile.in5
-rw-r--r--src/ipsec/Makefile.in5
-rw-r--r--src/ipsec/_ipsec.817
-rw-r--r--src/ipsec/_ipsec.8.in15
-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.h (renamed from src/libhydra/attributes/attribute_handler.h)20
-rw-r--r--src/libcharon/attributes/attribute_manager.c (renamed from src/libhydra/attributes/attribute_manager.c)39
-rw-r--r--src/libcharon/attributes/attribute_manager.h (renamed from src/libhydra/attributes/attribute_manager.h)27
-rw-r--r--src/libcharon/attributes/attribute_provider.h (renamed from src/libhydra/attributes/attribute_provider.h)14
-rw-r--r--src/libcharon/attributes/attributes.c (renamed from src/libhydra/attributes/attributes.c)0
-rw-r--r--src/libcharon/attributes/attributes.h (renamed from src/libhydra/attributes/attributes.h)0
-rw-r--r--src/libcharon/attributes/mem_pool.c (renamed from src/libhydra/attributes/mem_pool.c)186
-rw-r--r--src/libcharon/attributes/mem_pool.h (renamed from src/libhydra/attributes/mem_pool.h)10
-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.am (renamed from src/libhydra/plugins/attr/Makefile.am)3
-rw-r--r--src/libcharon/plugins/attr/Makefile.in (renamed from src/libhydra/plugins/attr/Makefile.in)14
-rw-r--r--src/libcharon/plugins/attr/attr_plugin.c (renamed from src/libhydra/plugins/attr/attr_plugin.c)10
-rw-r--r--src/libcharon/plugins/attr/attr_plugin.h (renamed from src/libhydra/plugins/attr/attr_plugin.h)2
-rw-r--r--src/libcharon/plugins/attr/attr_provider.c (renamed from src/libhydra/plugins/attr/attr_provider.c)4
-rw-r--r--src/libcharon/plugins/attr/attr_provider.h (renamed from src/libhydra/plugins/attr/attr_provider.h)0
-rw-r--r--src/libcharon/plugins/attr_sql/Makefile.am (renamed from src/libhydra/plugins/attr_sql/Makefile.am)5
-rw-r--r--src/libcharon/plugins/attr_sql/Makefile.in (renamed from src/libhydra/plugins/attr_sql/Makefile.in)20
-rw-r--r--src/libcharon/plugins/attr_sql/attr_sql_plugin.c (renamed from src/libhydra/plugins/attr_sql/attr_sql_plugin.c)16
-rw-r--r--src/libcharon/plugins/attr_sql/attr_sql_plugin.h (renamed from src/libhydra/plugins/attr_sql/attr_sql_plugin.h)4
-rw-r--r--src/libcharon/plugins/attr_sql/attr_sql_provider.c (renamed from src/libhydra/plugins/attr_sql/sql_attribute.c)45
-rw-r--r--src/libcharon/plugins/attr_sql/attr_sql_provider.h (renamed from src/libhydra/plugins/attr_sql/sql_attribute.h)20
-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.in (renamed from src/libcharon/plugins/unit_tester/Makefile.in)111
-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.am (renamed from src/libhydra/plugins/resolve/Makefile.am)1
-rw-r--r--src/libcharon/plugins/resolve/Makefile.in (renamed from src/libhydra/plugins/resolve/Makefile.in)12
-rw-r--r--src/libcharon/plugins/resolve/resolve_handler.c (renamed from src/libhydra/plugins/resolve/resolve_handler.c)11
-rw-r--r--src/libcharon/plugins/resolve/resolve_handler.h (renamed from src/libhydra/plugins/resolve/resolve_handler.h)0
-rw-r--r--src/libcharon/plugins/resolve/resolve_plugin.c (renamed from src/libhydra/plugins/resolve/resolve_plugin.c)11
-rw-r--r--src/libcharon/plugins/resolve/resolve_plugin.h (renamed from src/libhydra/plugins/resolve/resolve_plugin.h)0
-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.in (renamed from src/_updown_espmark/Makefile.in)308
-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__.py (renamed from src/starter/starter.8)0
-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
-rw-r--r--src/libfast/Makefile.in5
-rw-r--r--src/libhydra/Android.mk7
-rw-r--r--src/libhydra/Makefile.am24
-rw-r--r--src/libhydra/Makefile.in73
-rw-r--r--src/libhydra/hydra.c4
-rw-r--r--src/libhydra/hydra.h9
-rw-r--r--src/libhydra/kernel/kernel_interface.c276
-rw-r--r--src/libhydra/kernel/kernel_interface.h76
-rw-r--r--src/libhydra/kernel/kernel_ipsec.h28
-rw-r--r--src/libhydra/kernel/kernel_listener.h13
-rw-r--r--src/libhydra/plugins/kernel_netlink/Makefile.am21
-rw-r--r--src/libhydra/plugins/kernel_netlink/Makefile.in267
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c299
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c46
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c477
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h4
-rw-r--r--src/libhydra/plugins/kernel_netlink/suites/test_socket.c302
-rw-r--r--src/libhydra/plugins/kernel_netlink/tests.c51
-rw-r--r--src/libhydra/plugins/kernel_netlink/tests.h16
-rw-r--r--src/libhydra/plugins/kernel_pfkey/Makefile.in5
-rw-r--r--src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c112
-rw-r--r--src/libhydra/plugins/kernel_pfroute/Makefile.in5
-rw-r--r--src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c9
-rw-r--r--src/libhydra/tests/Makefile.am18
-rw-r--r--src/libhydra/tests/Makefile.in839
-rw-r--r--src/libhydra/tests/hydra_tests.c53
-rw-r--r--src/libhydra/tests/hydra_tests.h14
-rw-r--r--src/libimcv/Makefile.am3
-rw-r--r--src/libimcv/Makefile.in11
-rw-r--r--src/libimcv/imv/data.sql155
-rw-r--r--src/libimcv/imv/imv_agent.c76
-rw-r--r--src/libimcv/imv/imv_database.c111
-rw-r--r--src/libimcv/imv/imv_policy_manager.c76
-rw-r--r--src/libimcv/imv/imv_session.c33
-rw-r--r--src/libimcv/imv/imv_session.h14
-rw-r--r--src/libimcv/imv/imv_session_manager.c40
-rw-r--r--src/libimcv/imv/imv_session_manager.h7
-rw-r--r--src/libimcv/imv/tables-mysql.sql8
-rw-r--r--src/libimcv/imv/tables.sql8
-rw-r--r--src/libimcv/plugins/imc_attestation/Makefile.in5
-rw-r--r--src/libimcv/plugins/imc_attestation/imc_attestation_process.c12
-rw-r--r--src/libimcv/plugins/imc_os/Makefile.in5
-rw-r--r--src/libimcv/plugins/imc_scanner/Makefile.in5
-rw-r--r--src/libimcv/plugins/imc_swid/Makefile.in5
-rw-r--r--src/libimcv/plugins/imc_test/Makefile.in5
-rw-r--r--src/libimcv/plugins/imv_attestation/Makefile.in5
-rw-r--r--src/libimcv/plugins/imv_attestation/attest_db.c18
-rwxr-xr-xsrc/libimcv/plugins/imv_attestation/build-database.sh2
-rw-r--r--src/libimcv/plugins/imv_attestation/imv_attestation_build.c6
-rw-r--r--src/libimcv/plugins/imv_attestation/imv_attestation_process.c8
-rw-r--r--src/libimcv/plugins/imv_os/Makefile.in5
-rw-r--r--src/libimcv/plugins/imv_scanner/Makefile.in5
-rw-r--r--src/libimcv/plugins/imv_swid/Makefile.in5
-rw-r--r--src/libimcv/plugins/imv_test/Makefile.in5
-rw-r--r--src/libimcv/pts/components/ita/ita_comp_tboot.c9
-rw-r--r--src/libimcv/pts/pts.c18
-rw-r--r--src/libimcv/pts/pts.h6
-rw-r--r--src/libimcv/seg/seg_env.c3
-rw-r--r--src/libimcv/seg/seg_env.h2
-rw-r--r--src/libimcv/suites/test_imcv_seg.c12
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c3
-rw-r--r--src/libipsec/Makefile.in5
-rw-r--r--src/libipsec/ip_packet.c2
-rw-r--r--src/libipsec/ipsec_event_listener.h6
-rw-r--r--src/libipsec/ipsec_event_relay.c34
-rw-r--r--src/libipsec/ipsec_event_relay.h6
-rw-r--r--src/libipsec/ipsec_sa.c11
-rw-r--r--src/libipsec/ipsec_sa.h6
-rw-r--r--src/libipsec/ipsec_sa_mgr.c14
-rw-r--r--src/libipsec/ipsec_sa_mgr.h9
-rw-r--r--src/libpttls/Makefile.in5
-rw-r--r--src/libradius/Makefile.in5
-rw-r--r--src/libradius/radius_socket.c87
-rw-r--r--src/libsimaka/Makefile.in5
-rw-r--r--src/libstrongswan/Android.mk2
-rw-r--r--src/libstrongswan/Makefile.am29
-rw-r--r--src/libstrongswan/Makefile.in190
-rw-r--r--src/libstrongswan/asn1/oid.c518
-rw-r--r--src/libstrongswan/asn1/oid.h199
-rw-r--r--src/libstrongswan/asn1/oid.txt22
-rw-r--r--src/libstrongswan/credentials/auth_cfg.c60
-rw-r--r--src/libstrongswan/credentials/auth_cfg.h4
-rw-r--r--src/libstrongswan/credentials/cred_encoding.h4
-rw-r--r--src/libstrongswan/credentials/credential_manager.c3
-rw-r--r--src/libstrongswan/credentials/keys/public_key.c168
-rw-r--r--src/libstrongswan/credentials/keys/public_key.h41
-rw-r--r--src/libstrongswan/credentials/sets/cert_cache.c17
-rw-r--r--src/libstrongswan/credentials/sets/mem_cred.c19
-rw-r--r--src/libstrongswan/credentials/sets/mem_cred.h12
-rw-r--r--src/libstrongswan/crypto/crypters/crypter.c7
-rw-r--r--src/libstrongswan/crypto/crypto_tester.c27
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.c87
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.h30
-rw-r--r--src/libstrongswan/crypto/hashers/hash_algorithm_set.c113
-rw-r--r--src/libstrongswan/crypto/hashers/hash_algorithm_set.h76
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.c102
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.h40
-rw-r--r--src/libstrongswan/crypto/mgf1/mgf1.c (renamed from src/libstrongswan/plugins/ntru/ntru_mgf1.c)42
-rw-r--r--src/libstrongswan/crypto/mgf1/mgf1.h (renamed from src/libstrongswan/plugins/ntru/ntru_mgf1.h)30
-rw-r--r--src/libstrongswan/crypto/mgf1/mgf1_bitspender.c208
-rw-r--r--src/libstrongswan/crypto/mgf1/mgf1_bitspender.h67
-rw-r--r--src/libstrongswan/crypto/pkcs5.c32
-rw-r--r--src/libstrongswan/ipsec/ipsec_types.c10
-rw-r--r--src/libstrongswan/ipsec/ipsec_types.h4
-rw-r--r--src/libstrongswan/library.h3
-rw-r--r--src/libstrongswan/networking/host.c38
-rw-r--r--src/libstrongswan/networking/host.h21
-rw-r--r--src/libstrongswan/networking/host_resolver.c17
-rw-r--r--src/libstrongswan/networking/tun_device.c25
-rw-r--r--src/libstrongswan/networking/tun_device.h4
-rw-r--r--src/libstrongswan/plugins/acert/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/aes/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/af_alg/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_prf.c1
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_signer.c1
-rw-r--r--src/libstrongswan/plugins/agent/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/bliss/Makefile.am54
-rw-r--r--src/libstrongswan/plugins/bliss/Makefile.in862
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_bitpacker.c207
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_bitpacker.h85
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_fft.c199
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_fft.h71
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_fft_params.c215
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_fft_params.h75
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_huffman.c433
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_huffman_code.c42
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_huffman_code.h80
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_huffman_code_1.c160
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_huffman_code_3.c261
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_huffman_code_4.c435
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_huffman_coder.c138
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_huffman_coder.h77
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_param_set.c339
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_param_set.h201
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_plugin.c101
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_plugin.h42
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_private_key.c1316
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_private_key.h62
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_public_key.c515
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_public_key.h101
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_sampler.c250
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_sampler.h94
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_signature.c233
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_signature.h75
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_utils.c167
-rw-r--r--src/libstrongswan/plugins/bliss/bliss_utils.h70
-rw-r--r--src/libstrongswan/plugins/bliss/tests/Makefile.am27
-rw-r--r--src/libstrongswan/plugins/bliss/tests/Makefile.in985
-rw-r--r--src/libstrongswan/plugins/bliss/tests/bliss_tests.c60
-rw-r--r--src/libstrongswan/plugins/bliss/tests/bliss_tests.h23
-rw-r--r--src/libstrongswan/plugins/bliss/tests/suites/test_bliss_bitpacker.c112
-rw-r--r--src/libstrongswan/plugins/bliss/tests/suites/test_bliss_fft.c110
-rw-r--r--src/libstrongswan/plugins/bliss/tests/suites/test_bliss_huffman.c122
-rw-r--r--src/libstrongswan/plugins/bliss/tests/suites/test_bliss_keys.c249
-rw-r--r--src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sampler.c97
-rw-r--r--src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c211
-rw-r--r--src/libstrongswan/plugins/bliss/tests/suites/test_bliss_signature.c141
-rw-r--r--src/libstrongswan/plugins/blowfish/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/ccm/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/cmac/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/cmac/cmac.c3
-rw-r--r--src/libstrongswan/plugins/constraints/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/constraints/constraints_validator.c217
-rw-r--r--src/libstrongswan/plugins/ctr/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/curl/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/des/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/dnskey/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/files/Makefile.am16
-rw-r--r--src/libstrongswan/plugins/files/Makefile.in775
-rw-r--r--src/libstrongswan/plugins/files/files_fetcher.c117
-rw-r--r--src/libstrongswan/plugins/files/files_fetcher.h (renamed from src/libcharon/plugins/unit_tester/tests.h)36
-rw-r--r--src/libstrongswan/plugins/files/files_plugin.c76
-rw-r--r--src/libstrongswan/plugins/files/files_plugin.h (renamed from src/libcharon/plugins/unit_tester/unit_tester.h)28
-rw-r--r--src/libstrongswan/plugins/fips_prf/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf.c7
-rw-r--r--src/libstrongswan/plugins/gcm/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/gcrypt/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_dh.c21
-rw-r--r--src/libstrongswan/plugins/gmp/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c23
-rw-r--r--src/libstrongswan/plugins/hmac/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/hmac/hmac.c3
-rw-r--r--src/libstrongswan/plugins/keychain/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/ldap/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/md4/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/md5/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/mysql/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/nonce/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/ntru/Makefile.am1
-rw-r--r--src/libstrongswan/plugins/ntru/Makefile.in12
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_ke.c38
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_poly.c62
-rw-r--r--src/libstrongswan/plugins/ntru/ntru_trits.c39
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crypter.c2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c21
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c23
-rw-r--r--src/libstrongswan/plugins/padlock/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/pem/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/pem/pem_builder.c25
-rw-r--r--src/libstrongswan/plugins/pem/pem_encoder.c11
-rw-r--r--src/libstrongswan/plugins/pem/pem_plugin.c5
-rw-r--r--src/libstrongswan/plugins/pgp/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/pkcs1/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/pkcs1/pkcs1_builder.c9
-rw-r--r--src/libstrongswan/plugins/pkcs11/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_dh.c30
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_library.c44
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c21
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c50
-rw-r--r--src/libstrongswan/plugins/pkcs12/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/pkcs7/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/pkcs8/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/plugin_loader.c16
-rw-r--r--src/libstrongswan/plugins/pubkey/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/random/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/rc2/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/rdrand/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/revocation/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/sha1/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/sha2/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/soup/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/sqlite/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/sshkey/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/test_vectors/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/unbound/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/winhttp/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.c4
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c2
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.c25
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_request.c6
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_response.c4
-rw-r--r--src/libstrongswan/plugins/x509/x509_pkcs10.c2
-rw-r--r--src/libstrongswan/plugins/xcbc/Makefile.in5
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc.c4
-rw-r--r--src/libstrongswan/processing/processor.h2
-rw-r--r--src/libstrongswan/processing/scheduler.c19
-rw-r--r--src/libstrongswan/processing/scheduler.h7
-rw-r--r--src/libstrongswan/processing/watcher.c113
-rw-r--r--src/libstrongswan/selectors/traffic_selector.c121
-rw-r--r--src/libstrongswan/selectors/traffic_selector.h19
-rw-r--r--src/libstrongswan/settings/settings_lexer.c190
-rw-r--r--src/libstrongswan/settings/settings_lexer.l5
-rw-r--r--src/libstrongswan/tests/Makefile.am4
-rw-r--r--src/libstrongswan/tests/Makefile.in81
-rw-r--r--src/libstrongswan/tests/suites/test_certnames.c398
-rw-r--r--src/libstrongswan/tests/suites/test_certpolicy.c637
-rw-r--r--src/libstrongswan/tests/suites/test_chunk.c13
-rw-r--r--src/libstrongswan/tests/suites/test_enum.c166
-rw-r--r--src/libstrongswan/tests/suites/test_hasher.c3
-rw-r--r--src/libstrongswan/tests/suites/test_host.c137
-rw-r--r--src/libstrongswan/tests/suites/test_identification.c114
-rw-r--r--src/libstrongswan/tests/suites/test_mgf1.c268
-rw-r--r--src/libstrongswan/tests/suites/test_ntru.c222
-rw-r--r--src/libstrongswan/tests/suites/test_settings.c4
-rw-r--r--src/libstrongswan/tests/suites/test_threading.c236
-rw-r--r--src/libstrongswan/tests/suites/test_traffic_selector.c284
-rw-r--r--src/libstrongswan/tests/suites/test_utils.c45
-rw-r--r--src/libstrongswan/tests/tests.h5
-rw-r--r--src/libstrongswan/threading/semaphore.h6
-rw-r--r--src/libstrongswan/threading/thread.h63
-rw-r--r--src/libstrongswan/threading/windows/rwlock.c2
-rw-r--r--src/libstrongswan/utils/chunk.c2
-rw-r--r--src/libstrongswan/utils/compat/apple.h119
-rw-r--r--src/libstrongswan/utils/compat/windows.c (renamed from src/libstrongswan/utils/windows.c)45
-rw-r--r--src/libstrongswan/utils/compat/windows.h (renamed from src/libstrongswan/utils/windows.h)45
-rw-r--r--src/libstrongswan/utils/enum.c93
-rw-r--r--src/libstrongswan/utils/enum.h35
-rw-r--r--src/libstrongswan/utils/identification.c87
-rw-r--r--src/libstrongswan/utils/identification.h9
-rw-r--r--src/libstrongswan/utils/utils.h6
-rw-r--r--src/libtls/Makefile.in5
-rw-r--r--src/libtls/tests/Makefile.in5
-rw-r--r--src/libtls/tls.c9
-rw-r--r--src/libtls/tls.h7
-rw-r--r--src/libtls/tls_eap.c7
-rw-r--r--src/libtls/tls_eap.h7
-rw-r--r--src/libtls/tls_fragmentation.c35
-rw-r--r--src/libtls/tls_fragmentation.h4
-rw-r--r--src/libtls/tls_handshake.h7
-rw-r--r--src/libtls/tls_peer.c40
-rw-r--r--src/libtls/tls_protection.c11
-rw-r--r--src/libtls/tls_server.c23
-rw-r--r--src/libtls/tls_socket.c15
-rw-r--r--src/libtnccs/Android.mk2
-rw-r--r--src/libtnccs/Makefile.in5
-rw-r--r--src/libtnccs/plugins/tnc_imc/Makefile.in5
-rw-r--r--src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c1
-rw-r--r--src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h2
-rw-r--r--src/libtnccs/plugins/tnc_imv/Makefile.in5
-rw-r--r--src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h2
-rw-r--r--src/libtnccs/plugins/tnc_tnccs/Makefile.in5
-rw-r--r--src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c48
-rw-r--r--src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h2
-rw-r--r--src/libtnccs/plugins/tnccs_11/Makefile.in5
-rw-r--r--src/libtnccs/plugins/tnccs_11/tnccs_11.c57
-rw-r--r--src/libtnccs/plugins/tnccs_11/tnccs_11.h15
-rw-r--r--src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h2
-rw-r--r--src/libtnccs/plugins/tnccs_20/Makefile.am4
-rw-r--r--src/libtnccs/plugins/tnccs_20/Makefile.in39
-rw-r--r--src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c85
-rw-r--r--src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h30
-rw-r--r--src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.c174
-rw-r--r--src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.h75
-rw-r--r--src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.c92
-rw-r--r--src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.h44
-rw-r--r--src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c22
-rw-r--r--src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h20
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20.c945
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20.h15
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20_client.c820
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20_client.h65
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h105
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h2
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20_server.c693
-rw-r--r--src/libtnccs/plugins/tnccs_20/tnccs_20_server.h71
-rw-r--r--src/libtnccs/plugins/tnccs_dynamic/Makefile.in5
-rw-r--r--src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c61
-rw-r--r--src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h15
-rw-r--r--src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h2
-rw-r--r--src/libtnccs/tnc/imc/imc.h2
-rw-r--r--src/libtnccs/tnc/imv/imv.h2
-rw-r--r--src/libtnccs/tnc/tnc.h7
-rw-r--r--src/libtnccs/tnc/tnccs/tnccs.h30
-rw-r--r--src/libtnccs/tnc/tnccs/tnccs_manager.h15
-rw-r--r--src/libtncif/Makefile.in5
-rw-r--r--src/libtncif/tncif_names.c14
-rw-r--r--src/libtncif/tncif_names.h4
-rw-r--r--src/manager/Makefile.in5
-rw-r--r--src/medsrv/Makefile.in5
-rw-r--r--src/pki/Makefile.am1
-rw-r--r--src/pki/Makefile.in11
-rw-r--r--src/pki/command.h2
-rw-r--r--src/pki/commands/acert.c11
-rw-r--r--src/pki/commands/gen.c14
-rw-r--r--src/pki/commands/issue.c12
-rw-r--r--src/pki/commands/keyid.c7
-rw-r--r--src/pki/commands/pkcs12.c247
-rw-r--r--src/pki/commands/print.c34
-rw-r--r--src/pki/commands/pub.c10
-rw-r--r--src/pki/commands/req.c17
-rw-r--r--src/pki/commands/self.c20
-rw-r--r--src/pki/commands/signcrl.c8
-rw-r--r--src/pki/man/Makefile.in21
-rw-r--r--src/pki/man/pki---acert.1.in4
-rw-r--r--src/pki/man/pki---issue.1.in20
-rw-r--r--src/pki/man/pki---pkcs12.1.in62
-rw-r--r--src/pki/man/pki---req.1.in4
-rw-r--r--src/pki/man/pki---self.1.in20
-rw-r--r--src/pki/man/pki---signcrl.1.in4
-rw-r--r--src/pki/pki.c46
-rw-r--r--src/pki/pki.h8
-rw-r--r--src/pool/Makefile.am4
-rw-r--r--src/pool/Makefile.in12
-rw-r--r--src/pt-tls-client/Makefile.in5
-rw-r--r--src/pt-tls-client/pt-tls-client.c43
-rw-r--r--src/scepclient/Makefile.in5
-rw-r--r--src/starter/Makefile.in5
-rw-r--r--src/starter/cmp.c2
-rw-r--r--src/starter/parser/lexer.c230
-rw-r--r--src/starter/parser/lexer.l5
-rw-r--r--src/starter/starterstroke.c14
-rw-r--r--src/starter/tests/Makefile.in5
-rw-r--r--src/stroke/Makefile.in5
-rw-r--r--src/stroke/stroke_msg.h2
-rw-r--r--src/swanctl/Makefile.am1
-rw-r--r--src/swanctl/Makefile.in6
-rw-r--r--src/swanctl/commands/list_conns.c5
-rw-r--r--src/swanctl/commands/list_sas.c6
-rw-r--r--src/swanctl/commands/load_conns.c47
-rw-r--r--src/swanctl/commands/load_creds.c290
-rw-r--r--src/swanctl/swanctl.conf14
-rw-r--r--src/swanctl/swanctl.conf.5.main80
-rw-r--r--src/swanctl/swanctl.h5
-rw-r--r--src/swanctl/swanctl.opt52
691 files changed, 33472 insertions, 6661 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 38363d4f7..9608a3a13 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -69,7 +69,7 @@ if USE_STROKE
endif
if USE_UPDOWN
- SUBDIRS += _updown _updown_espmark
+ SUBDIRS += _updown
endif
if USE_SCEPCLIENT
diff --git a/src/Makefile.in b/src/Makefile.in
index 2dd046042..7596e7e55 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -94,7 +94,7 @@ host_triplet = @host@
@USE_SYSTEMD_TRUE@am__append_15 = charon-systemd
@USE_NM_TRUE@am__append_16 = charon-nm
@USE_STROKE_TRUE@am__append_17 = stroke
-@USE_UPDOWN_TRUE@am__append_18 = _updown _updown_espmark
+@USE_UPDOWN_TRUE@am__append_18 = _updown
@USE_SCEPCLIENT_TRUE@am__append_19 = scepclient
@USE_PKI_TRUE@am__append_20 = pki
@USE_SWANCTL_TRUE@am__append_21 = swanctl
@@ -187,9 +187,9 @@ CTAGS = ctags
DIST_SUBDIRS = . include libstrongswan libhydra libipsec libsimaka \
libtls libradius libtncif libtnccs libpttls libimcv libcharon \
starter ipsec _copyright charon charon-systemd charon-nm \
- stroke _updown _updown_espmark scepclient pki swanctl conftest \
- dumm libfast manager medsrv pool charon-tkm charon-cmd \
- charon-svc pt-tls-client checksum aikgen
+ stroke _updown scepclient pki swanctl conftest dumm libfast \
+ manager medsrv pool charon-tkm charon-cmd charon-svc \
+ pt-tls-client checksum aikgen
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -241,6 +241,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@
@@ -301,10 +302,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@
@@ -378,6 +381,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/_copyright/Makefile.in b/src/_copyright/Makefile.in
index a17bbcc1a..2a4838c9a 100644
--- a/src/_copyright/Makefile.in
+++ b/src/_copyright/Makefile.in
@@ -195,6 +195,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@
@@ -255,10 +256,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@
@@ -332,6 +335,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/_updown/Makefile.am b/src/_updown/Makefile.am
index b6a81f547..32fa0423a 100644
--- a/src/_updown/Makefile.am
+++ b/src/_updown/Makefile.am
@@ -1,6 +1,5 @@
ipsec_SCRIPTS = _updown
CLEANFILES = _updown
-dist_man8_MANS = _updown.8
EXTRA_DIST = _updown.in
_updown : _updown.in
diff --git a/src/_updown/Makefile.in b/src/_updown/Makefile.in
index a215a2548..fe31dff64 100644
--- a/src/_updown/Makefile.in
+++ b/src/_updown/Makefile.in
@@ -79,8 +79,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/_updown
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(dist_man8_MANS)
+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 \
@@ -125,7 +124,7 @@ am__uninstall_files_from_dir = { \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
-am__installdirs = "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"
+am__installdirs = "$(DESTDIR)$(ipsecdir)"
SCRIPTS = $(ipsec_SCRIPTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -146,9 +145,6 @@ am__can_run_installinfo = \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
-man8dir = $(mandir)/man8
-NROFF = nroff
-MANS = $(dist_man8_MANS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
@@ -176,6 +172,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@
@@ -236,10 +233,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@
@@ -313,6 +312,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@
@@ -373,7 +374,6 @@ xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
ipsec_SCRIPTS = _updown
CLEANFILES = _updown
-dist_man8_MANS = _updown.8
EXTRA_DIST = _updown.in
all: all-am
@@ -449,47 +449,6 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
-install-man8: $(dist_man8_MANS)
- @$(NORMAL_INSTALL)
- @list1='$(dist_man8_MANS)'; \
- list2=''; \
- test -n "$(man8dir)" \
- && test -n "`echo $$list1$$list2`" \
- || exit 0; \
- echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
- { for i in $$list1; do echo "$$i"; done; \
- if test -n "$$list2"; then \
- for i in $$list2; do echo "$$i"; done \
- | sed -n '/\.8[a-z]*$$/p'; \
- fi; \
- } | while read p; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; echo "$$p"; \
- done | \
- sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
- sed 'N;N;s,\n, ,g' | { \
- list=; while read file base inst; do \
- if test "$$base" = "$$inst"; then list="$$list $$file"; else \
- echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
- $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
- fi; \
- done; \
- for i in $$list; do echo "$$i"; done | $(am__base_list) | \
- while read files; do \
- test -z "$$files" || { \
- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
- $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
- done; }
-
-uninstall-man8:
- @$(NORMAL_UNINSTALL)
- @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \
- files=`{ for i in $$list; do echo "$$i"; done; \
- } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
- dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
tags TAGS:
ctags CTAGS:
@@ -529,9 +488,9 @@ distdir: $(DISTFILES)
done
check-am: all-am
check: check-am
-all-am: Makefile $(SCRIPTS) $(MANS)
+all-am: Makefile $(SCRIPTS)
installdirs:
- for dir in "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"; do \
+ for dir in "$(DESTDIR)$(ipsecdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -585,7 +544,7 @@ info: info-am
info-am:
-install-data-am: install-ipsecSCRIPTS install-man
+install-data-am: install-ipsecSCRIPTS
install-dvi: install-dvi-am
@@ -601,7 +560,7 @@ install-info: install-info-am
install-info-am:
-install-man: install-man8
+install-man:
install-pdf: install-pdf-am
@@ -629,9 +588,7 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-ipsecSCRIPTS uninstall-man
-
-uninstall-man: uninstall-man8
+uninstall-am: uninstall-ipsecSCRIPTS
.MAKE: install-am install-strip
@@ -641,13 +598,12 @@ uninstall-man: uninstall-man8
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-ipsecSCRIPTS install-man install-man8 install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
+ install-ipsecSCRIPTS install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \
- uninstall-am uninstall-ipsecSCRIPTS uninstall-man \
- uninstall-man8
+ uninstall-am uninstall-ipsecSCRIPTS
_updown : _updown.in
diff --git a/src/_updown/_updown.8 b/src/_updown/_updown.8
deleted file mode 100644
index 8c88e5fb8..000000000
--- a/src/_updown/_updown.8
+++ /dev/null
@@ -1,16 +0,0 @@
-.TH _UPDOWN 8 "27 Apr 2006"
-.SH NAME
-ipsec _updown \- route and firewall manipulation script
-.SH SYNOPSIS
-.I _updown
-is invoked by pluto when it has brought up a new connection. This script
-is used to insert the appropriate routing entries for IPsec operation.
-It can also be used to insert and delete dynamic iptables firewall rules.
-The interface to the script is documented in the pluto man page.
-.SH "SEE ALSO"
-ipsec(8), ipsec_pluto(8).
-.SH HISTORY
-Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/>
-by Michael Richardson. Original program written by Henry Spencer. Extended
-for the Linux strongSwan project <http://www.strongswan.org/> by Andreas
-Steffen.
diff --git a/src/_updown/_updown.in b/src/_updown/_updown.in
index 532bd2437..4090fe074 100644
--- a/src/_updown/_updown.in
+++ b/src/_updown/_updown.in
@@ -1,5 +1,5 @@
-#! /bin/sh
-# iproute2 version, default updown script
+#!/bin/sh
+# default updown script
#
# Copyright (C) 2003-2004 Nigel Meteringham
# Copyright (C) 2003-2004 Tuomo Soini
@@ -22,8 +22,6 @@
# that, and use the (left/right)updown parameters in ipsec.conf to make
# strongSwan use yours instead of this default one.
-# things that this script gets (from ipsec_pluto(8) man page)
-#
# PLUTO_VERSION
# indicates what version of this interface is being
# used. This document describes version 1.1. This
@@ -128,7 +126,7 @@
PATH="/sbin:/bin:/usr/sbin:/usr/bin:@sbindir@"
export PATH
-# uncomment to log VPN connections
+# comment to disable logging VPN connections to syslog
VPN_LOGGING=1
#
# tag put in front of each log entry:
@@ -142,21 +140,11 @@ FAC_PRIO=local0.notice
#
# local0.notice -/var/log/vpn
-# in order to use source IP routing the Linux kernel options
-# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES
-# must be enabled
-#
-# special routing table for sourceip routes
-SOURCEIP_ROUTING_TABLE=@routing_table@
-#
-# priority of the sourceip routing table
-SOURCEIP_ROUTING_TABLE_PRIO=@routing_table_prio@
-
# check interface version
case "$PLUTO_VERSION" in
-1.[0|1]) # Older Pluto?!? Play it safe, script may be using new features.
+1.[0|1]) # Older release?!? Play it safe, script may be using new features.
echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
- echo "$0: called by obsolete Pluto?" >&2
+ echo "$0: called by obsolete release?" >&2
exit 2
;;
1.*) ;;
@@ -178,120 +166,9 @@ custom:*) # custom parameters (see above CAUTION comment)
;;
esac
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
- doroute add
- ip route flush cache
-}
-downroute() {
- doroute delete
- ip route flush cache
-}
-
-addsource() {
- st=0
- if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
- then
- it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
- oops="`eval $it 2>&1`"
- st=$?
- if test " $oops" = " " -a " $st" != " 0"
- then
- oops="silent error, exit status $st"
- fi
- if test " $oops" != " " -o " $st" != " 0"
- then
- echo "$0: addsource \`$it' failed ($oops)" >&2
- fi
- fi
- return $st
-}
-
-doroute() {
- st=0
-
- if [ -z "$PLUTO_MY_SOURCEIP" ]
- then
- for dir in /etc/sysconfig /etc/conf.d; do
- if [ -f "$dir/defaultsource" ]
- then
- . "$dir/defaultsource"
- fi
- done
-
- if [ -n "$DEFAULTSOURCE" ]
- then
- PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
- fi
- fi
-
- if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
- then
- # leave because no route entry is required
- return $st
- fi
-
- parms1="$PLUTO_PEER_CLIENT"
-
- if [ -n "$PLUTO_NEXT_HOP" ]
- then
- parms2="via $PLUTO_NEXT_HOP"
- else
- parms2="via $PLUTO_PEER"
- fi
- parms2="$parms2 dev $PLUTO_INTERFACE"
-
- parms3=
- if [ -n "$PLUTO_MY_SOURCEIP" ]
- then
- if test "$1" = "add"
- then
- addsource
- if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE"
- then
- ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE
- fi
- fi
- parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE"
- fi
-
- case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
- "0.0.0.0/0.0.0.0")
- # opportunistic encryption work around
- # need to provide route that eclipses default, without
- # replacing it.
- it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
- ip route $1 128.0.0.0/1 $parms2 $parms3"
- ;;
- *) it="ip route $1 $parms1 $parms2 $parms3"
- ;;
- esac
- oops="`eval $it 2>&1`"
- st=$?
- if test " $oops" = " " -a " $st" != " 0"
- then
- oops="silent error, exit status $st"
- fi
- if test " $oops" != " " -o " $st" != " 0"
- then
- echo "$0: doroute \`$it' failed ($oops)" >&2
- fi
- return $st
-}
-
-# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
- KLIPS=1
- IPSEC_POLICY_IN=""
- IPSEC_POLICY_OUT=""
-else
- KLIPS=
- IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
- IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
- IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
-fi
+IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID"
+IPSEC_POLICY_IN="$IPSEC_POLICY --dir in"
+IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out"
# use protocol specific options to set ports
case "$PLUTO_MY_PROTOCOL" in
@@ -334,59 +211,7 @@ fi
PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
-# the big choice
case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
- if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ]
- then
- # exit because no route will be added,
- # so that existing routes can stay
- exit 0
- fi
-
- # delete possibly-existing route (preliminary to adding a route)
- case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
- "0.0.0.0/0.0.0.0")
- # need to provide route that eclipses default, without
- # replacing it.
- parms1="0.0.0.0/1"
- parms2="128.0.0.0/1"
- it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
- oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
- ;;
- *)
- parms="$PLUTO_PEER_CLIENT"
- it="ip route delete $parms 2>&1"
- oops="`ip route delete $parms 2>&1`"
- ;;
- esac
- status="$?"
- if test " $oops" = " " -a " $status" != " 0"
- then
- oops="silent error, exit status $status"
- fi
- case "$oops" in
- *'RTNETLINK answers: No such process'*)
- # This is what route (currently -- not documented!) gives
- # for "could not find such a route".
- oops=
- status=0
- ;;
- esac
- if test " $oops" != " " -o " $status" != " 0"
- then
- echo "$0: \`$it' failed ($oops)" >&2
- fi
- exit $status
- ;;
-route-host:*|route-client:*)
- # connection to me or my client subnet being routed
- uproute
- ;;
-unroute-host:*|unroute-client:*)
- # connection to me or my client subnet being unrouted
- downroute
- ;;
up-host:)
# connection to me coming up
# If you are doing a custom version, firewall commands go here.
@@ -567,16 +392,6 @@ down-client:iptables)
#
# IPv6
#
-prepare-host-v6:*|prepare-client-v6:*)
- ;;
-route-host-v6:*|route-client-v6:*)
- # connection to me or my client subnet being routed
- #uproute_v6
- ;;
-unroute-host-v6:*|unroute-client-v6:*)
- # connection to me or my client subnet being unrouted
- #downroute_v6
- ;;
up-host-v6:)
# connection to me coming up
# If you are doing a custom version, firewall commands go here.
diff --git a/src/_updown_espmark/Makefile.am b/src/_updown_espmark/Makefile.am
deleted file mode 100644
index 456702690..000000000
--- a/src/_updown_espmark/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-dist_ipsec_SCRIPTS = _updown_espmark
-dist_man8_MANS = _updown_espmark.8
diff --git a/src/_updown_espmark/_updown_espmark b/src/_updown_espmark/_updown_espmark
deleted file mode 100644
index 864a91708..000000000
--- a/src/_updown_espmark/_updown_espmark
+++ /dev/null
@@ -1,438 +0,0 @@
-#! /bin/sh
-# iproute2 version, default updown script
-#
-# Copyright (C) 2003-2004 Nigel Meteringham
-# Copyright (C) 2003-2004 Tuomo Soini
-# Copyright (C) 2002-2004 Michael Richardson
-# Copyright (C) 2005 Andreas Steffen <andreas.steffen@strongsec.com>
-#
-# 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.
-
-
-
-# CAUTION: Installing a new version of strongSwan will install a new
-# copy of this script, wiping out any custom changes you make. If
-# you need changes, make a copy of this under another name, and customize
-# that, and use the (left/right)updown parameters in ipsec.conf to make
-# FreeS/WAN use yours instead of this default one.
-
-# things that this script gets (from ipsec_pluto(8) man page)
-#
-#
-# PLUTO_VERSION
-# indicates what version of this interface is being
-# used. This document describes version 1.1. This
-# is upwardly compatible with version 1.0.
-#
-# PLUTO_VERB
-# specifies the name of the operation to be performed
-# (prepare-host, prepare-client, up-host, up-client,
-# down-host, or down-client). If the address family
-# for security gateway to security gateway communica-
-# tions is IPv6, then a suffix of -v6 is added to the
-# verb.
-#
-# PLUTO_CONNECTION
-# is the name of the connection for which we are
-# routing.
-#
-# PLUTO_INTERFACE
-# is the name of the ipsec interface to be used.
-#
-# PLUTO_ME
-# is the IP address of our host.
-#
-# PLUTO_MY_ID
-# is the ID of our host.
-#
-# PLUTO_MY_CLIENT
-# is the IP address / count of our client subnet. If
-# the client is just the host, this will be the
-# host's own IP address / max (where max is 32 for
-# IPv4 and 128 for IPv6).
-#
-# PLUTO_MY_SOURCEIP
-# if non-empty, then the source address for the route will be
-# set to this IP address.
-#
-# PLUTO_MY_PROTOCOL
-# is the IP protocol that will be transported.
-#
-# PLUTO_MY_PORT
-# is the UDP/TCP port to which the IPsec SA is
-# restricted on our side.
-#
-# PLUTO_PEER
-# is the IP address of our peer.
-#
-# PLUTO_PEER_ID
-# is the ID of our peer.
-#
-# PLUTO_PEER_CLIENT
-# is the IP address / count of the peer's client sub-
-# net. If the client is just the peer, this will be
-# the peer's own IP address / max (where max is 32
-# for IPv4 and 128 for IPv6).
-#
-# PLUTO_PEER_PROTOCOL
-# is the IP protocol that will be transported.
-#
-# PLUTO_PEER_PORT
-# is the UDP/TCP port to which the IPsec SA is
-# restricted on the peer side.
-#
-# PLUTO_XAUTH_ID
-# is an optional user ID employed by the XAUTH protocol
-#
-# PLUTO_MARK_IN
-# is an optional XFRM mark set on the inbound IPsec SA
-#
-# PLUTO_MARK_OUT
-# is an optional XFRM mark set on the outbound IPsec SA
-#
-# PLUTO_UDP_ENC
-# contains the remote UDP port in the case of ESP_IN_UDP
-# encapsulation
-#
-
-# logging of VPN connections
-#
-# tag put in front of each log entry:
-TAG=vpn
-#
-# syslog facility and priority used:
-FAC_PRIO=local0.notice
-#
-# to create a special vpn logging file, put the following line into
-# the syslog configuration file /etc/syslog.conf:
-#
-# local0.notice -/var/log/vpn
-#
-
-# check interface version
-case "$PLUTO_VERSION" in
-1.[0]) # Older Pluto?!? Play it safe, script may be using new features.
- echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2
- echo "$0: called by obsolete Pluto?" >&2
- exit 2
- ;;
-1.*) ;;
-*) echo "$0: unknown interface version \`$PLUTO_VERSION'" >&2
- exit 2
- ;;
-esac
-
-# check parameter(s)
-case "$1:$*" in
-':') # no parameters
- ;;
-ipfwadm:ipfwadm) # due to (left/right)firewall; for default script only
- ;;
-custom:*) # custom parameters (see above CAUTION comment)
- ;;
-*) echo "$0: unknown parameters \`$*'" >&2
- exit 2
- ;;
-esac
-
-# utility functions for route manipulation
-# Meddling with this stuff should not be necessary and requires great care.
-uproute() {
- doroute add
- ip route flush cache
-}
-downroute() {
- doroute delete
- ip route flush cache
-}
-
-addsource() {
- st=0
- if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local
- then
- it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE"
- oops="`eval $it 2>&1`"
- st=$?
- if test " $oops" = " " -a " $st" != " 0"
- then
- oops="silent error, exit status $st"
- fi
- if test " $oops" != " " -o " $st" != " 0"
- then
- echo "$0: addsource \`$it' failed ($oops)" >&2
- fi
- fi
- return $st
-}
-
-doroute() {
- st=0
- parms="$PLUTO_PEER_CLIENT"
-
- parms2=
- if [ -n "$PLUTO_NEXT_HOP" ]
- then
- parms2="via $PLUTO_NEXT_HOP"
- fi
- parms2="$parms2 dev $PLUTO_INTERFACE"
-
- if [ -z "$PLUTO_MY_SOURCEIP" ]
- then
- for dir in /etc/sysconfig /etc/conf.d; do
- if [ -f "$dir/defaultsource" ]
- then
- . "$dir/defaultsource"
- fi
- done
-
- if [ -n "$DEFAULTSOURCE" ]
- then
- PLUTO_MY_SOURCEIP=$DEFAULTSOURCE
- fi
- fi
-
- parms3=
- if test "$1" = "add" -a -n "$PLUTO_MY_SOURCEIP"
- then
- addsource
- parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*}"
- fi
-
- case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
- "0.0.0.0/0.0.0.0")
- # opportunistic encryption work around
- # need to provide route that eclipses default, without
- # replacing it.
- it="ip route $1 0.0.0.0/1 $parms2 $parms3 &&
- ip route $1 128.0.0.0/1 $parms2 $parms3"
- ;;
- *) it="ip route $1 $parms $parms2 $parms3"
- ;;
- esac
- oops="`eval $it 2>&1`"
- st=$?
- if test " $oops" = " " -a " $st" != " 0"
- then
- oops="silent error, exit status $st"
- fi
- if test " $oops" != " " -o " $st" != " 0"
- then
- echo "$0: doroute \`$it' failed ($oops)" >&2
- fi
- return $st
-}
-
-# define ESP mark
-ESP_MARK=50
-
-# add the following static rule to the INPUT chain in the mangle table
-# iptables -t mangle -A INPUT -p 50 -j MARK --set-mark 50
-
-# NAT traversal via UDP encapsulation is supported with the rule
-# iptables -t mangle -A INPUT -p udp --dport 4500 -j MARK --set-mark 50
-
-# in the presence of KLIPS and ipsecN interfaces do not use ESP mark rules
-if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ]
-then
- CHECK_MARK=""
-else
- CHECK_MARK="-m mark --mark $ESP_MARK"
-fi
-
-# are there port numbers?
-if [ "$PLUTO_MY_PORT" != 0 ]
-then
- S_MY_PORT="--sport $PLUTO_MY_PORT"
- D_MY_PORT="--dport $PLUTO_MY_PORT"
-fi
-if [ "$PLUTO_PEER_PORT" != 0 ]
-then
- S_PEER_PORT="--sport $PLUTO_PEER_PORT"
- D_PEER_PORT="--dport $PLUTO_PEER_PORT"
-fi
-
-# resolve octal escape sequences
-PLUTO_MY_ID=`printf "$PLUTO_MY_ID"`
-PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"`
-
-# the big choice
-case "$PLUTO_VERB:$1" in
-prepare-host:*|prepare-client:*)
- # delete possibly-existing route (preliminary to adding a route)
- case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in
- "0.0.0.0/0.0.0.0")
- # need to provide route that eclipses default, without
- # replacing it.
- parms1="0.0.0.0/1"
- parms2="128.0.0.0/1"
- it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1"
- oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`"
- ;;
- *)
- parms="$PLUTO_PEER_CLIENT"
- it="ip route delete $parms 2>&1"
- oops="`ip route delete $parms 2>&1`"
- ;;
- esac
- status="$?"
- if test " $oops" = " " -a " $status" != " 0"
- then
- oops="silent error, exit status $status"
- fi
- case "$oops" in
- *'RTNETLINK answers: No such process'*)
- # This is what route (currently -- not documented!) gives
- # for "could not find such a route".
- oops=
- status=0
- ;;
- esac
- if test " $oops" != " " -o " $status" != " 0"
- then
- echo "$0: \`$it' failed ($oops)" >&2
- fi
- exit $status
- ;;
-route-host:*|route-client:*)
- # connection to me or my client subnet being routed
- uproute
- ;;
-unroute-host:*|unroute-client:*)
- # connection to me or my client subnet being unrouted
- downroute
- ;;
-up-host:*)
- # connection to me coming up
- # If you are doing a custom version, firewall commands go here.
- iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
- iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_ME $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
- #
- if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO \
- "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
- else
- logger -t $TAG -p $FAC_PRIO \
- "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
- fi
- ;;
-down-host:*)
- # connection to me going down
- # If you are doing a custom version, firewall commands go here.
- # connection to me going down
- # If you are doing a custom version, firewall commands go here.
- iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT
- iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_ME $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
- #
- if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO -- \
- "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
- else
- logger -t $TAG -p $FAC_PRIO -- \
- "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
- fi
- ;;
-up-client:)
- # connection to my client subnet coming up
- # If you are doing a custom version, firewall commands go here.
- iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
- iptables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
- $CHECK_MARK -j ACCEPT
- #
- if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO \
- "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- else
- logger -t $TAG -p $FAC_PRIO \
- "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- fi
- ;;
-down-client:)
- # connection to my client subnet going down
- # If you are doing a custom version, firewall commands go here.
- iptables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
- -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
- iptables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
- -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
- $CHECK_MARK -j ACCEPT
- #
- if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
- then
- logger -t $TAG -p $FAC_PRIO -- \
- "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- else
- logger -t $TAG -p $FAC_PRIO -- \
- "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
- fi
- ;;
-up-client:ipfwadm)
- # connection to client subnet, with (left/right)firewall=yes, coming up
- # This is used only by the default updown script, not by your custom
- # ones, so do not mess with it; see CAUTION comment up at top.
- ipfwadm -F -i accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
- -D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
- ;;
-down-client:ipfwadm)
- # connection to client subnet, with (left/right)firewall=yes, going down
- # This is used only by the default updown script, not by your custom
- # ones, so do not mess with it; see CAUTION comment up at top.
- ipfwadm -F -d accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \
- -D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK
- ;;
-#
-# IPv6
-#
-prepare-host-v6:*|prepare-client-v6:*)
- ;;
-route-host-v6:*|route-client-v6:*)
- # connection to me or my client subnet being routed
- #uproute_v6
- ;;
-unroute-host-v6:*|unroute-client-v6:*)
- # connection to me or my client subnet being unrouted
- #downroute_v6
- ;;
-up-host-v6:*)
- # connection to me coming up
- # If you are doing a custom version, firewall commands go here.
- ;;
-down-host-v6:*)
- # connection to me going down
- # If you are doing a custom version, firewall commands go here.
- ;;
-up-client-v6:)
- # connection to my client subnet coming up
- # If you are doing a custom version, firewall commands go here.
- ;;
-down-client-v6:)
- # connection to my client subnet going down
- # If you are doing a custom version, firewall commands go here.
- ;;
-*) echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
- exit 1
- ;;
-esac
diff --git a/src/_updown_espmark/_updown_espmark.8 b/src/_updown_espmark/_updown_espmark.8
deleted file mode 100644
index 34383cb8e..000000000
--- a/src/_updown_espmark/_updown_espmark.8
+++ /dev/null
@@ -1,15 +0,0 @@
-.TH _UPDOWN_ESPMARK 8 "7 Apr 2005"
-.SH NAME
-ipsec _updown_espmark \- manages routes and firewall rules
-.SH SYNOPSIS
-.I _updown_espmark
-is invoked by pluto when it has brought up a new connection. This script
-is used to insert the appropriate routing and iptables firewall entries for
-IPsec operation. The incoming ESP traffic must be marked by a static rule
-in the mangle table. The default value for the mark is 50.
-The interface to the script is documented in the pluto man page.
-.SH "SEE ALSO"
-ipsec(8), ipsec_pluto(8).
-.SH HISTORY
-Man page written for the Linux strongSwan project <http://www.strongswan.org/>
-by Andreas Steffen. Original program written by Henry Spencer.
diff --git a/src/aikgen/Makefile.in b/src/aikgen/Makefile.in
index 2bd5be64b..33ed13397 100644
--- a/src/aikgen/Makefile.in
+++ b/src/aikgen/Makefile.in
@@ -198,6 +198,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@
@@ -258,10 +259,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@
@@ -335,6 +338,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/charon-cmd/Makefile.in b/src/charon-cmd/Makefile.in
index 9f67eec1f..64dea34c7 100644
--- a/src/charon-cmd/Makefile.in
+++ b/src/charon-cmd/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/charon-nm/Makefile.in b/src/charon-nm/Makefile.in
index 69cbfe07e..82f6fbcb2 100644
--- a/src/charon-nm/Makefile.in
+++ b/src/charon-nm/Makefile.in
@@ -203,6 +203,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@
@@ -263,10 +264,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@
@@ -340,6 +343,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/charon-nm/nm/nm_backend.c b/src/charon-nm/nm/nm_backend.c
index 613c2f6b5..601daca0a 100644
--- a/src/charon-nm/nm/nm_backend.c
+++ b/src/charon-nm/nm/nm_backend.c
@@ -18,7 +18,6 @@
#include "nm_creds.h"
#include "nm_handler.h"
-#include <hydra.h>
#include <daemon.h>
#include <processing/jobs/callback_job.h>
@@ -97,7 +96,8 @@ static void nm_backend_deinit()
g_object_unref(this->plugin);
}
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
- hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler);
+ charon->attributes->remove_handler(charon->attributes,
+ &this->handler->handler);
this->creds->destroy(this->creds);
this->handler->destroy(this->handler);
free(this);
@@ -130,7 +130,7 @@ static bool nm_backend_init()
this->plugin = nm_strongswan_plugin_new(this->creds, this->handler);
nm_backend = this;
- hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
+ charon->attributes->add_handler(charon->attributes, &this->handler->handler);
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
if (!this->plugin)
{
diff --git a/src/charon-nm/nm/nm_handler.c b/src/charon-nm/nm/nm_handler.c
index 28aa04b31..bdc0667cf 100644
--- a/src/charon-nm/nm/nm_handler.c
+++ b/src/charon-nm/nm/nm_handler.c
@@ -41,7 +41,7 @@ struct private_nm_handler_t {
};
METHOD(attribute_handler_t, handle, bool,
- private_nm_handler_t *this, identification_t *server,
+ private_nm_handler_t *this, ike_sa_t *ike_sa,
configuration_attribute_type_t type, chunk_t data)
{
linked_list_t *list;
@@ -92,7 +92,7 @@ static bool enumerate_dns(enumerator_t *this,
}
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
- private_nm_handler_t *this, identification_t *server, linked_list_t *vips)
+ private_nm_handler_t *this, ike_sa_t *ike_sa, linked_list_t *vips)
{
if (vips->get_count(vips))
{
@@ -185,4 +185,3 @@ nm_handler_t *nm_handler_create()
return &this->public;
}
-
diff --git a/src/charon-svc/Makefile.in b/src/charon-svc/Makefile.in
index 3783ac9f0..1c0a4058d 100644
--- a/src/charon-svc/Makefile.in
+++ b/src/charon-svc/Makefile.in
@@ -197,6 +197,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@
@@ -257,10 +258,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@
@@ -334,6 +337,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/charon-systemd/Makefile.in b/src/charon-systemd/Makefile.in
index 790c8ef8f..d6e1c471c 100644
--- a/src/charon-systemd/Makefile.in
+++ b/src/charon-systemd/Makefile.in
@@ -200,6 +200,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@
@@ -260,10 +261,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@
@@ -337,6 +340,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/charon-systemd/charon-systemd.c b/src/charon-systemd/charon-systemd.c
index 4a2136fc9..e391a5397 100644
--- a/src/charon-systemd/charon-systemd.c
+++ b/src/charon-systemd/charon-systemd.c
@@ -40,6 +40,17 @@
#include <threading/rwlock.h>
/**
+ * Default user and group
+ */
+#ifndef IPSEC_USER
+#define IPSEC_USER NULL
+#endif
+
+#ifndef IPSEC_GROUP
+#define IPSEC_GROUP NULL
+#endif
+
+/**
* hook in library for debugging messages
*/
extern void (*dbg) (debug_t group, level_t level, char *fmt, ...);
@@ -268,18 +279,20 @@ static int run()
*/
static bool lookup_uid_gid()
{
-#ifdef IPSEC_USER
- if (!lib->caps->resolve_uid(lib->caps, IPSEC_USER))
+ char *name;
+
+ name = lib->settings->get_str(lib->settings, "%s.user", IPSEC_USER,
+ lib->ns);
+ if (name && !lib->caps->resolve_uid(lib->caps, name))
{
return FALSE;
}
-#endif /* IPSEC_USER */
-#ifdef IPSEC_GROUP
- if (!lib->caps->resolve_gid(lib->caps, IPSEC_GROUP))
+ name = lib->settings->get_str(lib->settings, "%s.group", IPSEC_GROUP,
+ lib->ns);
+ if (name && !lib->caps->resolve_gid(lib->caps, name))
{
return FALSE;
}
-#endif /* IPSEC_GROUP */
return TRUE;
}
@@ -365,7 +378,8 @@ int main(int argc, char *argv[])
lib->plugins->add_static_features(lib->plugins, lib->ns, features,
countof(features), TRUE, journal_reload, &journal);
- if (!charon->initialize(charon, PLUGINS))
+ if (!charon->initialize(charon,
+ lib->settings->get_str(lib->settings, "%s.load", PLUGINS, lib->ns)))
{
sd_notifyf(0, "STATUS=charon initialization failed");
return SS_RC_INITIALIZATION_FAILED;
diff --git a/src/charon-tkm/Makefile.in b/src/charon-tkm/Makefile.in
index fe6606bc5..bff198ab8 100644
--- a/src/charon-tkm/Makefile.in
+++ b/src/charon-tkm/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@
diff --git a/src/charon-tkm/src/charon-tkm.c b/src/charon-tkm/src/charon-tkm.c
index a6770fc50..7c60f0ca8 100644
--- a/src/charon-tkm/src/charon-tkm.c
+++ b/src/charon-tkm/src/charon-tkm.c
@@ -276,6 +276,10 @@ int main(int argc, char *argv[])
goto deinit;
}
+ /* the authorize hook currently does not support RFC 7427 signature auth */
+ lib->settings->set_bool(lib->settings, "%s.signature_authentication", FALSE,
+ dmn_name);
+
/* make sure we log to the DAEMON facility by default */
lib->settings->set_int(lib->settings, "%s.syslog.daemon.default",
lib->settings->get_int(lib->settings, "%s.syslog.daemon.default", 1,
diff --git a/src/charon-tkm/src/ees/ees_callbacks.c b/src/charon-tkm/src/ees/ees_callbacks.c
index 2d9653837..74c0d3618 100644
--- a/src/charon-tkm/src/ees/ees_callbacks.c
+++ b/src/charon-tkm/src/ees/ees_callbacks.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
* Copyright (C) 2012 Adrian-Ken Rueegsegger
* Hochschule fuer Technik Rapperswil
*
@@ -19,11 +19,12 @@
#include <tkm/constants.h>
#include <tkm/types.h>
+#include "tkm.h"
#include "ees_callbacks.h"
void charon_esa_acquire(result_type *res, const sp_id_type sp_id)
{
- DBG1(DBG_KNL, "ees: acquire received for reqid {%d}", sp_id);
+ DBG1(DBG_KNL, "ees: acquire received for reqid %u", sp_id);
hydra->kernel_interface->acquire(hydra->kernel_interface, sp_id, NULL,
NULL);
*res = TKM_OK;
@@ -33,8 +34,19 @@ void charon_esa_expire(result_type *res, const sp_id_type sp_id,
const esp_spi_type spi_rem, const protocol_type protocol,
const expiry_flag_type hard)
{
- DBG1(DBG_KNL, "ees: expire received for reqid {%d}", sp_id);
- hydra->kernel_interface->expire(hydra->kernel_interface, sp_id, protocol,
- spi_rem, hard != 0);
+ host_t *dst;
+
+ dst = tkm->sad->get_dst_host(tkm->sad, sp_id, spi_rem, protocol);
*res = TKM_OK;
+ if (dst == NULL)
+ {
+ DBG3(DBG_KNL, "ees: destination host not found for reqid %u, spi %x, "
+ "proto %u", sp_id, ntohl(spi_rem), protocol);
+ return;
+ }
+
+ DBG1(DBG_KNL, "ees: expire received for reqid %u, spi %x, dst %H", sp_id,
+ ntohl(spi_rem), dst);
+ hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+ spi_rem, dst, hard != 0);
}
diff --git a/src/charon-tkm/src/tkm/tkm.c b/src/charon-tkm/src/tkm/tkm.c
index 61eb6056c..333b699a0 100644
--- a/src/charon-tkm/src/tkm/tkm.c
+++ b/src/charon-tkm/src/tkm/tkm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
* Copyright (C) 2012 Adrian-Ken Rueegsegger
* Hochschule fuer Technik Rapperswil
*
@@ -95,6 +95,7 @@ bool tkm_init()
.public = {
.idmgr = tkm_id_manager_create(limits),
.chunk_map = tkm_chunk_map_create(),
+ .sad = tkm_kernel_sad_create(),
},
);
tkm = &this->public;
@@ -114,6 +115,7 @@ void tkm_deinit()
private_tkm_t *this = (private_tkm_t*)tkm;
this->public.idmgr->destroy(this->public.idmgr);
this->public.chunk_map->destroy(this->public.chunk_map);
+ this->public.sad->destroy(this->public.sad);
ees_server_finalize();
diff --git a/src/charon-tkm/src/tkm/tkm.h b/src/charon-tkm/src/tkm/tkm.h
index fb5acd117..4aed08602 100644
--- a/src/charon-tkm/src/tkm/tkm.h
+++ b/src/charon-tkm/src/tkm/tkm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
* Copyright (C) 2012 Adrian-Ken Rueegsegger
* Hochschule fuer Technik Rapperswil
*
@@ -72,6 +72,7 @@
#include "tkm_id_manager.h"
#include "tkm_chunk_map.h"
+#include "tkm_kernel_sad.h"
typedef struct tkm_t tkm_t;
@@ -90,6 +91,11 @@ struct tkm_t {
*/
tkm_chunk_map_t *chunk_map;
+ /**
+ * CHILD/ESP SA database.
+ */
+ tkm_kernel_sad_t *sad;
+
};
/**
diff --git a/src/charon-tkm/src/tkm/tkm_diffie_hellman.c b/src/charon-tkm/src/tkm/tkm_diffie_hellman.c
index 67db5e6d8..c4953b6aa 100644
--- a/src/charon-tkm/src/tkm/tkm_diffie_hellman.c
+++ b/src/charon-tkm/src/tkm/tkm_diffie_hellman.c
@@ -41,7 +41,7 @@ struct private_tkm_diffie_hellman_t {
/**
* Diffie Hellman group number.
*/
- u_int16_t group;
+ diffie_hellman_group_t group;
/**
* Diffie Hellman public value.
@@ -55,30 +55,29 @@ struct private_tkm_diffie_hellman_t {
};
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
private_tkm_diffie_hellman_t *this, chunk_t *value)
{
sequence_to_chunk(this->pubvalue.data, this->pubvalue.size, value);
+ return TRUE;
}
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
private_tkm_diffie_hellman_t *this, chunk_t *secret)
{
*secret = chunk_empty;
- return SUCCESS;
+ return TRUE;
}
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_tkm_diffie_hellman_t *this, chunk_t value)
{
- // TODO: unvoid this function
-
dh_pubvalue_type othervalue;
othervalue.size = value.len;
memcpy(&othervalue.data, value.ptr, value.len);
- ike_dh_generate_key(this->context_id, othervalue);
+ return ike_dh_generate_key(this->context_id, othervalue) == TKM_OK;
}
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
diff --git a/src/charon-tkm/src/tkm/tkm_id_manager.c b/src/charon-tkm/src/tkm/tkm_id_manager.c
index 0fadf1acf..e6d571b83 100644
--- a/src/charon-tkm/src/tkm/tkm_id_manager.c
+++ b/src/charon-tkm/src/tkm/tkm_id_manager.c
@@ -24,7 +24,7 @@
ENUM_BEGIN(tkm_context_kind_names, TKM_CTX_NONCE, TKM_CTX_ESA,
"NONCE_CONTEXT",
"DH_CONTEXT",
- "CC_CONTEXT"
+ "CC_CONTEXT",
"ISA_CONTEXT",
"AE_CONTEXT",
"ESA_CONTEXT");
diff --git a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
index dbeea93f2..734b1ec55 100644
--- a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
+++ b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
* Copyright (C) 2012 Adrian-Ken Rueegsegger
* Hochschule fuer Technik Rapperswil
*
@@ -26,7 +26,6 @@
#include "tkm_utils.h"
#include "tkm_types.h"
#include "tkm_keymat.h"
-#include "tkm_kernel_sad.h"
#include "tkm_kernel_ipsec.h"
/** From linux/in.h */
@@ -51,16 +50,11 @@ struct private_tkm_kernel_ipsec_t {
*/
rng_t *rng;
- /**
- * CHILD/ESP SA database.
- */
- tkm_kernel_sad_t *sad;
-
};
METHOD(kernel_ipsec_t, get_spi, status_t,
private_tkm_kernel_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)
{
bool result;
@@ -74,7 +68,6 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
}
}
- DBG1(DBG_KNL, "getting SPI for reqid {%u}", reqid);
result = this->rng->get_bytes(this->rng, sizeof(u_int32_t),
(u_int8_t *)spi);
return result ? SUCCESS : FAILED;
@@ -82,7 +75,7 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
METHOD(kernel_ipsec_t, get_cpi, status_t,
private_tkm_kernel_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
+ u_int16_t *cpi)
{
return NOT_SUPPORTED;
}
@@ -93,11 +86,10 @@ 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)
{
esa_info_t esa;
- bool initiator;
esp_spi_type spi_loc, spi_rem;
host_t *local, *peer;
chunk_t *nonce_loc, *nonce_rem;
@@ -120,9 +112,6 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
return SUCCESS;
}
- /* Initiator if encr_r is passed as enc_key to the inbound add_sa call */
- /* TODO: does the new _initiator parameter have the same meaning? */
- initiator = esa.is_encr_r && inbound;
if (initiator)
{
spi_loc = spi;
@@ -143,7 +132,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
}
esa_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_ESA);
- if (!this->sad->insert(this->sad, esa_id, peer, local, spi_loc, protocol))
+ if (!tkm->sad->insert(tkm->sad, reqid, esa_id, local, peer, spi_rem,
+ protocol))
{
DBG1(DBG_KNL, "unable to add entry (%llu) to SAD", esa_id);
goto sad_failure;
@@ -207,7 +197,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
return SUCCESS;
failure:
- this->sad->remove(this->sad, esa_id);
+ tkm->sad->remove(tkm->sad, esa_id);
sad_failure:
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_ESA, esa_id);
chunk_free(&esa.nonce_i);
@@ -229,7 +219,7 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
{
esa_id_type esa_id;
- esa_id = this->sad->get_esa_id(this->sad, src, dst, spi, protocol);
+ esa_id = tkm->sad->get_esa_id(tkm->sad, src, dst, spi, protocol);
if (esa_id)
{
DBG1(DBG_KNL, "deleting child SA (esa: %llu, spi: %x)", esa_id,
@@ -239,7 +229,7 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
DBG1(DBG_KNL, "child SA (%llu) deletion failed", esa_id);
return FAILED;
}
- this->sad->remove(this->sad, esa_id);
+ tkm->sad->remove(tkm->sad, esa_id);
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_ESA, esa_id);
}
return SUCCESS;
@@ -350,7 +340,6 @@ METHOD(kernel_ipsec_t, destroy, void,
private_tkm_kernel_ipsec_t *this)
{
DESTROY_IF(this->rng);
- DESTROY_IF(this->sad);
free(this);
}
@@ -380,15 +369,7 @@ tkm_kernel_ipsec_t *tkm_kernel_ipsec_create()
.destroy = _destroy,
},
},
- .sad = tkm_kernel_sad_create(),
);
- if (!this->sad)
- {
- DBG1(DBG_KNL, "unable to create SAD");
- destroy(this);
- return NULL;
- }
-
return &this->public;
}
diff --git a/src/charon-tkm/src/tkm/tkm_kernel_sad.c b/src/charon-tkm/src/tkm/tkm_kernel_sad.c
index 360a47bdc..3394b58af 100644
--- a/src/charon-tkm/src/tkm/tkm_kernel_sad.c
+++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
* Copyright (C) 2012 Adrian-Ken Rueegsegger
* Hochschule fuer Technik Rapperswil
*
@@ -57,6 +57,11 @@ struct sad_entry_t {
esa_id_type esa_id;
/**
+ * Reqid.
+ */
+ u_int32_t reqid;
+
+ /**
* Source address of CHILD SA.
*/
host_t *src;
@@ -109,6 +114,19 @@ static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src,
}
/**
+ * Find a list entry with given reqid, spi and proto values.
+ */
+static bool sad_entry_match_dst(sad_entry_t * const entry,
+ const u_int32_t * const reqid,
+ const u_int32_t * const spi,
+ const u_int8_t * const proto)
+{
+ return entry->reqid == *reqid &&
+ entry->spi == *spi &&
+ entry->proto == *proto;
+}
+
+/**
* Compare two SAD entries for equality.
*/
static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right)
@@ -119,6 +137,7 @@ static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right)
return FALSE;
}
return left->esa_id == right->esa_id &&
+ left->reqid == right->reqid &&
left->src->ip_equals(left->src, right->src) &&
left->dst->ip_equals(left->dst, right->dst) &&
left->spi == right->spi && left->proto == right->proto;
@@ -126,14 +145,15 @@ static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right)
METHOD(tkm_kernel_sad_t, insert, bool,
private_tkm_kernel_sad_t * const this, const esa_id_type esa_id,
- const host_t * const src, const host_t * const dst, const u_int32_t spi,
- const u_int8_t proto)
+ const u_int32_t reqid, const host_t * const src, const host_t * const dst,
+ const u_int32_t spi, const u_int8_t proto)
{
status_t result;
sad_entry_t *new_entry;
INIT(new_entry,
.esa_id = esa_id,
+ .reqid = reqid,
.src = (host_t *)src,
.dst = (host_t *)dst,
.spi = spi,
@@ -146,8 +166,9 @@ METHOD(tkm_kernel_sad_t, insert, bool,
new_entry);
if (result == NOT_FOUND)
{
- DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, src: %H, dst: %H, "
- "spi: %x, proto: %u)", esa_id, src, dst, ntohl(spi), proto);
+ DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, reqid: %u, src: %H, "
+ "dst: %H, spi: %x, proto: %u)", esa_id, reqid, src, dst,
+ ntohl(spi), proto);
new_entry->src = src->clone((host_t *)src);
new_entry->dst = dst->clone((host_t *)dst);
this->data->insert_last(this->data, new_entry);
@@ -176,18 +197,44 @@ METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type,
if (res == SUCCESS && entry)
{
id = entry->esa_id;
- DBG3(DBG_KNL, "getting ESA id of SAD entry (esa: %llu, src: %H, "
- "dst: %H, spi: %x, proto: %u)", id, src, dst, ntohl(spi),
- proto);
+ DBG3(DBG_KNL, "returning ESA id %llu of SAD entry (src: %H, dst: %H, "
+ "spi: %x, proto: %u)", id, src, dst, ntohl(spi), proto);
}
else
{
- DBG3(DBG_KNL, "no SAD entry found");
+ DBG3(DBG_KNL, "no SAD entry found for src %H, dst %H, spi %x, proto %u",
+ src, dst, ntohl(spi), proto);
}
this->mutex->unlock(this->mutex);
return id;
}
+METHOD(tkm_kernel_sad_t, get_dst_host, host_t *,
+ private_tkm_kernel_sad_t * const this, const u_int32_t reqid,
+ const u_int32_t spi, const u_int8_t proto)
+{
+ host_t *dst = NULL;
+ sad_entry_t *entry = NULL;
+
+ this->mutex->lock(this->mutex);
+ const status_t res = this->data->find_first(this->data,
+ (linked_list_match_t)sad_entry_match_dst,
+ (void**)&entry, &reqid, &spi, &proto);
+ if (res == SUCCESS && entry)
+ {
+ dst = entry->dst;
+ DBG3(DBG_KNL, "returning destination host %H of SAD entry (reqid: %u,"
+ " spi: %x, proto: %u)", dst, reqid, ntohl(spi), proto);
+ }
+ else
+ {
+ DBG3(DBG_KNL, "no SAD entry found for reqid %u, spi %x, proto: %u",
+ reqid, ntohl(spi), proto);
+ }
+ this->mutex->unlock(this->mutex);
+ return dst;
+}
+
METHOD(tkm_kernel_sad_t, _remove, bool,
private_tkm_kernel_sad_t * const this, const esa_id_type esa_id)
{
@@ -242,6 +289,7 @@ tkm_kernel_sad_t *tkm_kernel_sad_create()
.public = {
.insert = _insert,
.get_esa_id = _get_esa_id,
+ .get_dst_host = _get_dst_host,
.remove = __remove,
.destroy = _destroy,
},
diff --git a/src/charon-tkm/src/tkm/tkm_kernel_sad.h b/src/charon-tkm/src/tkm/tkm_kernel_sad.h
index 0194cd3bc..38b19dd01 100644
--- a/src/charon-tkm/src/tkm/tkm_kernel_sad.h
+++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
* Copyright (C) 2012 Adrian-Ken Rueegsegger
* Hochschule fuer Technik Rapperswil
*
@@ -37,6 +37,7 @@ struct tkm_kernel_sad_t {
* Insert new SAD entry with specified parameters.
*
* @param esa_id ESP SA context identifier
+ * @param reqid reqid of the SA
* @param src source address of CHILD SA
* @param dst destination address of CHILD SA
* @param spi SPI of CHILD SA
@@ -44,8 +45,9 @@ struct tkm_kernel_sad_t {
* @return TRUE if entry was inserted, FALSE otherwise
*/
bool (*insert)(tkm_kernel_sad_t * const this, const esa_id_type esa_id,
- const host_t * const src, const host_t * const dst,
- const u_int32_t spi, const u_int8_t proto);
+ const u_int32_t reqid, const host_t * const src,
+ const host_t * const dst, const u_int32_t spi,
+ const u_int8_t proto);
/**
* Get ESA id for entry with given parameters.
@@ -61,6 +63,17 @@ struct tkm_kernel_sad_t {
const u_int32_t spi, const u_int8_t proto);
/**
+ * Get destination host for entry with given parameters.
+ *
+ * @param reqid reqid of CHILD SA
+ * @param spi SPI of CHILD SA
+ * @param proto protocol of CHILD SA (ESP/AH)
+ * @return destination host of entry if found, NULL otherwise
+ */
+ host_t * (*get_dst_host)(tkm_kernel_sad_t * const this,
+ const u_int32_t reqid, const u_int32_t spi, const u_int8_t proto);
+
+ /**
* Remove entry with given ESA id from SAD.
*
* @param esa_id ESA identifier of entry to remove
diff --git a/src/charon-tkm/src/tkm/tkm_keymat.c b/src/charon-tkm/src/tkm/tkm_keymat.c
index 772fac8b0..80721fafe 100644
--- a/src/charon-tkm/src/tkm/tkm_keymat.c
+++ b/src/charon-tkm/src/tkm/tkm_keymat.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
* Copyrigth (C) 2012 Reto Buerki
* Copyright (C) 2012 Adrian-Ken Rueegsegger
* Hochschule fuer Technik Rapperswil
@@ -17,6 +18,7 @@
#include <daemon.h>
#include <tkm/constants.h>
#include <tkm/client.h>
+#include <crypto/hashers/hash_algorithm_set.h>
#include "tkm.h"
#include "tkm_types.h"
@@ -71,6 +73,10 @@ struct private_tkm_keymat_t {
*/
chunk_t other_init_msg;
+ /**
+ * Set of hash algorithms supported by peer for signature authentication
+ */
+ hash_algorithm_set_t *hash_algorithms;
};
/**
@@ -417,6 +423,26 @@ METHOD(keymat_v2_t, get_psk_sig, bool,
return FALSE;
}
+METHOD(keymat_v2_t, hash_algorithm_supported, bool,
+ private_tkm_keymat_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_tkm_keymat_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_tkm_keymat_t *this)
{
@@ -435,6 +461,7 @@ METHOD(keymat_t, destroy, void,
tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_AE, this->ae_ctx_id);
}
+ DESTROY_IF(this->hash_algorithms);
DESTROY_IF(this->aead_in);
DESTROY_IF(this->aead_out);
chunk_free(&this->auth_payload);
@@ -488,6 +515,8 @@ tkm_keymat_t *tkm_keymat_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,
},
.get_isa_id = _get_isa_id,
.set_auth_payload = _set_auth_payload,
diff --git a/src/charon-tkm/src/tkm/tkm_listener.c b/src/charon-tkm/src/tkm/tkm_listener.c
index b2692a586..bb1218266 100644
--- a/src/charon-tkm/src/tkm/tkm_listener.c
+++ b/src/charon-tkm/src/tkm/tkm_listener.c
@@ -240,6 +240,8 @@ METHOD(listener_t, authorize, bool,
return TRUE;
}
+ *success = FALSE;
+
keymat = (tkm_keymat_t*)ike_sa->get_keymat(ike_sa);
isa_id = keymat->get_isa_id(keymat);
DBG1(DBG_IKE, "TKM authorize listener called for ISA context %llu", isa_id);
@@ -248,28 +250,26 @@ METHOD(listener_t, authorize, bool,
if (!cc_id)
{
DBG1(DBG_IKE, "unable to acquire CC context id");
- *success = FALSE;
return TRUE;
}
if (!build_cert_chain(ike_sa, cc_id))
{
DBG1(DBG_IKE, "unable to build certificate chain");
- *success = FALSE;
- return TRUE;
+ goto cc_reset;
}
auth = keymat->get_auth_payload(keymat);
if (!auth->ptr)
{
DBG1(DBG_IKE, "no AUTHENTICATION data available");
- *success = FALSE;
+ goto cc_reset;
}
other_init_msg = keymat->get_peer_init_msg(keymat);
if (!other_init_msg->ptr)
{
DBG1(DBG_IKE, "no peer init message available");
- *success = FALSE;
+ goto cc_reset;
}
chunk_to_sequence(auth, &signature, sizeof(signature_type));
@@ -279,7 +279,7 @@ METHOD(listener_t, authorize, bool,
{
DBG1(DBG_IKE, "TKM based authentication failed"
" for ISA context %llu", isa_id);
- *success = FALSE;
+ goto cc_reset;
}
else
{
@@ -288,7 +288,13 @@ METHOD(listener_t, authorize, bool,
*success = TRUE;
}
- return TRUE;
+cc_reset:
+ if (ike_cc_reset(cc_id) != TKM_OK)
+ {
+ DBG1(DBG_IKE, "unable to reset CC context %llu", cc_id);
+ }
+ tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_CC, cc_id);
+ return TRUE; /* stay registered */
}
METHOD(listener_t, message, bool,
diff --git a/src/charon-tkm/tests/diffie_hellman_tests.c b/src/charon-tkm/tests/diffie_hellman_tests.c
index 89658a770..5ef6f41ab 100644
--- a/src/charon-tkm/tests/diffie_hellman_tests.c
+++ b/src/charon-tkm/tests/diffie_hellman_tests.c
@@ -40,7 +40,7 @@ START_TEST(test_dh_get_my_pubvalue)
fail_if(!dh, "Unable to create DH");
chunk_t value;
- dh->dh.get_my_public_value(&dh->dh, &value);
+ ck_assert(dh->dh.get_my_public_value(&dh->dh, &value));
dh->dh.destroy(&dh->dh);
fail_if(value.ptr == NULL, "Pubvalue is NULL");
diff --git a/src/charon-tkm/tests/kernel_sad_tests.c b/src/charon-tkm/tests/kernel_sad_tests.c
index 6f0b396d3..b9ab3cb5e 100644
--- a/src/charon-tkm/tests/kernel_sad_tests.c
+++ b/src/charon-tkm/tests/kernel_sad_tests.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
* Copyright (C) 2012 Adrian-Ken Rueegsegger
* Hochschule fuer Technik Rapperswil
*
@@ -34,7 +34,7 @@ START_TEST(test_insert)
host_t *addr = host_create_from_string("127.0.0.1", 1024);
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
- fail_unless(sad->insert(sad, 1, addr, addr, 42, 50),
+ fail_unless(sad->insert(sad, 1, 2, addr, addr, 42, 50),
"Error inserting SAD entry");
sad->destroy(sad);
@@ -47,9 +47,9 @@ START_TEST(test_insert_duplicate)
host_t *addr = host_create_from_string("127.0.0.1", 1024);
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
- fail_unless(sad->insert(sad, 1, addr, addr, 42, 50),
+ fail_unless(sad->insert(sad, 1, 2, addr, addr, 42, 50),
"Error inserting SAD entry");
- fail_if(sad->insert(sad, 1, addr, addr, 42, 50),
+ fail_if(sad->insert(sad, 1, 2, addr, addr, 42, 50),
"Expected error inserting duplicate entry");
sad->destroy(sad);
@@ -61,7 +61,7 @@ START_TEST(test_get_esa_id)
{
host_t *addr = host_create_from_string("127.0.0.1", 1024);
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
- fail_unless(sad->insert(sad, 23, addr, addr, 42, 50),
+ fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50),
"Error inserting SAD entry");
fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
"Error getting esa id");
@@ -81,11 +81,34 @@ START_TEST(test_get_esa_id_nonexistent)
}
END_TEST
+START_TEST(test_get_dst_host)
+{
+ host_t *addr = host_create_from_string("127.0.0.1", 1024);
+ tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
+ fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50),
+ "Error inserting SAD entry");
+
+ host_t *dst = sad->get_dst_host(sad, 54, 42, 50);
+ fail_unless(addr->equals(addr, dst), "Error getting dst host");
+ sad->destroy(sad);
+ addr->destroy(addr);
+}
+END_TEST
+
+START_TEST(test_get_dst_host_nonexistent)
+{
+ tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
+ fail_unless(sad->get_dst_host(sad, 1, 12, 50) == NULL,
+ "Got dst for nonexistent SAD entry");
+ sad->destroy(sad);
+}
+END_TEST
+
START_TEST(test_remove)
{
host_t *addr = host_create_from_string("127.0.0.1", 1024);
tkm_kernel_sad_t *sad = tkm_kernel_sad_create();
- fail_unless(sad->insert(sad, 23, addr, addr, 42, 50),
+ fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50),
"Error inserting SAD entry");
fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23,
"Error getting esa id");
@@ -128,6 +151,11 @@ Suite *make_kernel_sad_tests()
tcase_add_test(tc, test_get_esa_id_nonexistent);
suite_add_tcase(s, tc);
+ tc = tcase_create("get_dst_host");
+ tcase_add_test(tc, test_get_dst_host);
+ tcase_add_test(tc, test_get_dst_host_nonexistent);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("remove");
tcase_add_test(tc, test_remove);
tcase_add_test(tc, test_remove_nonexistent);
diff --git a/src/charon-tkm/tests/keymat_tests.c b/src/charon-tkm/tests/keymat_tests.c
index 1982671d3..889965a78 100644
--- a/src/charon-tkm/tests/keymat_tests.c
+++ b/src/charon-tkm/tests/keymat_tests.c
@@ -53,8 +53,8 @@ START_TEST(test_derive_ike_keys)
/* Use the same pubvalue for both sides */
chunk_t pubvalue;
- dh->dh.get_my_public_value(&dh->dh, &pubvalue);
- dh->dh.set_other_public_value(&dh->dh, pubvalue);
+ ck_assert(dh->dh.get_my_public_value(&dh->dh, &pubvalue));
+ ck_assert(dh->dh.set_other_public_value(&dh->dh, pubvalue));
fail_unless(keymat->keymat_v2.derive_ike_keys(&keymat->keymat_v2, proposal,
&dh->dh, nonce, nonce, ike_sa_id, PRF_UNDEFINED, chunk_empty),
diff --git a/src/charon-tkm/tests/tests.c b/src/charon-tkm/tests/tests.c
index 80894a133..669f4d500 100644
--- a/src/charon-tkm/tests/tests.c
+++ b/src/charon-tkm/tests/tests.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2013 Tobias Brunner
- * Copyright (C) 2012 Reto Buerki
+ * Copyright (C) 2012-2014 Reto Buerki
* Copyright (C) 2012 Adrian-Ken Rueegsegger
* Hochschule fuer Technik Rapperswil
*
@@ -53,7 +53,7 @@ static bool test_runner_init(bool init)
libhydra_init();
libcharon_init();
lib->settings->set_int(lib->settings,
- "test_runner.filelog.stdout.default", 0);
+ "test-runner.filelog.stdout.default", 0);
charon->load_loggers(charon, NULL, FALSE);
/* Register TKM specific plugins */
diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in
index f4dcf4fb0..e1cc5c202 100644
--- a/src/charon/Makefile.in
+++ b/src/charon/Makefile.in
@@ -199,6 +199,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@
@@ -259,10 +260,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@
@@ -336,6 +339,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/checksum/Makefile.in b/src/checksum/Makefile.in
index 86e7ca6dd..4e4134625 100644
--- a/src/checksum/Makefile.in
+++ b/src/checksum/Makefile.in
@@ -266,6 +266,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@
@@ -326,10 +327,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@
@@ -403,6 +406,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/conftest/Makefile.in b/src/conftest/Makefile.in
index e3c2e4335..78438d8f5 100644
--- a/src/conftest/Makefile.in
+++ b/src/conftest/Makefile.in
@@ -213,6 +213,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@
@@ -273,10 +274,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@
@@ -350,6 +353,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/conftest/actions.c b/src/conftest/actions.c
index 7532e95cf..474672ca1 100644
--- a/src/conftest/actions.c
+++ b/src/conftest/actions.c
@@ -117,19 +117,20 @@ static job_requeue_t rekey_child(char *config)
enumerator_t *enumerator, *children;
ike_sa_t *ike_sa;
child_sa_t *child_sa;
- u_int32_t reqid = 0, spi = 0;
- protocol_id_t proto = PROTO_ESP;
+ u_int32_t spi, proto;
+ host_t *dst = NULL;
enumerator = charon->controller->create_ike_sa_enumerator(
charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
children = ike_sa->create_child_sa_enumerator(ike_sa);
- while (children->enumerate(children, (void**)&child_sa))
+ while (children->enumerate(children, &child_sa))
{
if (streq(config, child_sa->get_name(child_sa)))
{
- reqid = child_sa->get_reqid(child_sa);
+ dst = ike_sa->get_my_host(ike_sa);
+ dst = dst->clone(dst);
proto = child_sa->get_protocol(child_sa);
spi = child_sa->get_spi(child_sa, TRUE);
break;
@@ -138,11 +139,12 @@ static job_requeue_t rekey_child(char *config)
children->destroy(children);
}
enumerator->destroy(enumerator);
- if (reqid)
+ if (dst)
{
DBG1(DBG_CFG, "starting rekey of CHILD_SA '%s'", config);
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));
+ dst->destroy(dst);
}
else
{
@@ -236,7 +238,7 @@ static job_requeue_t close_child(char *config)
{
if (streq(config, child_sa->get_name(child_sa)))
{
- id = child_sa->get_reqid(child_sa);
+ id = child_sa->get_unique_id(child_sa);
break;
}
}
diff --git a/src/dumm/Makefile.in b/src/dumm/Makefile.in
index 56ac3447f..2ecf61194 100644
--- a/src/dumm/Makefile.in
+++ b/src/dumm/Makefile.in
@@ -234,6 +234,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@
@@ -294,10 +295,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@
@@ -371,6 +374,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/dumm/ext/dumm.c b/src/dumm/ext/dumm.c
index d791c089d..df7ec4703 100644
--- a/src/dumm/ext/dumm.c
+++ b/src/dumm/ext/dumm.c
@@ -629,7 +629,7 @@ static VALUE iface_each_addr(int argc, VALUE *argv, VALUE self)
linked_list_t *list;
iface_t *iface;
host_t *addr;
- char buf[64];
+ char buf[64], *fmt = "%H";
if (!rb_block_given_p())
{
@@ -645,7 +645,7 @@ static VALUE iface_each_addr(int argc, VALUE *argv, VALUE self)
enumerator->destroy(enumerator);
while (list->remove_first(list, (void**)&addr) == SUCCESS)
{
- snprintf(buf, sizeof(buf), "%H", addr);
+ snprintf(buf, sizeof(buf), fmt, addr);
addr->destroy(addr);
rb_yield(rb_str_new2(buf));
}
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index 042c46cab..64be6ac4f 100644
--- a/src/include/Makefile.in
+++ b/src/include/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@
diff --git a/src/ipsec/Makefile.in b/src/ipsec/Makefile.in
index 526c7c46e..d4dafcb0c 100644
--- a/src/ipsec/Makefile.in
+++ b/src/ipsec/Makefile.in
@@ -176,6 +176,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@
@@ -236,10 +237,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@
@@ -313,6 +316,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/ipsec/_ipsec.8 b/src/ipsec/_ipsec.8
index 9ba9bd842..d2d0c2edd 100644
--- a/src/ipsec/_ipsec.8
+++ b/src/ipsec/_ipsec.8
@@ -1,4 +1,4 @@
-.TH IPSEC 8 "2013-10-29" "5.2.1" "strongSwan"
+.TH IPSEC 8 "2013-10-29" "5.3.0" "strongSwan"
.
.SH NAME
.
@@ -210,15 +210,18 @@ flushes and rereads all secrets defined in \fIipsec.secrets\fP.
.
.TP
.B "rereadcacerts"
-reads all certificate files contained in the \fI/etc/ipsec.d/cacerts\fP
-directory and adds them to the list of Certification Authority (CA)
-certificates.
+removes previously loaded CA certificates, reads all certificate files
+contained in the \fI/etc/ipsec.d/cacerts\fP directory and adds them to the list
+of Certification Authority (CA) certificates. This does not affect certificates
+explicitly defined in a
+.BR ipsec.conf (5)
+ca section, which may be separately updated using the \fBupdate\fP command.
.
.TP
.B "rereadaacerts"
-reads all certificate files contained in the \fI/etc/ipsec.d/aacerts\fP
-directory and adds them to the list of Authorization Authority (AA)
-certificates.
+removes previously loaded AA certificates, reads all certificate files
+contained in the \fI/etc/ipsec.d/aacerts\fP directory and adds them to the list
+of Authorization Authority (AA) certificates.
.
.TP
.B "rereadocspcerts"
diff --git a/src/ipsec/_ipsec.8.in b/src/ipsec/_ipsec.8.in
index 210d74ef8..0aef8c031 100644
--- a/src/ipsec/_ipsec.8.in
+++ b/src/ipsec/_ipsec.8.in
@@ -210,15 +210,18 @@ flushes and rereads all secrets defined in \fIipsec.secrets\fP.
.
.TP
.B "rereadcacerts"
-reads all certificate files contained in the \fI/etc/ipsec.d/cacerts\fP
-directory and adds them to the list of Certification Authority (CA)
-certificates.
+removes previously loaded CA certificates, reads all certificate files
+contained in the \fI/etc/ipsec.d/cacerts\fP directory and adds them to the list
+of Certification Authority (CA) certificates. This does not affect certificates
+explicitly defined in a
+.BR ipsec.conf (5)
+ca section, which may be separately updated using the \fBupdate\fP command.
.
.TP
.B "rereadaacerts"
-reads all certificate files contained in the \fI/etc/ipsec.d/aacerts\fP
-directory and adds them to the list of Authorization Authority (AA)
-certificates.
+removes previously loaded AA certificates, reads all certificate files
+contained in the \fI/etc/ipsec.d/aacerts\fP directory and adds them to the list
+of Authorization Authority (AA) certificates.
.
.TP
.B "rereadocspcerts"
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/libhydra/attributes/attribute_handler.h b/src/libcharon/attributes/attribute_handler.h
index bc488f6cb..3c14323a3 100644
--- a/src/libhydra/attributes/attribute_handler.h
+++ b/src/libcharon/attributes/attribute_handler.h
@@ -21,14 +21,14 @@
#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 <utils/identification.h>
#include <collections/linked_list.h>
#include "attributes.h"
-typedef struct attribute_handler_t attribute_handler_t;
-
/**
* Interface to handle configuration payload attributes.
*/
@@ -40,12 +40,12 @@ struct attribute_handler_t {
* After receiving a configuration attriubte, it is passed to each
* attribute handler until it is handled.
*
- * @param server server from which the attribute was received
+ * @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, identification_t *server,
+ bool (*handle)(attribute_handler_t *this, ike_sa_t *ike_sa,
configuration_attribute_type_t type, chunk_t data);
/**
@@ -54,19 +54,23 @@ struct attribute_handler_t {
* 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, identification_t *server,
+ 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 server server identity to request attributes from
+ * @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,
- identification_t *server, linked_list_t *vips);
+ ike_sa_t *ike_sa, linked_list_t *vips);
};
#endif /** ATTRIBUTE_HANDLER_H_ @}*/
diff --git a/src/libhydra/attributes/attribute_manager.c b/src/libcharon/attributes/attribute_manager.c
index 5fda8b426..2ab7ed118 100644
--- a/src/libhydra/attributes/attribute_manager.c
+++ b/src/libcharon/attributes/attribute_manager.c
@@ -53,15 +53,15 @@ struct private_attribute_manager_t {
typedef struct {
/** attribute group pools */
linked_list_t *pools;
- /** server/peer identity */
- identification_t *id;
+ /** 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,
- identification_t *id, host_t *requested)
+ ike_sa_t *ike_sa, host_t *requested)
{
enumerator_t *enumerator;
attribute_provider_t *current;
@@ -71,7 +71,7 @@ METHOD(attribute_manager_t, acquire_address, host_t*,
enumerator = this->providers->create_enumerator(this->providers);
while (enumerator->enumerate(enumerator, &current))
{
- host = current->acquire_address(current, pools, id, requested);
+ host = current->acquire_address(current, pools, ike_sa, requested);
if (host)
{
break;
@@ -85,7 +85,7 @@ METHOD(attribute_manager_t, acquire_address, host_t*,
METHOD(attribute_manager_t, release_address, bool,
private_attribute_manager_t *this, linked_list_t *pools, host_t *address,
- identification_t *id)
+ ike_sa_t *ike_sa)
{
enumerator_t *enumerator;
attribute_provider_t *current;
@@ -95,7 +95,7 @@ METHOD(attribute_manager_t, release_address, bool,
enumerator = this->providers->create_enumerator(this->providers);
while (enumerator->enumerate(enumerator, &current))
{
- if (current->release_address(current, pools, address, id))
+ if (current->release_address(current, pools, address, ike_sa))
{
found = TRUE;
break;
@@ -114,18 +114,18 @@ static enumerator_t *responder_enum_create(attribute_provider_t *provider,
enum_data_t *data)
{
return provider->create_attribute_enumerator(provider, data->pools,
- data->id, data->vips);
+ data->ike_sa, data->vips);
}
METHOD(attribute_manager_t, create_responder_enumerator, enumerator_t*,
private_attribute_manager_t *this, linked_list_t *pools,
- identification_t *id, linked_list_t *vips)
+ ike_sa_t *ike_sa, linked_list_t *vips)
{
enum_data_t *data;
INIT(data,
.pools = pools,
- .id = id,
+ .ike_sa = ike_sa,
.vips = vips,
);
this->lock->read_lock(this->lock);
@@ -153,7 +153,7 @@ METHOD(attribute_manager_t, remove_provider, void,
}
METHOD(attribute_manager_t, handle, attribute_handler_t*,
- private_attribute_manager_t *this, identification_t *server,
+ private_attribute_manager_t *this, ike_sa_t *ike_sa,
attribute_handler_t *handler, configuration_attribute_type_t type,
chunk_t data)
{
@@ -166,7 +166,7 @@ METHOD(attribute_manager_t, handle, attribute_handler_t*,
enumerator = this->handlers->create_enumerator(this->handlers);
while (enumerator->enumerate(enumerator, &current))
{
- if (current == handler && current->handle(current, server, type, data))
+ if (current == handler && current->handle(current, ike_sa, type, data))
{
handled = current;
break;
@@ -178,7 +178,7 @@ METHOD(attribute_manager_t, handle, attribute_handler_t*,
enumerator = this->handlers->create_enumerator(this->handlers);
while (enumerator->enumerate(enumerator, &current))
{
- if (current->handle(current, server, type, data))
+ if (current->handle(current, ike_sa, type, data))
{
handled = current;
break;
@@ -198,7 +198,7 @@ METHOD(attribute_manager_t, handle, attribute_handler_t*,
METHOD(attribute_manager_t, release, void,
private_attribute_manager_t *this, attribute_handler_t *handler,
- identification_t *server, configuration_attribute_type_t type, chunk_t data)
+ ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data)
{
enumerator_t *enumerator;
attribute_handler_t *current;
@@ -209,7 +209,7 @@ METHOD(attribute_manager_t, release, void,
{
if (current == handler)
{
- current->release(current, server, type, data);
+ current->release(current, ike_sa, type, data);
break;
}
}
@@ -231,8 +231,8 @@ typedef struct {
enumerator_t *outer;
/** inner enumerator over current handlers attributes */
enumerator_t *inner;
- /** server ID we want attributes for */
- identification_t *id;
+ /** 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;
@@ -254,7 +254,7 @@ static bool initiator_enumerate(initiator_enumerator_t *this,
}
DESTROY_IF(this->inner);
this->inner = this->handler->create_attribute_enumerator(this->handler,
- this->id, this->vips);
+ this->ike_sa, this->vips);
}
/* inject the handler as additional attribute */
*handler = this->handler;
@@ -273,7 +273,7 @@ static void initiator_destroy(initiator_enumerator_t *this)
}
METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*,
- private_attribute_manager_t *this, identification_t *id, linked_list_t *vips)
+ private_attribute_manager_t *this, ike_sa_t *ike_sa, linked_list_t *vips)
{
initiator_enumerator_t *enumerator;
@@ -285,7 +285,7 @@ METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*,
.destroy = (void*)initiator_destroy,
},
.this = this,
- .id = id,
+ .ike_sa = ike_sa,
.vips = vips,
.outer = this->handlers->create_enumerator(this->handlers),
);
@@ -345,4 +345,3 @@ attribute_manager_t *attribute_manager_create()
return &this->public;
}
-
diff --git a/src/libhydra/attributes/attribute_manager.h b/src/libcharon/attributes/attribute_manager.h
index 99f41772c..6db664968 100644
--- a/src/libhydra/attributes/attribute_manager.h
+++ b/src/libcharon/attributes/attribute_manager.h
@@ -24,6 +24,8 @@
#include "attribute_provider.h"
#include "attribute_handler.h"
+#include <sa/ike_sa.h>
+
typedef struct attribute_manager_t attribute_manager_t;
/**
@@ -40,12 +42,12 @@ 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 id peer identity to get address forua
+ * @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, identification_t *id,
+ linked_list_t *pool, ike_sa_t *ike_sa,
host_t *requested);
/**
@@ -53,23 +55,23 @@ struct attribute_manager_t {
*
* @param pools list of pool names (char*) to release to
* @param address address to release
- * @param id peer identity to get address for
+ * @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,
- identification_t *id);
+ 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 id peer identity to hand out attributes to
+ * @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, identification_t *id,
+ linked_list_t *pool, ike_sa_t *ike_sa,
linked_list_t *vips);
/**
@@ -90,38 +92,37 @@ struct attribute_manager_t {
/**
* Handle a configuration attribute by passing them to the handlers.
*
- * @param server server from which the attribute was received
+ * @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,
- identification_t *server, attribute_handler_t *handler,
+ 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 handler handler returned by handle() for this attribute
+ * @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,
- identification_t *server,
- configuration_attribute_type_t type,
+ ike_sa_t *ike_sa, configuration_attribute_type_t type,
chunk_t data);
/**
* Create an enumerator over attributes to request from server.
*
- * @param id server identity to hand out attributes to
+ * @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,
- identification_t *id, linked_list_t *vips);
+ ike_sa_t *ike_sa, linked_list_t *vips);
/**
* Register an attribute handler to the manager.
diff --git a/src/libhydra/attributes/attribute_provider.h b/src/libcharon/attributes/attribute_provider.h
index adfd4a516..57453c2a0 100644
--- a/src/libhydra/attributes/attribute_provider.h
+++ b/src/libcharon/attributes/attribute_provider.h
@@ -21,8 +21,8 @@
#ifndef ATTRIBUTE_PROVIDER_H_
#define ATTRIBUTE_PROVIDER_H_
+#include <sa/ike_sa.h>
#include <networking/host.h>
-#include <utils/identification.h>
#include <collections/linked_list.h>
typedef struct attribute_provider_t attribute_provider_t;
@@ -36,35 +36,35 @@ 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 id peer ID
+ * @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, identification_t *id,
+ 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 id peer ID
+ * @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,
- identification_t *id);
+ 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 id peer ID
+ * @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, identification_t *id,
+ linked_list_t *pools, ike_sa_t *ike_sa,
linked_list_t *vips);
};
diff --git a/src/libhydra/attributes/attributes.c b/src/libcharon/attributes/attributes.c
index 9fabcf4e4..9fabcf4e4 100644
--- a/src/libhydra/attributes/attributes.c
+++ b/src/libcharon/attributes/attributes.c
diff --git a/src/libhydra/attributes/attributes.h b/src/libcharon/attributes/attributes.h
index 5d1e9f9ba..5d1e9f9ba 100644
--- a/src/libhydra/attributes/attributes.h
+++ b/src/libcharon/attributes/attributes.h
diff --git a/src/libhydra/attributes/mem_pool.c b/src/libcharon/attributes/mem_pool.c
index cc45e5629..279668249 100644
--- a/src/libhydra/attributes/mem_pool.c
+++ b/src/libcharon/attributes/mem_pool.c
@@ -47,6 +47,11 @@ struct private_mem_pool_t {
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;
@@ -65,20 +70,25 @@ struct private_mem_pool_t {
* lock to safely access the pool
*/
mutex_t *mutex;
-
- /**
- * Do we reassign online leases to the same identity, if requested?
- */
- bool reassign_online;
};
/**
+ * 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 u_int offset */
+ /* array of online leases, as unique_lease_t */
array_t *online;
/* array of offline leases, as u_int offset */
array_t *offline;
@@ -93,13 +103,24 @@ static entry_t* entry_create(identification_t *id)
INIT(entry,
.id = id->clone(id),
- .online = array_create(sizeof(u_int), 0),
+ .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)
@@ -235,12 +256,25 @@ METHOD(mem_pool_t, get_offline, u_int,
}
/**
+ * 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 *requested, host_t *peer)
{
enumerator_t *enumerator;
+ unique_lease_t *lease, reassign;
u_int *current;
entry_t *entry;
int offset = 0;
@@ -255,8 +289,9 @@ static int get_existing(private_mem_pool_t *this, identification_t *id,
enumerator = array_create_enumerator(entry->offline);
if (enumerator->enumerate(enumerator, &current))
{
- offset = *current;
- array_insert(entry->online, ARRAY_TAIL, 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);
@@ -265,19 +300,20 @@ static int get_existing(private_mem_pool_t *this, identification_t *id,
DBG1(DBG_CFG, "reassigning offline lease to '%Y'", id);
return offset;
}
- if (!this->reassign_online)
+ if (!peer)
{
return 0;
}
/* check for a valid online lease to reassign */
enumerator = array_create_enumerator(entry->online);
- while (enumerator->enumerate(enumerator, &current))
+ while (enumerator->enumerate(enumerator, &lease))
{
- if (*current == host2offset(this, requested))
+ if (lease->offset == host2offset(this, requested) &&
+ lease->hash == hash_addr(peer))
{
- offset = *current;
+ offset = lease->offset;
/* add an additional "online" entry */
- array_insert(entry->online, ARRAY_TAIL, current);
+ array_insert(entry->online, ARRAY_TAIL, lease);
break;
}
}
@@ -292,10 +328,10 @@ static int get_existing(private_mem_pool_t *this, identification_t *id,
/**
* Get a new lease for id
*/
-static int get_new(private_mem_pool_t *this, identification_t *id)
+static int get_new(private_mem_pool_t *this, identification_t *id, host_t *peer)
{
entry_t *entry;
- u_int offset = 0;
+ unique_lease_t lease = {};
if (this->unused < this->size)
{
@@ -306,47 +342,63 @@ static int get_new(private_mem_pool_t *this, identification_t *id)
this->leases->put(this->leases, entry->id, entry);
}
/* assigning offset, starting by 1 */
- offset = ++this->unused;
- array_insert(entry->online, ARRAY_TAIL, &offset);
+ 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 offset;
+ 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)
+static int get_reassigned(private_mem_pool_t *this, identification_t *id,
+ host_t *peer)
{
enumerator_t *enumerator;
entry_t *entry;
- u_int current, offset = 0;
+ 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))
{
- offset = current;
- DBG1(DBG_CFG, "reassigning existing offline lease by '%Y'"
- " to '%Y'", entry->id, id);
+ 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 (offset)
+ if (lease.offset)
{
- entry = entry_create(id);
- array_insert(entry->online, ARRAY_TAIL, &offset);
- this->leases->put(this->leases, entry->id, entry);
+ 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 offset;
+ 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)
+ mem_pool_op_t operation, host_t *peer)
{
int offset = 0;
@@ -367,13 +419,13 @@ METHOD(mem_pool_t, acquire_address, host_t*,
switch (operation)
{
case MEM_POOL_EXISTING:
- offset = get_existing(this, id, requested);
+ offset = get_existing(this, id, requested, peer);
break;
case MEM_POOL_NEW:
- offset = get_new(this, id);
+ offset = get_new(this, id, peer);
break;
case MEM_POOL_REASSIGN:
- offset = get_reassigned(this, id);
+ offset = get_reassigned(this, id, peer);
if (!offset)
{
DBG1(DBG_CFG, "pool '%s' is full, unable to assign address",
@@ -398,7 +450,8 @@ METHOD(mem_pool_t, release_address, bool,
enumerator_t *enumerator;
bool found = FALSE, more = FALSE;
entry_t *entry;
- u_int offset, *current;
+ u_int offset;
+ unique_lease_t *current;
if (this->size != 0)
{
@@ -411,7 +464,7 @@ METHOD(mem_pool_t, release_address, bool,
enumerator = array_create_enumerator(entry->online);
while (enumerator->enumerate(enumerator, &current))
{
- if (*current == offset)
+ if (current->offset == offset)
{
if (!found)
{ /* remove the first entry only */
@@ -463,6 +516,7 @@ 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;
@@ -471,10 +525,10 @@ METHOD(enumerator_t, lease_enumerate, bool,
{
if (this->entry)
{
- if (this->online->enumerate(this->online, &offset))
+ if (this->online->enumerate(this->online, &lease))
{
*id = this->entry->id;
- *addr = this->addr = offset2host(this->pool, *offset);
+ *addr = this->addr = offset2host(this->pool, lease->offset);
*online = TRUE;
return TRUE;
}
@@ -535,10 +589,7 @@ METHOD(mem_pool_t, destroy, void,
enumerator = this->leases->create_enumerator(this->leases);
while (enumerator->enumerate(enumerator, NULL, &entry))
{
- entry->id->destroy(entry->id);
- array_destroy(entry->online);
- array_destroy(entry->offline);
- free(entry);
+ entry_destroy(entry);
}
enumerator->destroy(enumerator);
@@ -572,26 +623,45 @@ static private_mem_pool_t *create_generic(char *name)
.leases = hashtable_create((hashtable_hash_t)id_hash,
(hashtable_equals_t)id_equals, 16),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
- .reassign_online = lib->settings->get_bool(lib->settings,
- "%s.mem-pool.reassign_online", FALSE, lib->ns),
);
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, 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)
@@ -601,15 +671,31 @@ mem_pool_t *mem_pool_create(char *name, host_t *base, int bits)
base, addr_bits - bits);
}
this->size = 1 << bits;
+ this->base = base->clone(base);
if (this->size > 2)
- { /* do not use first and last addresses of a block */
- this->unused++;
- 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--;
}
- this->base = base->clone(base);
}
-
return &this->public;
}
diff --git a/src/libhydra/attributes/mem_pool.h b/src/libcharon/attributes/mem_pool.h
index 7347bb547..3ee1dd37d 100644
--- a/src/libhydra/attributes/mem_pool.h
+++ b/src/libcharon/attributes/mem_pool.h
@@ -87,13 +87,21 @@ struct mem_pool_t {
* 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 *requested, mem_pool_op_t operation,
+ host_t *peer);
/**
* Release a previously acquired address.
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/libhydra/plugins/attr/Makefile.am b/src/libcharon/plugins/attr/Makefile.am
index 5b899b80c..6bc7e77d8 100644
--- a/src/libhydra/plugins/attr/Makefile.am
+++ b/src/libcharon/plugins/attr/Makefile.am
@@ -1,6 +1,7 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
- -I$(top_srcdir)/src/libhydra
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
AM_CFLAGS = \
$(PLUGIN_CFLAGS)
diff --git a/src/libhydra/plugins/attr/Makefile.in b/src/libcharon/plugins/attr/Makefile.in
index 50ea066c5..486b3c0b0 100644
--- a/src/libhydra/plugins/attr/Makefile.in
+++ b/src/libcharon/plugins/attr/Makefile.in
@@ -78,7 +78,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-subdir = src/libhydra/plugins/attr
+subdir = src/libcharon/plugins/attr
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -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@
@@ -423,7 +428,8 @@ xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
- -I$(top_srcdir)/src/libhydra
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
AM_CFLAGS = \
$(PLUGIN_CFLAGS)
@@ -448,9 +454,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libhydra/plugins/attr/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/attr/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libhydra/plugins/attr/Makefile
+ $(AUTOMAKE) --gnu src/libcharon/plugins/attr/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
diff --git a/src/libhydra/plugins/attr/attr_plugin.c b/src/libcharon/plugins/attr/attr_plugin.c
index 72fcd6dff..9b15c3cc9 100644
--- a/src/libhydra/plugins/attr/attr_plugin.c
+++ b/src/libcharon/plugins/attr/attr_plugin.c
@@ -16,7 +16,7 @@
#include "attr_plugin.h"
#include "attr_provider.h"
-#include <hydra.h>
+#include <daemon.h>
typedef struct private_attr_plugin_t private_attr_plugin_t;
@@ -50,13 +50,13 @@ static bool plugin_cb(private_attr_plugin_t *this,
{
if (reg)
{
- 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);
}
return TRUE;
}
diff --git a/src/libhydra/plugins/attr/attr_plugin.h b/src/libcharon/plugins/attr/attr_plugin.h
index 29fb33839..0c6eebfa7 100644
--- a/src/libhydra/plugins/attr/attr_plugin.h
+++ b/src/libcharon/plugins/attr/attr_plugin.h
@@ -15,7 +15,7 @@
/**
* @defgroup attr attr
- * @ingroup hplugins
+ * @ingroup cplugins
*
* @defgroup attr_plugin attr_plugin
* @{ @ingroup attr
diff --git a/src/libhydra/plugins/attr/attr_provider.c b/src/libcharon/plugins/attr/attr_provider.c
index c1788df94..cac0ae4bf 100644
--- a/src/libhydra/plugins/attr/attr_provider.c
+++ b/src/libcharon/plugins/attr/attr_provider.c
@@ -18,7 +18,7 @@
#include <time.h>
-#include <hydra.h>
+#include <daemon.h>
#include <utils/debug.h>
#include <collections/linked_list.h>
#include <threading/rwlock.h>
@@ -78,7 +78,7 @@ static bool attr_enum_filter(void *null, attribute_entry_t **in,
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
private_attr_provider_t *this, linked_list_t *pools,
- identification_t *id, linked_list_t *vips)
+ ike_sa_t *ike_sa, linked_list_t *vips)
{
if (vips->get_count(vips))
{
diff --git a/src/libhydra/plugins/attr/attr_provider.h b/src/libcharon/plugins/attr/attr_provider.h
index 17db30408..17db30408 100644
--- a/src/libhydra/plugins/attr/attr_provider.h
+++ b/src/libcharon/plugins/attr/attr_provider.h
diff --git a/src/libhydra/plugins/attr_sql/Makefile.am b/src/libcharon/plugins/attr_sql/Makefile.am
index 6e7eae5eb..366c902f7 100644
--- a/src/libhydra/plugins/attr_sql/Makefile.am
+++ b/src/libcharon/plugins/attr_sql/Makefile.am
@@ -1,6 +1,7 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
- -I$(top_srcdir)/src/libhydra
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
AM_CFLAGS = \
$(PLUGIN_CFLAGS)
@@ -13,6 +14,6 @@ endif
libstrongswan_attr_sql_la_SOURCES = \
attr_sql_plugin.h attr_sql_plugin.c \
- sql_attribute.h sql_attribute.c
+ attr_sql_provider.h attr_sql_provider.c
libstrongswan_attr_sql_la_LDFLAGS = -module -avoid-version
diff --git a/src/libhydra/plugins/attr_sql/Makefile.in b/src/libcharon/plugins/attr_sql/Makefile.in
index 076e1f8f2..8f1b3c0ff 100644
--- a/src/libhydra/plugins/attr_sql/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/libhydra/plugins/attr_sql
+subdir = src/libcharon/plugins/attr_sql
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -129,7 +129,7 @@ am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
libstrongswan_attr_sql_la_LIBADD =
am_libstrongswan_attr_sql_la_OBJECTS = attr_sql_plugin.lo \
- sql_attribute.lo
+ attr_sql_provider.lo
libstrongswan_attr_sql_la_OBJECTS = \
$(am_libstrongswan_attr_sql_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -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@
@@ -426,7 +431,8 @@ xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
- -I$(top_srcdir)/src/libhydra
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
AM_CFLAGS = \
$(PLUGIN_CFLAGS)
@@ -435,7 +441,7 @@ AM_CFLAGS = \
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-attr-sql.la
libstrongswan_attr_sql_la_SOURCES = \
attr_sql_plugin.h attr_sql_plugin.c \
- sql_attribute.h sql_attribute.c
+ attr_sql_provider.h attr_sql_provider.c
libstrongswan_attr_sql_la_LDFLAGS = -module -avoid-version
all: all-am
@@ -451,9 +457,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libhydra/plugins/attr_sql/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/attr_sql/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libhydra/plugins/attr_sql/Makefile
+ $(AUTOMAKE) --gnu src/libcharon/plugins/attr_sql/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -529,7 +535,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr_sql_plugin.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql_attribute.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$$||'`;\
diff --git a/src/libhydra/plugins/attr_sql/attr_sql_plugin.c b/src/libcharon/plugins/attr_sql/attr_sql_plugin.c
index dde90051a..908877514 100644
--- a/src/libhydra/plugins/attr_sql/attr_sql_plugin.c
+++ b/src/libcharon/plugins/attr_sql/attr_sql_plugin.c
@@ -14,12 +14,12 @@
* for more details.
*/
-#include <hydra.h>
+#include <daemon.h>
#include <utils/debug.h>
#include <plugins/plugin_feature.h>
#include "attr_sql_plugin.h"
-#include "sql_attribute.h"
+#include "attr_sql_provider.h"
typedef struct private_attr_sql_plugin_t private_attr_sql_plugin_t;
@@ -41,7 +41,7 @@ struct private_attr_sql_plugin_t {
/**
* configuration attributes
*/
- sql_attribute_t *attribute;
+ attr_sql_provider_t *attribute;
};
METHOD(plugin_t, get_name, char*,
@@ -74,14 +74,14 @@ static bool open_database(private_attr_sql_plugin_t *this,
DBG1(DBG_CFG, "attr-sql plugin failed to connect to database");
return FALSE;
}
- this->attribute = sql_attribute_create(this->db);
- hydra->attributes->add_provider(hydra->attributes,
- &this->attribute->provider);
+ this->attribute = attr_sql_provider_create(this->db);
+ charon->attributes->add_provider(charon->attributes,
+ &this->attribute->provider);
}
else
{
- hydra->attributes->remove_provider(hydra->attributes,
- &this->attribute->provider);
+ charon->attributes->remove_provider(charon->attributes,
+ &this->attribute->provider);
this->attribute->destroy(this->attribute);
this->db->destroy(this->db);
}
diff --git a/src/libhydra/plugins/attr_sql/attr_sql_plugin.h b/src/libcharon/plugins/attr_sql/attr_sql_plugin.h
index ba85a6b28..b6b04ccc0 100644
--- a/src/libhydra/plugins/attr_sql/attr_sql_plugin.h
+++ b/src/libcharon/plugins/attr_sql/attr_sql_plugin.h
@@ -15,9 +15,9 @@
/**
* @defgroup attr_sql attr_sql
- * @ingroup hplugins
+ * @ingroup cplugins
*
- * @defgroup sql_plugin sql_plugin
+ * @defgroup attr_sql_plugin attr_sql_plugin
* @{ @ingroup attr_sql
*/
diff --git a/src/libhydra/plugins/attr_sql/sql_attribute.c b/src/libcharon/plugins/attr_sql/attr_sql_provider.c
index d527c3fba..c2410705d 100644
--- a/src/libhydra/plugins/attr_sql/sql_attribute.c
+++ b/src/libcharon/plugins/attr_sql/attr_sql_provider.c
@@ -18,19 +18,19 @@
#include <utils/debug.h>
#include <library.h>
-#include "sql_attribute.h"
+#include "attr_sql_provider.h"
-typedef struct private_sql_attribute_t private_sql_attribute_t;
+typedef struct private_attr_sql_provider_t private_attr_sql_provider_t;
/**
- * private data of sql_attribute
+ * private data of attr_sql_provider
*/
-struct private_sql_attribute_t {
+struct private_attr_sql_provider_t {
/**
* public functions
*/
- sql_attribute_t public;
+ attr_sql_provider_t public;
/**
* database connection
@@ -46,11 +46,14 @@ struct private_sql_attribute_t {
/**
* lookup/insert an identity
*/
-static u_int get_identity(private_sql_attribute_t *this, identification_t *id)
+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,
@@ -79,7 +82,7 @@ static u_int get_identity(private_sql_attribute_t *this, identification_t *id)
/**
* Lookup an attribute pool by name
*/
-static u_int get_attr_pool(private_sql_attribute_t *this, char *name)
+static u_int get_attr_pool(private_attr_sql_provider_t *this, char *name)
{
enumerator_t *e;
u_int row = 0;
@@ -99,7 +102,7 @@ static u_int get_attr_pool(private_sql_attribute_t *this, char *name)
/**
* Lookup pool by name and address family
*/
-static u_int get_pool(private_sql_attribute_t *this, char *name, int family,
+static u_int get_pool(private_attr_sql_provider_t *this, char *name, int family,
u_int *timeout)
{
enumerator_t *e;
@@ -125,7 +128,7 @@ static u_int get_pool(private_sql_attribute_t *this, char *name, int family,
/**
* Look up an existing lease
*/
-static host_t* check_lease(private_sql_attribute_t *this, char *name,
+static host_t* check_lease(private_attr_sql_provider_t *this, char *name,
u_int pool, u_int identity)
{
while (TRUE)
@@ -171,7 +174,7 @@ static host_t* check_lease(private_sql_attribute_t *this, char *name,
* 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_sql_attribute_t *this, char *name,
+static host_t* get_lease(private_attr_sql_provider_t *this, char *name,
u_int pool, u_int timeout, u_int identity)
{
while (TRUE)
@@ -243,7 +246,7 @@ static host_t* get_lease(private_sql_attribute_t *this, char *name,
}
METHOD(attribute_provider_t, acquire_address, host_t*,
- private_sql_attribute_t *this, linked_list_t *pools, identification_t *id,
+ private_attr_sql_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
host_t *requested)
{
enumerator_t *enumerator;
@@ -252,7 +255,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
char *name;
int family;
- identity = get_identity(this, id);
+ identity = get_identity(this, ike_sa);
if (identity)
{
family = requested->get_family(requested);
@@ -295,8 +298,8 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
}
METHOD(attribute_provider_t, release_address, bool,
- private_sql_attribute_t *this, linked_list_t *pools, host_t *address,
- identification_t *id)
+ 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;
@@ -338,7 +341,7 @@ METHOD(attribute_provider_t, release_address, bool,
}
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
- private_sql_attribute_t *this, linked_list_t *pools, identification_t *id,
+ private_attr_sql_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
linked_list_t *vips)
{
enumerator_t *attr_enumerator = NULL;
@@ -350,9 +353,9 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
char *name;
/* in a first step check for attributes that match name and id */
- if (id)
+ if (ike_sa)
{
- u_int identity = get_identity(this, id);
+ u_int identity = get_identity(this, ike_sa);
pool_enumerator = pools->create_enumerator(pools);
while (pool_enumerator->enumerate(pool_enumerator, &name))
@@ -432,8 +435,8 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
return (attr_enumerator ? attr_enumerator : enumerator_create_empty());
}
-METHOD(sql_attribute_t, destroy, void,
- private_sql_attribute_t *this)
+METHOD(attr_sql_provider_t, destroy, void,
+ private_attr_sql_provider_t *this)
{
free(this);
}
@@ -441,9 +444,9 @@ METHOD(sql_attribute_t, destroy, void,
/*
* see header file
*/
-sql_attribute_t *sql_attribute_create(database_t *db)
+attr_sql_provider_t *attr_sql_provider_create(database_t *db)
{
- private_sql_attribute_t *this;
+ private_attr_sql_provider_t *this;
time_t now = time(NULL);
INIT(this,
diff --git a/src/libhydra/plugins/attr_sql/sql_attribute.h b/src/libcharon/plugins/attr_sql/attr_sql_provider.h
index ca87eb27e..a9b037bf5 100644
--- a/src/libhydra/plugins/attr_sql/sql_attribute.h
+++ b/src/libcharon/plugins/attr_sql/attr_sql_provider.h
@@ -14,22 +14,22 @@
*/
/**
- * @defgroup sql_attribute sql_attribute
+ * @defgroup attr_sql_provider attr_sql_provider
* @{ @ingroup attr_sql
*/
-#ifndef SQL_ATTRIBUTE_H_
-#define SQL_ATTRIBUTE_H_
+#ifndef ATTR_SQL_PROVIDER_H_
+#define ATTR_SQL_PROVIDER_H_
#include <attributes/attribute_provider.h>
#include <database/database.h>
-typedef struct sql_attribute_t sql_attribute_t;
+typedef struct attr_sql_provider_t attr_sql_provider_t;
/**
* SQL database based IKEv2 cfg attribute provider.
*/
-struct sql_attribute_t {
+struct attr_sql_provider_t {
/**
* Implements attribute provider interface
@@ -37,14 +37,14 @@ struct sql_attribute_t {
attribute_provider_t provider;
/**
- * Destroy a sql_attribute instance.
+ * Destroy a attr_sql_provider instance.
*/
- void (*destroy)(sql_attribute_t *this);
+ void (*destroy)(attr_sql_provider_t *this);
};
/**
- * Create a sql_attribute instance.
+ * Create a attr_sql_provider instance.
*/
-sql_attribute_t *sql_attribute_create(database_t *db);
+attr_sql_provider_t *attr_sql_provider_create(database_t *db);
-#endif /** SQL_ATTRIBUTE_H_ @}*/
+#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/unit_tester/Makefile.in b/src/libcharon/plugins/connmark/Makefile.in
index 1aca319c7..65f53fde9 100644
--- a/src/libcharon/plugins/unit_tester/Makefile.in
+++ b/src/libcharon/plugins/connmark/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/connmark
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -127,25 +127,23 @@ 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)
+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_unit_tester_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+libstrongswan_connmark_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_connmark_la_LDFLAGS) \
$(LDFLAGS) -o $@
-@MONOLITHIC_FALSE@am_libstrongswan_unit_tester_la_rpath = -rpath \
+@MONOLITHIC_FALSE@am_libstrongswan_connmark_la_rpath = -rpath \
@MONOLITHIC_FALSE@ $(plugindir)
-@MONOLITHIC_TRUE@am_libstrongswan_unit_tester_la_rpath =
+@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
@@ -180,8 +178,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_connmark_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_connmark_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -232,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@
@@ -292,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@
@@ -369,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@
@@ -433,22 +436,16 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/src/libcharon
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
+ $(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:
@@ -462,9 +459,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/connmark/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libcharon/plugins/unit_tester/Makefile
+ $(AUTOMAKE) --gnu src/libcharon/plugins/connmark/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -529,49 +526,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-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)
- -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)/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$$||'`;\
@@ -602,7 +568,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 +684,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 +694,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 +740,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/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/libhydra/plugins/resolve/Makefile.am b/src/libcharon/plugins/resolve/Makefile.am
index 33c3e70fc..9cfc370c0 100644
--- a/src/libhydra/plugins/resolve/Makefile.am
+++ b/src/libcharon/plugins/resolve/Makefile.am
@@ -1,6 +1,7 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
-DRESOLV_CONF=\"${resolv_conf}\"
AM_CFLAGS = \
diff --git a/src/libhydra/plugins/resolve/Makefile.in b/src/libcharon/plugins/resolve/Makefile.in
index 5b4c7bc6a..91479bf52 100644
--- a/src/libhydra/plugins/resolve/Makefile.in
+++ b/src/libcharon/plugins/resolve/Makefile.in
@@ -78,7 +78,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-subdir = src/libhydra/plugins/resolve
+subdir = src/libcharon/plugins/resolve
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -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@
@@ -427,6 +432,7 @@ 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 = \
@@ -452,9 +458,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libhydra/plugins/resolve/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/resolve/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libhydra/plugins/resolve/Makefile
+ $(AUTOMAKE) --gnu src/libcharon/plugins/resolve/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
diff --git a/src/libhydra/plugins/resolve/resolve_handler.c b/src/libcharon/plugins/resolve/resolve_handler.c
index 069466ab5..74c3960ff 100644
--- a/src/libhydra/plugins/resolve/resolve_handler.c
+++ b/src/libcharon/plugins/resolve/resolve_handler.c
@@ -185,9 +185,10 @@ static bool invoke_resolvconf(private_resolve_handler_t *this,
}
METHOD(attribute_handler_t, handle, bool,
- private_resolve_handler_t *this, identification_t *server,
+ 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;
@@ -208,6 +209,7 @@ METHOD(attribute_handler_t, handle, bool,
DESTROY_IF(addr);
return FALSE;
}
+ server = ike_sa->get_other_id(ike_sa);
this->mutex->lock(this->mutex);
if (this->use_resolvconf)
@@ -229,9 +231,10 @@ METHOD(attribute_handler_t, handle, bool,
}
METHOD(attribute_handler_t, release, void,
- private_resolve_handler_t *this, identification_t *server,
+ 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;
@@ -247,6 +250,7 @@ METHOD(attribute_handler_t, release, void,
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)
@@ -319,7 +323,7 @@ static bool has_host_family(linked_list_t *list, int family)
}
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
- private_resolve_handler_t *this, identification_t *server,
+ private_resolve_handler_t *this, ike_sa_t *ike_sa,
linked_list_t *vips)
{
attribute_enumerator_t *enumerator;
@@ -374,4 +378,3 @@ resolve_handler_t *resolve_handler_create()
return &this->public;
}
-
diff --git a/src/libhydra/plugins/resolve/resolve_handler.h b/src/libcharon/plugins/resolve/resolve_handler.h
index 77bf9781c..77bf9781c 100644
--- a/src/libhydra/plugins/resolve/resolve_handler.h
+++ b/src/libcharon/plugins/resolve/resolve_handler.h
diff --git a/src/libhydra/plugins/resolve/resolve_plugin.c b/src/libcharon/plugins/resolve/resolve_plugin.c
index 2fef09a49..193c5b602 100644
--- a/src/libhydra/plugins/resolve/resolve_plugin.c
+++ b/src/libcharon/plugins/resolve/resolve_plugin.c
@@ -16,7 +16,7 @@
#include "resolve_plugin.h"
#include "resolve_handler.h"
-#include <hydra.h>
+#include <daemon.h>
typedef struct private_resolve_plugin_t private_resolve_plugin_t;
@@ -50,13 +50,13 @@ static bool plugin_cb(private_resolve_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;
}
@@ -99,4 +99,3 @@ plugin_t *resolve_plugin_create()
return &this->public.plugin;
}
-
diff --git a/src/libhydra/plugins/resolve/resolve_plugin.h b/src/libcharon/plugins/resolve/resolve_plugin.h
index 0148b10d7..0148b10d7 100644
--- a/src/libhydra/plugins/resolve/resolve_plugin.h
+++ b/src/libcharon/plugins/resolve/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/_updown_espmark/Makefile.in b/src/libcharon/plugins/vici/python/Makefile.in
index 51a0d9a13..3a5e5ea72 100644
--- a/src/_updown_espmark/Makefile.in
+++ b/src/libcharon/plugins/vici/python/Makefile.in
@@ -13,7 +13,6 @@
# PARTICULAR PURPOSE.
@SET_MAKE@
-
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
@@ -78,9 +77,8 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-subdir = src/_updown_espmark
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(dist_ipsec_SCRIPTS) $(dist_man8_MANS)
+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 \
@@ -98,35 +96,6 @@ 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)$(ipsecdir)" "$(DESTDIR)$(man8dir)"
-SCRIPTS = $(dist_ipsec_SCRIPTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@@ -146,10 +115,29 @@ am__can_run_installinfo = \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
-man8dir = $(mandir)/man8
-NROFF = nroff
-MANS = $(dist_man8_MANS)
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@
@@ -176,6 +164,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@
@@ -236,10 +225,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@
@@ -313,6 +304,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@
@@ -371,8 +364,17 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-dist_ipsec_SCRIPTS = _updown_espmark
-dist_man8_MANS = _updown_espmark.8
+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:
@@ -385,9 +387,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/_updown_espmark/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/vici/python/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/_updown_espmark/Makefile
+ $(AUTOMAKE) --gnu src/libcharon/plugins/vici/python/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -406,88 +408,12 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
-install-dist_ipsecSCRIPTS: $(dist_ipsec_SCRIPTS)
- @$(NORMAL_INSTALL)
- @list='$(dist_ipsec_SCRIPTS)'; test -n "$(ipsecdir)" || list=; \
- if test -n "$$list"; then \
- echo " $(MKDIR_P) '$(DESTDIR)$(ipsecdir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(ipsecdir)" || exit 1; \
- fi; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
- done | \
- sed -e 'p;s,.*/,,;n' \
- -e 'h;s|.*|.|' \
- -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
- if ($$2 == $$4) { files[d] = files[d] " " $$1; \
- if (++n[d] == $(am__install_max)) { \
- print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
- else { print "f", d "/" $$4, $$1 } } \
- END { for (d in files) print "f", d, files[d] }' | \
- while read type dir files; do \
- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
- test -z "$$files" || { \
- echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(ipsecdir)$$dir'"; \
- $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(ipsecdir)$$dir" || exit $$?; \
- } \
- ; done
-
-uninstall-dist_ipsecSCRIPTS:
- @$(NORMAL_UNINSTALL)
- @list='$(dist_ipsec_SCRIPTS)'; test -n "$(ipsecdir)" || exit 0; \
- files=`for p in $$list; do echo "$$p"; done | \
- sed -e 's,.*/,,;$(transform)'`; \
- dir='$(DESTDIR)$(ipsecdir)'; $(am__uninstall_files_from_dir)
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
-install-man8: $(dist_man8_MANS)
- @$(NORMAL_INSTALL)
- @list1='$(dist_man8_MANS)'; \
- list2=''; \
- test -n "$(man8dir)" \
- && test -n "`echo $$list1$$list2`" \
- || exit 0; \
- echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
- { for i in $$list1; do echo "$$i"; done; \
- if test -n "$$list2"; then \
- for i in $$list2; do echo "$$i"; done \
- | sed -n '/\.8[a-z]*$$/p'; \
- fi; \
- } | while read p; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; echo "$$p"; \
- done | \
- sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
- sed 'N;N;s,\n, ,g' | { \
- list=; while read file base inst; do \
- if test "$$base" = "$$inst"; then list="$$list $$file"; else \
- echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
- $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
- fi; \
- done; \
- for i in $$list; do echo "$$i"; done | $(am__base_list) | \
- while read files; do \
- test -z "$$files" || { \
- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
- $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
- done; }
-
-uninstall-man8:
- @$(NORMAL_UNINSTALL)
- @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \
- files=`{ for i in $$list; do echo "$$i"; done; \
- } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
- dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
tags TAGS:
ctags CTAGS:
@@ -495,6 +421,99 @@ 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'`; \
@@ -526,12 +545,10 @@ distdir: $(DISTFILES)
fi; \
done
check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
-all-am: Makefile $(SCRIPTS) $(MANS)
+all-am: Makefile all-local
installdirs:
- for dir in "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
@@ -564,7 +581,7 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-libtool mostlyclean-am
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
distclean: distclean-am
-rm -f Makefile
@@ -582,13 +599,13 @@ info: info-am
info-am:
-install-data-am: install-dist_ipsecSCRIPTS install-man
+install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
-install-exec-am:
+install-exec-am: install-exec-local
install-html: install-html-am
@@ -598,7 +615,7 @@ install-info: install-info-am
install-info-am:
-install-man: install-man8
+install-man:
install-pdf: install-pdf-am
@@ -626,26 +643,43 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-dist_ipsecSCRIPTS uninstall-man
+uninstall-am:
-uninstall-man: uninstall-man8
+.MAKE: check-am install-am install-strip
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-am clean clean-generic clean-libtool \
- 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-dist_ipsecSCRIPTS install-dvi install-dvi-am \
- install-exec install-exec-am install-html install-html-am \
- install-info install-info-am install-man install-man8 \
+.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 uninstall-dist_ipsecSCRIPTS \
- uninstall-man uninstall-man8
+ 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.
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/starter/starter.8 b/src/libcharon/plugins/vici/python/vici/test/__init__.py
index e69de29bb..e69de29bb 100644
--- a/src/starter/starter.8
+++ 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;
+}
diff --git a/src/libfast/Makefile.in b/src/libfast/Makefile.in
index f0e9cbe35..6a3a4ebd5 100644
--- a/src/libfast/Makefile.in
+++ b/src/libfast/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/libhydra/Android.mk b/src/libhydra/Android.mk
index ff134da7b..af39f04ec 100644
--- a/src/libhydra/Android.mk
+++ b/src/libhydra/Android.mk
@@ -4,10 +4,6 @@ include $(CLEAR_VARS)
# copy-n-paste from Makefile.am
libhydra_la_SOURCES := \
hydra.c hydra.h \
-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 \
kernel/kernel_interface.c kernel/kernel_interface.h \
kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
kernel/kernel_net.c kernel/kernel_net.h \
@@ -17,8 +13,6 @@ LOCAL_SRC_FILES := $(filter %.c,$(libhydra_la_SOURCES))
# adding the plugin source files
-LOCAL_SRC_FILES += $(call add_plugin, attr)
-
LOCAL_SRC_FILES += $(call add_plugin, kernel-pfkey)
LOCAL_SRC_FILES += $(call add_plugin, kernel-netlink)
@@ -42,4 +36,3 @@ LOCAL_PRELINK_MODULE := false
LOCAL_SHARED_LIBRARIES += libstrongswan
include $(BUILD_SHARED_LIBRARY)
-
diff --git a/src/libhydra/Makefile.am b/src/libhydra/Makefile.am
index 510f2a124..9cdbc0147 100644
--- a/src/libhydra/Makefile.am
+++ b/src/libhydra/Makefile.am
@@ -2,10 +2,6 @@ ipseclib_LTLIBRARIES = libhydra.la
libhydra_la_SOURCES = \
hydra.c hydra.h \
-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 \
kernel/kernel_interface.c kernel/kernel_interface.h \
kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
kernel/kernel_net.c kernel/kernel_net.h \
@@ -37,20 +33,6 @@ else
SUBDIRS = .
endif
-if USE_ATTR
- SUBDIRS += plugins/attr
-if MONOLITHIC
- libhydra_la_LIBADD += plugins/attr/libstrongswan-attr.la
-endif
-endif
-
-if USE_ATTR_SQL
- SUBDIRS += plugins/attr_sql
-if MONOLITHIC
- libhydra_la_LIBADD += plugins/attr_sql/libstrongswan-attr-sql.la
-endif
-endif
-
if USE_KERNEL_PFKEY
SUBDIRS += plugins/kernel_pfkey
if MONOLITHIC
@@ -72,9 +54,7 @@ if MONOLITHIC
endif
endif
-if USE_RESOLVE
- SUBDIRS += plugins/resolve
if MONOLITHIC
- libhydra_la_LIBADD += plugins/resolve/libstrongswan-resolve.la
-endif
+ SUBDIRS += .
endif
+SUBDIRS += tests
diff --git a/src/libhydra/Makefile.in b/src/libhydra/Makefile.in
index e3ff1981c..9bb2e839a 100644
--- a/src/libhydra/Makefile.in
+++ b/src/libhydra/Makefile.in
@@ -79,18 +79,12 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@USE_WINDOWS_TRUE@am__append_1 = -lws2_32
-@USE_ATTR_TRUE@am__append_2 = plugins/attr
-@MONOLITHIC_TRUE@@USE_ATTR_TRUE@am__append_3 = plugins/attr/libstrongswan-attr.la
-@USE_ATTR_SQL_TRUE@am__append_4 = plugins/attr_sql
-@MONOLITHIC_TRUE@@USE_ATTR_SQL_TRUE@am__append_5 = plugins/attr_sql/libstrongswan-attr-sql.la
-@USE_KERNEL_PFKEY_TRUE@am__append_6 = plugins/kernel_pfkey
-@MONOLITHIC_TRUE@@USE_KERNEL_PFKEY_TRUE@am__append_7 = plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la
-@USE_KERNEL_PFROUTE_TRUE@am__append_8 = plugins/kernel_pfroute
-@MONOLITHIC_TRUE@@USE_KERNEL_PFROUTE_TRUE@am__append_9 = plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la
-@USE_KERNEL_NETLINK_TRUE@am__append_10 = plugins/kernel_netlink
-@MONOLITHIC_TRUE@@USE_KERNEL_NETLINK_TRUE@am__append_11 = plugins/kernel_netlink/libstrongswan-kernel-netlink.la
-@USE_RESOLVE_TRUE@am__append_12 = plugins/resolve
-@MONOLITHIC_TRUE@@USE_RESOLVE_TRUE@am__append_13 = plugins/resolve/libstrongswan-resolve.la
+@USE_KERNEL_PFKEY_TRUE@am__append_2 = plugins/kernel_pfkey
+@MONOLITHIC_TRUE@@USE_KERNEL_PFKEY_TRUE@am__append_3 = plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la
+@USE_KERNEL_PFROUTE_TRUE@am__append_4 = plugins/kernel_pfroute
+@MONOLITHIC_TRUE@@USE_KERNEL_PFROUTE_TRUE@am__append_5 = plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la
+@USE_KERNEL_NETLINK_TRUE@am__append_6 = plugins/kernel_netlink
+@MONOLITHIC_TRUE@@USE_KERNEL_NETLINK_TRUE@am__append_7 = plugins/kernel_netlink/libstrongswan-kernel-netlink.la
subdir = src/libhydra
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
@@ -144,13 +138,10 @@ am__DEPENDENCIES_1 =
libhydra_la_DEPENDENCIES = \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
$(am__DEPENDENCIES_1) $(am__append_3) $(am__append_5) \
- $(am__append_7) $(am__append_9) $(am__append_11) \
- $(am__append_13)
+ $(am__append_7)
am__dirstamp = $(am__leading_dot)dirstamp
-am_libhydra_la_OBJECTS = hydra.lo attributes/attributes.lo \
- attributes/attribute_manager.lo attributes/mem_pool.lo \
- kernel/kernel_interface.lo kernel/kernel_ipsec.lo \
- kernel/kernel_net.lo
+am_libhydra_la_OBJECTS = hydra.lo kernel/kernel_interface.lo \
+ kernel/kernel_ipsec.lo kernel/kernel_net.lo
libhydra_la_OBJECTS = $(am_libhydra_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -232,8 +223,8 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = . plugins/attr plugins/attr_sql plugins/kernel_pfkey \
- plugins/kernel_pfroute plugins/kernel_netlink plugins/resolve
+DIST_SUBDIRS = . plugins/kernel_pfkey plugins/kernel_pfroute \
+ plugins/kernel_netlink tests
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -285,6 +276,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@
@@ -345,10 +337,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@
@@ -422,6 +416,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@
@@ -483,10 +479,6 @@ xml_LIBS = @xml_LIBS@
ipseclib_LTLIBRARIES = libhydra.la
libhydra_la_SOURCES = \
hydra.c hydra.h \
-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 \
kernel/kernel_interface.c kernel/kernel_interface.h \
kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
kernel/kernel_net.c kernel/kernel_net.h \
@@ -495,8 +487,7 @@ kernel/kernel_listener.h
libhydra_la_LIBADD = \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
$(am__append_1) $(am__append_3) $(am__append_5) \
- $(am__append_7) $(am__append_9) $(am__append_11) \
- $(am__append_13)
+ $(am__append_7)
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
-DIPSEC_DIR=\"${ipsecdir}\" \
@@ -507,14 +498,12 @@ AM_LDFLAGS = \
EXTRA_DIST = Android.mk
@MONOLITHIC_FALSE@SUBDIRS = . $(am__append_2) $(am__append_4) \
-@MONOLITHIC_FALSE@ $(am__append_6) $(am__append_8) \
-@MONOLITHIC_FALSE@ $(am__append_10) $(am__append_12)
+@MONOLITHIC_FALSE@ $(am__append_6) tests
# build optional plugins
########################
@MONOLITHIC_TRUE@SUBDIRS = $(am__append_2) $(am__append_4) \
-@MONOLITHIC_TRUE@ $(am__append_6) $(am__append_8) \
-@MONOLITHIC_TRUE@ $(am__append_10) $(am__append_12)
+@MONOLITHIC_TRUE@ $(am__append_6) . tests
all: all-recursive
.SUFFIXES:
@@ -584,18 +573,6 @@ 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)
kernel/$(am__dirstamp):
@$(MKDIR_P) kernel
@: > kernel/$(am__dirstamp)
@@ -614,8 +591,6 @@ libhydra.la: $(libhydra_la_OBJECTS) $(libhydra_la_DEPENDENCIES) $(EXTRA_libhydra
mostlyclean-compile:
-rm -f *.$(OBJEXT)
- -rm -f attributes/*.$(OBJEXT)
- -rm -f attributes/*.lo
-rm -f kernel/*.$(OBJEXT)
-rm -f kernel/*.lo
@@ -623,9 +598,6 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hydra.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@kernel/$(DEPDIR)/kernel_interface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@kernel/$(DEPDIR)/kernel_ipsec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@kernel/$(DEPDIR)/kernel_net.Plo@am__quote@
@@ -659,7 +631,6 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
- -rm -rf attributes/.libs attributes/_libs
-rm -rf kernel/.libs kernel/_libs
# This directory's subdirectories are mostly independent; you can cd
@@ -850,8 +821,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 attributes/$(DEPDIR)/$(am__dirstamp)
- -rm -f attributes/$(am__dirstamp)
-rm -f kernel/$(DEPDIR)/$(am__dirstamp)
-rm -f kernel/$(am__dirstamp)
@@ -864,7 +833,7 @@ clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-recursive
- -rm -rf ./$(DEPDIR) attributes/$(DEPDIR) kernel/$(DEPDIR)
+ -rm -rf ./$(DEPDIR) kernel/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -910,7 +879,7 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
- -rm -rf ./$(DEPDIR) attributes/$(DEPDIR) kernel/$(DEPDIR)
+ -rm -rf ./$(DEPDIR) kernel/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
diff --git a/src/libhydra/hydra.c b/src/libhydra/hydra.c
index 1b5065081..47ffb59c6 100644
--- a/src/libhydra/hydra.c
+++ b/src/libhydra/hydra.c
@@ -57,7 +57,6 @@ void libhydra_deinit()
return;
}
- this->public.attributes->destroy(this->public.attributes);
this->public.kernel_interface->destroy(this->public.kernel_interface);
free(this);
hydra = NULL;
@@ -78,9 +77,6 @@ bool libhydra_init()
}
INIT(this,
- .public = {
- .attributes = attribute_manager_create(),
- },
.ref = 1,
);
hydra = &this->public;
diff --git a/src/libhydra/hydra.h b/src/libhydra/hydra.h
index 94209ff59..b23a30584 100644
--- a/src/libhydra/hydra.h
+++ b/src/libhydra/hydra.h
@@ -16,9 +16,6 @@
/**
* @defgroup libhydra libhydra
*
- * @defgroup attributes attributes
- * @ingroup libhydra
- *
* @defgroup hkernel kernel
* @ingroup libhydra
*
@@ -34,7 +31,6 @@
typedef struct hydra_t hydra_t;
-#include <attributes/attribute_manager.h>
#include <kernel/kernel_interface.h>
#include <library.h>
@@ -45,11 +41,6 @@ typedef struct hydra_t hydra_t;
struct hydra_t {
/**
- * manager for payload attributes
- */
- attribute_manager_t *attributes;
-
- /**
* kernel interface to communicate with kernel
*/
kernel_interface_t *kernel_interface;
diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c
index 3fa28e054..ce31bd410 100644
--- a/src/libhydra/kernel/kernel_interface.c
+++ b/src/libhydra/kernel/kernel_interface.c
@@ -43,6 +43,8 @@
#include <utils/debug.h>
#include <threading/mutex.h>
#include <collections/linked_list.h>
+#include <collections/hashtable.h>
+#include <collections/array.h>
typedef struct private_kernel_interface_t private_kernel_interface_t;
@@ -115,6 +117,16 @@ struct private_kernel_interface_t {
linked_list_t *listeners;
/**
+ * Reqid entries indexed by reqids
+ */
+ hashtable_t *reqids;
+
+ /**
+ * Reqid entries indexed by traffic selectors
+ */
+ hashtable_t *reqids_by_ts;
+
+ /**
* mutex for algorithm mappings
*/
mutex_t *mutex_algs;
@@ -155,24 +167,252 @@ METHOD(kernel_interface_t, get_features, kernel_feature_t,
METHOD(kernel_interface_t, get_spi, status_t,
private_kernel_interface_t *this, host_t *src, host_t *dst,
- u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+ u_int8_t protocol, u_int32_t *spi)
{
if (!this->ipsec)
{
return NOT_SUPPORTED;
}
- return this->ipsec->get_spi(this->ipsec, src, dst, protocol, reqid, spi);
+ return this->ipsec->get_spi(this->ipsec, src, dst, protocol, spi);
}
METHOD(kernel_interface_t, get_cpi, status_t,
private_kernel_interface_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
+ u_int16_t *cpi)
{
if (!this->ipsec)
{
return NOT_SUPPORTED;
}
- return this->ipsec->get_cpi(this->ipsec, src, dst, reqid, cpi);
+ return this->ipsec->get_cpi(this->ipsec, src, dst, cpi);
+}
+
+/**
+ * Reqid mapping entry
+ */
+typedef struct {
+ /** allocated reqid */
+ u_int32_t reqid;
+ /** references to this entry */
+ u_int refs;
+ /** inbound mark used for SA */
+ mark_t mark_in;
+ /** outbound mark used for SA */
+ mark_t mark_out;
+ /** local traffic selectors */
+ array_t *local;
+ /** remote traffic selectors */
+ array_t *remote;
+} reqid_entry_t;
+
+/**
+ * Destroy a reqid mapping entry
+ */
+static void reqid_entry_destroy(reqid_entry_t *entry)
+{
+ array_destroy_offset(entry->local, offsetof(traffic_selector_t, destroy));
+ array_destroy_offset(entry->remote, offsetof(traffic_selector_t, destroy));
+ free(entry);
+}
+
+/**
+ * Hashtable hash function for reqid entries using reqid as key
+ */
+static u_int hash_reqid(reqid_entry_t *entry)
+{
+ return chunk_hash_inc(chunk_from_thing(entry->reqid),
+ chunk_hash_inc(chunk_from_thing(entry->mark_in),
+ chunk_hash(chunk_from_thing(entry->mark_out))));
+}
+
+/**
+ * Hashtable equals function for reqid entries using reqid as key
+ */
+static bool equals_reqid(reqid_entry_t *a, reqid_entry_t *b)
+{
+ return a->reqid == b->reqid &&
+ a->mark_in.value == b->mark_in.value &&
+ a->mark_in.mask == b->mark_in.mask &&
+ a->mark_out.value == b->mark_out.value &&
+ a->mark_out.mask == b->mark_out.mask;
+}
+
+/**
+ * Hash an array of traffic selectors
+ */
+static u_int hash_ts_array(array_t *array, u_int hash)
+{
+ enumerator_t *enumerator;
+ traffic_selector_t *ts;
+
+ enumerator = array_create_enumerator(array);
+ while (enumerator->enumerate(enumerator, &ts))
+ {
+ hash = ts->hash(ts, hash);
+ }
+ enumerator->destroy(enumerator);
+
+ return hash;
+}
+
+/**
+ * Hashtable hash function for reqid entries using traffic selectors as key
+ */
+static u_int hash_reqid_by_ts(reqid_entry_t *entry)
+{
+ return hash_ts_array(entry->local, hash_ts_array(entry->remote,
+ chunk_hash_inc(chunk_from_thing(entry->mark_in),
+ chunk_hash(chunk_from_thing(entry->mark_out)))));
+}
+
+/**
+ * Compare two array with traffic selectors for equality
+ */
+static bool ts_array_equals(array_t *a, array_t *b)
+{
+ traffic_selector_t *tsa, *tsb;
+ enumerator_t *ae, *be;
+ bool equal = TRUE;
+
+ if (array_count(a) != array_count(b))
+ {
+ return FALSE;
+ }
+
+ ae = array_create_enumerator(a);
+ be = array_create_enumerator(b);
+ while (equal && ae->enumerate(ae, &tsa) && be->enumerate(be, &tsb))
+ {
+ equal = tsa->equals(tsa, tsb);
+ }
+ ae->destroy(ae);
+ be->destroy(be);
+
+ return equal;
+}
+
+/**
+ * Hashtable equals function for reqid entries using traffic selectors as key
+ */
+static bool equals_reqid_by_ts(reqid_entry_t *a, reqid_entry_t *b)
+{
+ return ts_array_equals(a->local, b->local) &&
+ ts_array_equals(a->remote, b->remote) &&
+ a->mark_in.value == b->mark_in.value &&
+ a->mark_in.mask == b->mark_in.mask &&
+ a->mark_out.value == b->mark_out.value &&
+ a->mark_out.mask == b->mark_out.mask;
+}
+
+/**
+ * Create an array from copied traffic selector list items
+ */
+static array_t *array_from_ts_list(linked_list_t *list)
+{
+ enumerator_t *enumerator;
+ traffic_selector_t *ts;
+ array_t *array;
+
+ array = array_create(0, 0);
+
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, &ts))
+ {
+ array_insert(array, ARRAY_TAIL, ts->clone(ts));
+ }
+ enumerator->destroy(enumerator);
+
+ return array;
+}
+
+METHOD(kernel_interface_t, alloc_reqid, status_t,
+ private_kernel_interface_t *this,
+ linked_list_t *local_ts, linked_list_t *remote_ts,
+ mark_t mark_in, mark_t mark_out, u_int32_t *reqid)
+{
+ static u_int32_t counter = 0;
+ reqid_entry_t *entry = NULL, *tmpl;
+ status_t status = SUCCESS;
+
+ INIT(tmpl,
+ .local = array_from_ts_list(local_ts),
+ .remote = array_from_ts_list(remote_ts),
+ .mark_in = mark_in,
+ .mark_out = mark_out,
+ .reqid = *reqid,
+ );
+
+ this->mutex->lock(this->mutex);
+ if (tmpl->reqid)
+ {
+ /* search by reqid if given */
+ entry = this->reqids->get(this->reqids, tmpl);
+ }
+ if (entry)
+ {
+ /* we don't require a traffic selector match for explicit reqids,
+ * as we wan't to reuse a reqid for trap-triggered policies that
+ * got narrowed during negotiation. */
+ reqid_entry_destroy(tmpl);
+ }
+ else
+ {
+ /* search by traffic selectors */
+ entry = this->reqids_by_ts->get(this->reqids_by_ts, tmpl);
+ if (entry)
+ {
+ reqid_entry_destroy(tmpl);
+ }
+ else
+ {
+ /* none found, create a new entry, allocating a reqid */
+ entry = tmpl;
+ entry->reqid = ++counter;
+ this->reqids_by_ts->put(this->reqids_by_ts, entry, entry);
+ this->reqids->put(this->reqids, entry, entry);
+ }
+ *reqid = entry->reqid;
+ }
+ entry->refs++;
+ this->mutex->unlock(this->mutex);
+
+ return status;
+}
+
+METHOD(kernel_interface_t, release_reqid, status_t,
+ private_kernel_interface_t *this, u_int32_t reqid,
+ mark_t mark_in, mark_t mark_out)
+{
+ reqid_entry_t *entry, tmpl = {
+ .reqid = reqid,
+ .mark_in = mark_in,
+ .mark_out = mark_out,
+ };
+
+ this->mutex->lock(this->mutex);
+ entry = this->reqids->remove(this->reqids, &tmpl);
+ if (entry)
+ {
+ if (--entry->refs == 0)
+ {
+ entry = this->reqids_by_ts->remove(this->reqids_by_ts, entry);
+ if (entry)
+ {
+ reqid_entry_destroy(entry);
+ }
+ }
+ else
+ {
+ this->reqids->put(this->reqids, entry, entry);
+ }
+ }
+ this->mutex->unlock(this->mutex);
+
+ if (entry)
+ {
+ return SUCCESS;
+ }
+ return NOT_FOUND;
}
METHOD(kernel_interface_t, add_sa, status_t,
@@ -181,8 +421,8 @@ METHOD(kernel_interface_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)
{
if (!this->ipsec)
{
@@ -191,7 +431,7 @@ METHOD(kernel_interface_t, add_sa, status_t,
return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,
mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode,
ipcomp, cpi, replay_window, initiator, encap, esn, inbound,
- src_ts, dst_ts);
+ update, src_ts, dst_ts);
}
METHOD(kernel_interface_t, update_sa, status_t,
@@ -575,17 +815,18 @@ METHOD(kernel_interface_t, acquire, void,
}
METHOD(kernel_interface_t, expire, void,
- private_kernel_interface_t *this, u_int32_t reqid, u_int8_t protocol,
- u_int32_t spi, bool hard)
+ private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard)
{
kernel_listener_t *listener;
enumerator_t *enumerator;
+
this->mutex->lock(this->mutex);
enumerator = this->listeners->create_enumerator(this->listeners);
while (enumerator->enumerate(enumerator, &listener))
{
if (listener->expire &&
- !listener->expire(listener, reqid, protocol, spi, hard))
+ !listener->expire(listener, protocol, spi, dst, hard))
{
this->listeners->remove_at(this->listeners, enumerator);
}
@@ -595,17 +836,18 @@ METHOD(kernel_interface_t, expire, void,
}
METHOD(kernel_interface_t, mapping, void,
- private_kernel_interface_t *this, u_int32_t reqid, u_int32_t spi,
- host_t *remote)
+ private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, host_t *remote)
{
kernel_listener_t *listener;
enumerator_t *enumerator;
+
this->mutex->lock(this->mutex);
enumerator = this->listeners->create_enumerator(this->listeners);
while (enumerator->enumerate(enumerator, &listener))
{
if (listener->mapping &&
- !listener->mapping(listener, reqid, spi, remote))
+ !listener->mapping(listener, protocol, spi, dst, remote))
{
this->listeners->remove_at(this->listeners, enumerator);
}
@@ -733,6 +975,8 @@ METHOD(kernel_interface_t, destroy, void,
DESTROY_IF(this->ipsec);
DESTROY_IF(this->net);
DESTROY_FUNCTION_IF(this->ifaces_filter, (void*)free);
+ this->reqids->destroy(this->reqids);
+ this->reqids_by_ts->destroy(this->reqids_by_ts);
this->listeners->destroy(this->listeners);
this->mutex->destroy(this->mutex);
free(this);
@@ -751,6 +995,8 @@ kernel_interface_t *kernel_interface_create()
.get_features = _get_features,
.get_spi = _get_spi,
.get_cpi = _get_cpi,
+ .alloc_reqid = _alloc_reqid,
+ .release_reqid = _release_reqid,
.add_sa = _add_sa,
.update_sa = _update_sa,
.query_sa = _query_sa,
@@ -795,6 +1041,10 @@ kernel_interface_t *kernel_interface_create()
.listeners = linked_list_create(),
.mutex_algs = mutex_create(MUTEX_TYPE_DEFAULT),
.algorithms = linked_list_create(),
+ .reqids = hashtable_create((hashtable_hash_t)hash_reqid,
+ (hashtable_equals_t)equals_reqid, 8),
+ .reqids_by_ts = hashtable_create((hashtable_hash_t)hash_reqid_by_ts,
+ (hashtable_equals_t)equals_reqid_by_ts, 8),
);
ifaces = lib->settings->get_str(lib->settings,
diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h
index cd550383c..96ce9e26d 100644
--- a/src/libhydra/kernel/kernel_interface.h
+++ b/src/libhydra/kernel/kernel_interface.h
@@ -104,39 +104,67 @@ struct kernel_interface_t {
* @param src source address of SA
* @param dst destination address of SA
* @param protocol protocol for SA (ESP/AH)
- * @param reqid unique ID for this SA
* @param spi allocated spi
- * @return SUCCESS if operation completed
+ * @return SUCCESS if operation completed
*/
status_t (*get_spi)(kernel_interface_t *this, host_t *src, host_t *dst,
- u_int8_t protocol, u_int32_t reqid, u_int32_t *spi);
+ u_int8_t protocol, u_int32_t *spi);
/**
* Get a Compression Parameter Index (CPI) from the kernel.
*
* @param src source address of SA
* @param dst destination address of SA
- * @param reqid unique ID for the corresponding SA
* @param cpi allocated cpi
- * @return SUCCESS if operation completed
+ * @return SUCCESS if operation completed
*/
status_t (*get_cpi)(kernel_interface_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi);
+ u_int16_t *cpi);
+
+ /**
+ * Allocate or confirm a reqid to use for a given SA pair.
+ *
+ * Each returned reqid by a successful call to alloc_reqid() must be
+ * released using release_reqid().
+ *
+ * The reqid parameter is an in/out parameter. If it points to non-zero,
+ * the reqid is confirmed and registered for use. If it points to zero,
+ * a reqid is allocated for the given selectors, and returned to reqid.
+ *
+ * @param local_ts traffic selectors of local side for SA
+ * @param remote_ts traffic selectors of remote side for SA
+ * @param mark_in inbound mark on SA
+ * @param mark_out outbound mark on SA
+ * @param reqid allocated reqid
+ * @return SUCCESS if reqid allocated
+ */
+ status_t (*alloc_reqid)(kernel_interface_t *this,
+ linked_list_t *local_ts, linked_list_t *remote_ts,
+ mark_t mark_in, mark_t mark_out,
+ u_int32_t *reqid);
+
+ /**
+ * Release a previously allocated reqid.
+ *
+ * @param reqid reqid to release
+ * @param mark_in inbound mark on SA
+ * @param mark_out outbound mark on SA
+ * @return SUCCESS if reqid released
+ */
+ status_t (*release_reqid)(kernel_interface_t *this, u_int32_t reqid,
+ mark_t mark_in, mark_t mark_out);
/**
* Add an SA to the SAD.
*
- * add_sa() may update an already allocated
- * SPI (via get_spi). In this case, the replace
- * flag must be set.
- * This function does install a single SA for a
- * single protocol in one direction.
+ * This function does install a single SA for a single protocol in one
+ * direction.
*
* @param src source address for this SA
* @param dst destination address for this SA
* @param spi SPI allocated by us or remote peer
* @param protocol protocol for this SA (ESP/AH)
- * @param reqid unique ID for this SA
+ * @param reqid reqid for this SA
* @param mark optional mark for this SA
* @param tfc Traffic Flow Confidentiality padding for this SA
* @param lifetime lifetime_cfg_t for this SA
@@ -152,8 +180,9 @@ struct kernel_interface_t {
* @param encap enable UDP encapsulation for NAT traversal
* @param esn TRUE to use Extended Sequence Numbers
* @param inbound TRUE if this is an inbound SA
- * @param src_ts traffic selector with BEET source address
- * @param dst_ts traffic selector with BEET destination address
+ * @param update TRUE if an SPI has already been allocated for SA
+ * @param src_ts list of source traffic selectors
+ * @param dst_ts list of destination traffic selectors
* @return SUCCESS if operation completed
*/
status_t (*add_sa) (kernel_interface_t *this,
@@ -163,9 +192,9 @@ struct kernel_interface_t {
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);
+ u_int32_t replay_window, bool initiator, bool encap,
+ bool esn, bool inbound, bool update,
+ linked_list_t *src_ts, linked_list_t *dst_ts);
/**
* Update the hosts on an installed SA.
@@ -531,23 +560,24 @@ struct kernel_interface_t {
/**
* Raise an expire event.
*
- * @param reqid reqid of the expired SA
* @param protocol protocol of the expired SA
* @param spi spi of the expired SA
+ * @param dst destination address of expired SA
* @param hard TRUE if it is a hard expire, FALSE otherwise
*/
- void (*expire)(kernel_interface_t *this, u_int32_t reqid,
- u_int8_t protocol, u_int32_t spi, bool hard);
+ void (*expire)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard);
/**
* Raise a mapping event.
*
- * @param reqid reqid of the SA
+ * @param protocol protocol of affected SA
* @param spi spi of the SA
+ * @param dst original destination address of SA
* @param remote new remote host
*/
- void (*mapping)(kernel_interface_t *this, u_int32_t reqid, u_int32_t spi,
- host_t *remote);
+ void (*mapping)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, host_t *remote);
/**
* Raise a migrate event.
diff --git a/src/libhydra/kernel/kernel_ipsec.h b/src/libhydra/kernel/kernel_ipsec.h
index eec7401e9..19caaa400 100644
--- a/src/libhydra/kernel/kernel_ipsec.h
+++ b/src/libhydra/kernel/kernel_ipsec.h
@@ -58,33 +58,28 @@ struct kernel_ipsec_t {
* @param src source address of SA
* @param dst destination address of SA
* @param protocol protocol for SA (ESP/AH)
- * @param reqid unique ID for this SA
* @param spi allocated spi
- * @return SUCCESS if operation completed
+ * @return SUCCESS if operation completed
*/
status_t (*get_spi)(kernel_ipsec_t *this, host_t *src, host_t *dst,
- u_int8_t protocol, u_int32_t reqid, u_int32_t *spi);
+ u_int8_t protocol, u_int32_t *spi);
/**
* Get a Compression Parameter Index (CPI) from the kernel.
*
* @param src source address of SA
* @param dst destination address of SA
- * @param reqid unique ID for the corresponding SA
* @param cpi allocated cpi
- * @return SUCCESS if operation completed
+ * @return SUCCESS if operation completed
*/
status_t (*get_cpi)(kernel_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi);
+ u_int16_t *cpi);
/**
* Add an SA to the SAD.
*
- * add_sa() may update an already allocated
- * SPI (via get_spi). In this case, the replace
- * flag must be set.
- * This function does install a single SA for a
- * single protocol in one direction.
+ * This function does install a single SA for a single protocol in one
+ * direction.
*
* @param src source address for this SA
* @param dst destination address for this SA
@@ -106,8 +101,9 @@ struct kernel_ipsec_t {
* @param encap enable UDP encapsulation for NAT traversal
* @param esn TRUE to use Extended Sequence Numbers
* @param inbound TRUE if this is an inbound SA
- * @param src_ts traffic selector with BEET source address
- * @param dst_ts traffic selector with BEET destination address
+ * @param update TRUE if an SPI has already been allocated for SA
+ * @param src_ts list of source traffic selectors
+ * @param dst_ts list of destination traffic selectors
* @return SUCCESS if operation completed
*/
status_t (*add_sa) (kernel_ipsec_t *this,
@@ -117,9 +113,9 @@ struct kernel_ipsec_t {
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);
+ u_int32_t replay_window, bool initiator, bool encap,
+ bool esn, bool inbound, bool update,
+ linked_list_t *src_ts, linked_list_t *dst_ts);
/**
* Update the hosts on an installed SA.
diff --git a/src/libhydra/kernel/kernel_listener.h b/src/libhydra/kernel/kernel_listener.h
index 4382a43fd..8074356a4 100644
--- a/src/libhydra/kernel/kernel_listener.h
+++ b/src/libhydra/kernel/kernel_listener.h
@@ -49,25 +49,26 @@ struct kernel_listener_t {
/**
* Hook called if an exire event for an IPsec SA is received.
*
- * @param reqid reqid of the expired SA
* @param protocol protocol of the expired SA
* @param spi spi of the expired SA
+ * @param dst destination address of expired SA
* @param hard TRUE if it is a hard expire, FALSE otherwise
* @return TRUE to remain registered, FALSE to unregister
*/
- bool (*expire)(kernel_listener_t *this, u_int32_t reqid,
- u_int8_t protocol, u_int32_t spi, bool hard);
+ bool (*expire)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard);
/**
* Hook called if the NAT mappings of an IPsec SA changed.
*
- * @param reqid reqid of the SA
+ * @param protocol IPsec protocol of affected SA
* @param spi spi of the SA
+ * @param dst old destinatino address of SA
* @param remote new remote host
* @return TRUE to remain registered, FALSE to unregister
*/
- bool (*mapping)(kernel_listener_t *this, u_int32_t reqid, u_int32_t spi,
- host_t *remote);
+ bool (*mapping)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, host_t *remote);
/**
* Hook called if a migrate event for a policy is received.
diff --git a/src/libhydra/plugins/kernel_netlink/Makefile.am b/src/libhydra/plugins/kernel_netlink/Makefile.am
index c91f9a9e4..cc8855406 100644
--- a/src/libhydra/plugins/kernel_netlink/Makefile.am
+++ b/src/libhydra/plugins/kernel_netlink/Makefile.am
@@ -21,3 +21,24 @@ libstrongswan_kernel_netlink_la_SOURCES = \
kernel_netlink_shared.h kernel_netlink_shared.c
libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version
+
+
+TESTS = tests
+
+check_PROGRAMS = $(TESTS)
+
+tests_SOURCES = \
+ tests.h tests.c \
+ suites/test_socket.c \
+ kernel_netlink_shared.c
+
+tests_CFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libstrongswan/tests \
+ -DNETLINK_MSG_LOSS_HOOK=netlink_msg_loss \
+ @COVERAGE_CFLAGS@
+
+tests_LDFLAGS = @COVERAGE_LDFLAGS@
+tests_LDADD = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la
diff --git a/src/libhydra/plugins/kernel_netlink/Makefile.in b/src/libhydra/plugins/kernel_netlink/Makefile.in
index a9b523eb8..962fe1ba1 100644
--- a/src/libhydra/plugins/kernel_netlink/Makefile.in
+++ b/src/libhydra/plugins/kernel_netlink/Makefile.in
@@ -78,6 +78,8 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+TESTS = tests$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
subdir = src/libhydra/plugins/kernel_netlink
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp
@@ -144,6 +146,18 @@ libstrongswan_kernel_netlink_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
@MONOLITHIC_FALSE@am_libstrongswan_kernel_netlink_la_rpath = -rpath \
@MONOLITHIC_FALSE@ $(plugindir)
@MONOLITHIC_TRUE@am_libstrongswan_kernel_netlink_la_rpath =
+am__EXEEXT_1 = tests$(EXEEXT)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_tests_OBJECTS = tests-tests.$(OBJEXT) \
+ suites/tests-test_socket.$(OBJEXT) \
+ tests-kernel_netlink_shared.$(OBJEXT)
+tests_OBJECTS = $(am_tests_OBJECTS)
+tests_DEPENDENCIES = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la
+tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(tests_CFLAGS) $(CFLAGS) \
+ $(tests_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@@ -178,8 +192,9 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
-SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES)
+SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES) $(tests_SOURCES)
+DIST_SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES) \
+ $(tests_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -204,6 +219,28 @@ am__define_uniq_tagged_files = \
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@
@@ -230,6 +267,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 +328,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 +407,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@
@@ -444,6 +486,22 @@ libstrongswan_kernel_netlink_la_SOURCES = \
kernel_netlink_shared.h kernel_netlink_shared.c
libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version
+tests_SOURCES = \
+ tests.h tests.c \
+ suites/test_socket.c \
+ kernel_netlink_shared.c
+
+tests_CFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libstrongswan/tests \
+ -DNETLINK_MSG_LOSS_HOOK=netlink_msg_loss \
+ @COVERAGE_CFLAGS@
+
+tests_LDFLAGS = @COVERAGE_LDFLAGS@
+tests_LDADD = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la
+
all: all-am
.SUFFIXES:
@@ -528,8 +586,30 @@ clean-pluginLTLIBRARIES:
libstrongswan-kernel-netlink.la: $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_DEPENDENCIES) $(EXTRA_libstrongswan_kernel_netlink_la_DEPENDENCIES)
$(AM_V_CCLD)$(libstrongswan_kernel_netlink_la_LINK) $(am_libstrongswan_kernel_netlink_la_rpath) $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_LIBADD) $(LIBS)
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+suites/$(am__dirstamp):
+ @$(MKDIR_P) suites
+ @: > suites/$(am__dirstamp)
+suites/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) suites/$(DEPDIR)
+ @: > suites/$(DEPDIR)/$(am__dirstamp)
+suites/tests-test_socket.$(OBJEXT): suites/$(am__dirstamp) \
+ suites/$(DEPDIR)/$(am__dirstamp)
+
+tests$(EXEEXT): $(tests_OBJECTS) $(tests_DEPENDENCIES) $(EXTRA_tests_DEPENDENCIES)
+ @rm -f tests$(EXEEXT)
+ $(AM_V_CCLD)$(tests_LINK) $(tests_OBJECTS) $(tests_LDADD) $(LIBS)
+
mostlyclean-compile:
-rm -f *.$(OBJEXT)
+ -rm -f suites/*.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@@ -538,6 +618,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_net.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_plugin.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_shared.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests-kernel_netlink_shared.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests-tests.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_socket.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@@ -563,6 +646,48 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+tests-tests.o: tests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-tests.o -MD -MP -MF $(DEPDIR)/tests-tests.Tpo -c -o tests-tests.o `test -f 'tests.c' || echo '$(srcdir)/'`tests.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-tests.Tpo $(DEPDIR)/tests-tests.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests.c' object='tests-tests.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-tests.o `test -f 'tests.c' || echo '$(srcdir)/'`tests.c
+
+tests-tests.obj: tests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-tests.obj -MD -MP -MF $(DEPDIR)/tests-tests.Tpo -c -o tests-tests.obj `if test -f 'tests.c'; then $(CYGPATH_W) 'tests.c'; else $(CYGPATH_W) '$(srcdir)/tests.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-tests.Tpo $(DEPDIR)/tests-tests.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests.c' object='tests-tests.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-tests.obj `if test -f 'tests.c'; then $(CYGPATH_W) 'tests.c'; else $(CYGPATH_W) '$(srcdir)/tests.c'; fi`
+
+suites/tests-test_socket.o: suites/test_socket.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_socket.o -MD -MP -MF suites/$(DEPDIR)/tests-test_socket.Tpo -c -o suites/tests-test_socket.o `test -f 'suites/test_socket.c' || echo '$(srcdir)/'`suites/test_socket.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_socket.Tpo suites/$(DEPDIR)/tests-test_socket.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_socket.c' object='suites/tests-test_socket.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_socket.o `test -f 'suites/test_socket.c' || echo '$(srcdir)/'`suites/test_socket.c
+
+suites/tests-test_socket.obj: suites/test_socket.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_socket.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_socket.Tpo -c -o suites/tests-test_socket.obj `if test -f 'suites/test_socket.c'; then $(CYGPATH_W) 'suites/test_socket.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_socket.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_socket.Tpo suites/$(DEPDIR)/tests-test_socket.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_socket.c' object='suites/tests-test_socket.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_socket.obj `if test -f 'suites/test_socket.c'; then $(CYGPATH_W) 'suites/test_socket.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_socket.c'; fi`
+
+tests-kernel_netlink_shared.o: kernel_netlink_shared.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-kernel_netlink_shared.o -MD -MP -MF $(DEPDIR)/tests-kernel_netlink_shared.Tpo -c -o tests-kernel_netlink_shared.o `test -f 'kernel_netlink_shared.c' || echo '$(srcdir)/'`kernel_netlink_shared.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-kernel_netlink_shared.Tpo $(DEPDIR)/tests-kernel_netlink_shared.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kernel_netlink_shared.c' object='tests-kernel_netlink_shared.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-kernel_netlink_shared.o `test -f 'kernel_netlink_shared.c' || echo '$(srcdir)/'`kernel_netlink_shared.c
+
+tests-kernel_netlink_shared.obj: kernel_netlink_shared.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-kernel_netlink_shared.obj -MD -MP -MF $(DEPDIR)/tests-kernel_netlink_shared.Tpo -c -o tests-kernel_netlink_shared.obj `if test -f 'kernel_netlink_shared.c'; then $(CYGPATH_W) 'kernel_netlink_shared.c'; else $(CYGPATH_W) '$(srcdir)/kernel_netlink_shared.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-kernel_netlink_shared.Tpo $(DEPDIR)/tests-kernel_netlink_shared.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kernel_netlink_shared.c' object='tests-kernel_netlink_shared.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-kernel_netlink_shared.obj `if test -f 'kernel_netlink_shared.c'; then $(CYGPATH_W) 'kernel_netlink_shared.c'; else $(CYGPATH_W) '$(srcdir)/kernel_netlink_shared.c'; fi`
+
mostlyclean-libtool:
-rm -f *.lo
@@ -621,6 +746,99 @@ cscopelist-am: $(am__tagged_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'`; \
@@ -652,6 +870,8 @@ distdir: $(DISTFILES)
fi; \
done
check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
@@ -684,17 +904,19 @@ 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-generic clean-libtool clean-noinstLTLIBRARIES \
- clean-pluginLTLIBRARIES mostlyclean-am
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES mostlyclean-am
distclean: distclean-am
- -rm -rf ./$(DEPDIR)
+ -rm -rf ./$(DEPDIR) suites/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -740,7 +962,7 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
+ -rm -rf ./$(DEPDIR) suites/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@@ -759,22 +981,23 @@ 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
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
+ clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pluginLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+ uninstall-pluginLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
index dfd71f3bd..03e44e510 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -38,6 +38,7 @@
#include <hydra.h>
#include <utils/debug.h>
#include <threading/mutex.h>
+#include <collections/array.h>
#include <collections/hashtable.h>
#include <collections/linked_list.h>
@@ -319,6 +320,16 @@ struct private_kernel_netlink_ipsec_t {
* Whether to track the history of a policy
*/
bool policy_history;
+
+ /**
+ * Whether to always use UPDATE to install policies
+ */
+ bool policy_update;
+
+ /**
+ * Installed port based IKE bypass policies, as bypass_t
+ */
+ array_t *bypass;
};
typedef struct route_entry_t route_entry_t;
@@ -859,25 +870,26 @@ static void process_expire(private_kernel_netlink_ipsec_t *this,
struct nlmsghdr *hdr)
{
struct xfrm_user_expire *expire;
- u_int32_t spi, reqid;
+ u_int32_t spi;
u_int8_t protocol;
+ host_t *dst;
expire = NLMSG_DATA(hdr);
protocol = expire->state.id.proto;
spi = expire->state.id.spi;
- reqid = expire->state.reqid;
DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE");
- if (protocol != IPPROTO_ESP && protocol != IPPROTO_AH)
+ if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH)
{
- DBG2(DBG_KNL, "ignoring XFRM_MSG_EXPIRE for SA with SPI %.8x and "
- "reqid {%u} which is not a CHILD_SA", ntohl(spi), reqid);
- return;
+ dst = xfrm2host(expire->state.family, &expire->state.id.daddr, 0);
+ if (dst)
+ {
+ hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+ spi, dst, expire->hard != 0);
+ dst->destroy(dst);
+ }
}
-
- hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol,
- spi, expire->hard != 0);
}
/**
@@ -961,23 +973,29 @@ static void process_mapping(private_kernel_netlink_ipsec_t *this,
struct nlmsghdr *hdr)
{
struct xfrm_user_mapping *mapping;
- u_int32_t spi, reqid;
+ u_int32_t spi;
mapping = NLMSG_DATA(hdr);
spi = mapping->id.spi;
- reqid = mapping->reqid;
DBG2(DBG_KNL, "received a XFRM_MSG_MAPPING");
if (mapping->id.proto == IPPROTO_ESP)
{
- host_t *host;
- host = xfrm2host(mapping->id.family, &mapping->new_saddr,
- mapping->new_sport);
- if (host)
+ host_t *dst, *new;
+
+ dst = xfrm2host(mapping->id.family, &mapping->id.daddr, 0);
+ if (dst)
{
- hydra->kernel_interface->mapping(hydra->kernel_interface, reqid,
- spi, host);
+ new = xfrm2host(mapping->id.family, &mapping->new_saddr,
+ mapping->new_sport);
+ if (new)
+ {
+ hydra->kernel_interface->mapping(hydra->kernel_interface,
+ IPPROTO_ESP, spi, dst, new);
+ new->destroy(new);
+ }
+ dst->destroy(dst);
}
}
}
@@ -1055,7 +1073,7 @@ METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
*/
static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this,
host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max,
- u_int32_t reqid, u_int32_t *spi)
+ u_int32_t *spi)
{
netlink_buf_t request;
struct nlmsghdr *hdr, *out;
@@ -1075,7 +1093,6 @@ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this,
host2xfrm(dst, &userspi->info.id.daddr);
userspi->info.id.proto = proto;
userspi->info.mode = XFRM_MODE_TUNNEL;
- userspi->info.reqid = reqid;
userspi->info.family = src->get_family(src);
userspi->min = min;
userspi->max = max;
@@ -1122,39 +1139,35 @@ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this,
METHOD(kernel_ipsec_t, get_spi, status_t,
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+ u_int8_t protocol, u_int32_t *spi)
{
- DBG2(DBG_KNL, "getting SPI for reqid {%u}", reqid);
-
if (get_spi_internal(this, src, dst, protocol,
- 0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS)
+ 0xc0000000, 0xcFFFFFFF, spi) != SUCCESS)
{
- DBG1(DBG_KNL, "unable to get SPI for reqid {%u}", reqid);
+ DBG1(DBG_KNL, "unable to get SPI");
return FAILED;
}
- DBG2(DBG_KNL, "got SPI %.8x for reqid {%u}", ntohl(*spi), reqid);
+ DBG2(DBG_KNL, "got SPI %.8x", ntohl(*spi));
return SUCCESS;
}
METHOD(kernel_ipsec_t, get_cpi, status_t,
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
+ u_int16_t *cpi)
{
u_int32_t received_spi = 0;
- DBG2(DBG_KNL, "getting CPI for reqid {%u}", reqid);
-
if (get_spi_internal(this, src, dst, IPPROTO_COMP,
- 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS)
+ 0x100, 0xEFFF, &received_spi) != SUCCESS)
{
- DBG1(DBG_KNL, "unable to get CPI for reqid {%u}", reqid);
+ DBG1(DBG_KNL, "unable to get CPI");
return FAILED;
}
*cpi = htons((u_int16_t)ntohl(received_spi));
- DBG2(DBG_KNL, "got CPI %.4x for reqid {%u}", ntohs(*cpi), reqid);
+ DBG2(DBG_KNL, "got CPI %.4x", ntohs(*cpi));
return SUCCESS;
}
@@ -1184,8 +1197,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)
{
netlink_buf_t request;
char *alg_name;
@@ -1193,6 +1206,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
struct xfrm_usersa_info *sa;
u_int16_t icv_size = 64;
ipsec_mode_t original_mode = mode;
+ traffic_selector_t *first_src_ts, *first_dst_ts;
status_t status = FAILED;
/* if IPComp is used, we install an additional IPComp SA. if the cpi is 0
@@ -1203,7 +1217,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,
chunk_empty, mode, ipcomp, 0, 0, initiator, FALSE, FALSE,
- inbound, src_ts, dst_ts);
+ inbound, update, src_ts, dst_ts);
ipcomp = IPCOMP_NONE;
/* use transport mode ESP SA, IPComp uses tunnel mode */
mode = MODE_TRANSPORT;
@@ -1216,7 +1230,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
hdr = &request.hdr;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- hdr->nlmsg_type = inbound ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
+ hdr->nlmsg_type = update ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
sa = NLMSG_DATA(hdr);
@@ -1238,9 +1252,10 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
* selector can be installed other traffic would get dropped */
break;
}
- if (src_ts && dst_ts)
+ if (src_ts->get_first(src_ts, (void**)&first_src_ts) == SUCCESS &&
+ dst_ts->get_first(dst_ts, (void**)&first_dst_ts) == SUCCESS)
{
- sa->sel = ts2selector(src_ts, dst_ts);
+ sa->sel = ts2selector(first_src_ts, first_dst_ts);
if (!this->proto_port_transport)
{
/* don't install proto/port on SA. This would break
@@ -1535,7 +1550,8 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
host_t *dst, mark_t mark,
struct xfrm_replay_state_esn **replay_esn,
u_int32_t *replay_esn_len,
- struct xfrm_replay_state **replay)
+ struct xfrm_replay_state **replay,
+ struct xfrm_lifetime_cur **lifetime)
{
netlink_buf_t request;
struct nlmsghdr *hdr, *out = NULL;
@@ -1603,20 +1619,27 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
rtasize = XFRM_PAYLOAD(out, struct xfrm_aevent_id);
while (RTA_OK(rta, rtasize))
{
+ if (rta->rta_type == XFRMA_LTIME_VAL &&
+ RTA_PAYLOAD(rta) == sizeof(**lifetime))
+ {
+ free(*lifetime);
+ *lifetime = malloc(RTA_PAYLOAD(rta));
+ memcpy(*lifetime, RTA_DATA(rta), RTA_PAYLOAD(rta));
+ }
if (rta->rta_type == XFRMA_REPLAY_VAL &&
RTA_PAYLOAD(rta) == sizeof(**replay))
{
+ free(*replay);
*replay = malloc(RTA_PAYLOAD(rta));
memcpy(*replay, RTA_DATA(rta), RTA_PAYLOAD(rta));
- break;
}
if (rta->rta_type == XFRMA_REPLAY_ESN_VAL &&
RTA_PAYLOAD(rta) >= sizeof(**replay_esn))
{
+ free(*replay_esn);
*replay_esn = malloc(RTA_PAYLOAD(rta));
*replay_esn_len = RTA_PAYLOAD(rta);
memcpy(*replay_esn, RTA_DATA(rta), RTA_PAYLOAD(rta));
- break;
}
rta = RTA_NEXT(rta, rtasize);
}
@@ -1798,6 +1821,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
struct xfrm_encap_tmpl* tmpl = NULL;
struct xfrm_replay_state *replay = NULL;
struct xfrm_replay_state_esn *replay_esn = NULL;
+ struct xfrm_lifetime_cur *lifetime = NULL;
u_int32_t replay_esn_len;
status_t status = FAILED;
@@ -1863,7 +1887,8 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
goto failed;
}
- get_replay_state(this, spi, protocol, dst, mark, &replay_esn, &replay_esn_len, &replay);
+ get_replay_state(this, spi, protocol, dst, mark, &replay_esn,
+ &replay_esn_len, &replay, &lifetime);
/* delete the old SA (without affecting the IPComp SA) */
if (del_sa(this, src, dst, spi, protocol, 0, mark) != SUCCESS)
@@ -1952,8 +1977,25 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
}
else
{
- DBG1(DBG_KNL, "unable to copy replay state from old SAD entry "
- "with SPI %.8x", ntohl(spi));
+ DBG1(DBG_KNL, "unable to copy replay state from old SAD entry with "
+ "SPI %.8x", ntohl(spi));
+ }
+ if (lifetime)
+ {
+ struct xfrm_lifetime_cur *state;
+
+ state = netlink_reserve(hdr, sizeof(request), XFRMA_LTIME_VAL,
+ sizeof(*state));
+ if (!state)
+ {
+ goto failed;
+ }
+ memcpy(state, lifetime, sizeof(*state));
+ }
+ else
+ {
+ DBG1(DBG_KNL, "unable to copy usage stats from old SAD entry with "
+ "SPI %.8x", ntohl(spi));
}
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
@@ -1966,6 +2008,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
failed:
free(replay);
free(replay_esn);
+ free(lifetime);
memwipe(out, len);
memwipe(&request, sizeof(request));
free(out);
@@ -2313,6 +2356,11 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
return SUCCESS;
}
+ if (this->policy_update)
+ {
+ found = TRUE;
+ }
+
DBG2(DBG_KNL, "%s policy %R === %R %N (mark %u/0x%08x)",
found ? "updating" : "adding", src_ts, dst_ts,
policy_dir_names, direction, mark.value, mark.mask);
@@ -2576,9 +2624,11 @@ METHOD(kernel_ipsec_t, flush_policies, status_t,
return SUCCESS;
}
-
-METHOD(kernel_ipsec_t, bypass_socket, bool,
- private_kernel_netlink_ipsec_t *this, int fd, int family)
+/**
+ * Bypass socket using a per-socket policy
+ */
+static bool add_socket_bypass(private_kernel_netlink_ipsec_t *this,
+ int fd, int family)
{
struct xfrm_userpolicy_info policy;
u_int sol, ipsec_policy;
@@ -2618,6 +2668,154 @@ METHOD(kernel_ipsec_t, bypass_socket, bool,
return TRUE;
}
+/**
+ * Port based IKE bypass policy
+ */
+typedef struct {
+ /** address family */
+ int family;
+ /** layer 4 protocol */
+ int proto;
+ /** port number, network order */
+ u_int16_t port;
+} bypass_t;
+
+/**
+ * Add or remove a bypass policy from/to kernel
+ */
+static bool manage_bypass(private_kernel_netlink_ipsec_t *this,
+ int type, policy_dir_t dir, bypass_t *bypass)
+{
+ netlink_buf_t request;
+ struct xfrm_selector *sel;
+ struct nlmsghdr *hdr;
+
+ memset(&request, 0, sizeof(request));
+ hdr = &request.hdr;
+ hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+ hdr->nlmsg_type = type;
+
+ if (type == XFRM_MSG_NEWPOLICY)
+ {
+ struct xfrm_userpolicy_info *policy;
+
+ hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info));
+
+ policy = NLMSG_DATA(hdr);
+ policy->dir = dir;
+ policy->priority = 32;
+ policy->action = XFRM_POLICY_ALLOW;
+ policy->share = XFRM_SHARE_ANY;
+
+ policy->lft.soft_byte_limit = XFRM_INF;
+ policy->lft.soft_packet_limit = XFRM_INF;
+ policy->lft.hard_byte_limit = XFRM_INF;
+ policy->lft.hard_packet_limit = XFRM_INF;
+
+ sel = &policy->sel;
+ }
+ else /* XFRM_MSG_DELPOLICY */
+ {
+ struct xfrm_userpolicy_id *policy;
+
+ hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id));
+
+ policy = NLMSG_DATA(hdr);
+ policy->dir = dir;
+
+ sel = &policy->sel;
+ }
+
+ sel->family = bypass->family;
+ sel->proto = bypass->proto;
+ if (dir == POLICY_IN)
+ {
+ sel->dport = bypass->port;
+ sel->dport_mask = 0xffff;
+ }
+ else
+ {
+ sel->sport = bypass->port;
+ sel->sport_mask = 0xffff;
+ }
+ return this->socket_xfrm->send_ack(this->socket_xfrm, hdr) == SUCCESS;
+}
+
+/**
+ * Bypass socket using a port-based bypass policy
+ */
+static bool add_port_bypass(private_kernel_netlink_ipsec_t *this,
+ int fd, int family)
+{
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in in;
+ struct sockaddr_in6 in6;
+ } saddr;
+ socklen_t len;
+ bypass_t bypass = {
+ .family = family,
+ };
+
+ len = sizeof(saddr);
+ if (getsockname(fd, &saddr.sa, &len) != 0)
+ {
+ return FALSE;
+ }
+#ifdef SO_PROTOCOL /* since 2.6.32 */
+ len = sizeof(bypass.proto);
+ if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &bypass.proto, &len) != 0)
+#endif
+ { /* assume UDP if SO_PROTOCOL not supported */
+ bypass.proto = IPPROTO_UDP;
+ }
+ switch (family)
+ {
+ case AF_INET:
+ bypass.port = saddr.in.sin_port;
+ break;
+ case AF_INET6:
+ bypass.port = saddr.in6.sin6_port;
+ break;
+ default:
+ return FALSE;
+ }
+
+ if (!manage_bypass(this, XFRM_MSG_NEWPOLICY, POLICY_IN, &bypass))
+ {
+ return FALSE;
+ }
+ if (!manage_bypass(this, XFRM_MSG_NEWPOLICY, POLICY_OUT, &bypass))
+ {
+ manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_IN, &bypass);
+ return FALSE;
+ }
+ array_insert(this->bypass, ARRAY_TAIL, &bypass);
+
+ return TRUE;
+}
+
+/**
+ * Remove installed port based bypass policy
+ */
+static void remove_port_bypass(bypass_t *bypass, int idx,
+ private_kernel_netlink_ipsec_t *this)
+{
+ manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_OUT, bypass);
+ manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_IN, bypass);
+}
+
+METHOD(kernel_ipsec_t, bypass_socket, bool,
+ private_kernel_netlink_ipsec_t *this, int fd, int family)
+{
+ if (lib->settings->get_bool(lib->settings,
+ "%s.plugins.kernel-netlink.port_bypass", FALSE, lib->ns))
+ {
+ return add_port_bypass(this, fd, family);
+ }
+ return add_socket_bypass(this, fd, family);
+}
+
METHOD(kernel_ipsec_t, enable_udp_decap, bool,
private_kernel_netlink_ipsec_t *this, int fd, int family, u_int16_t port)
{
@@ -2637,6 +2835,8 @@ METHOD(kernel_ipsec_t, destroy, void,
enumerator_t *enumerator;
policy_entry_t *policy;
+ array_destroy_function(this->bypass,
+ (array_callback_t)remove_port_bypass, this);
if (this->socket_xfrm_events > 0)
{
lib->watcher->remove(lib->watcher, this->socket_xfrm_events);
@@ -2688,8 +2888,11 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
(hashtable_equals_t)policy_equals, 32),
.sas = hashtable_create((hashtable_hash_t)ipsec_sa_hash,
(hashtable_equals_t)ipsec_sa_equals, 32),
+ .bypass = array_create(sizeof(bypass_t), 0),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.policy_history = TRUE,
+ .policy_update = lib->settings->get_bool(lib->settings,
+ "%s.plugins.kernel-netlink.policy_update", FALSE, lib->ns),
.install_routes = lib->settings->get_bool(lib->settings,
"%s.install_routes", TRUE, lib->ns),
.proto_port_transport = lib->settings->get_bool(lib->settings,
@@ -2711,7 +2914,9 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
fclose(f);
}
- this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names);
+ this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names,
+ lib->settings->get_bool(lib->settings,
+ "%s.plugins.kernel-netlink.parallel_xfrm", FALSE, lib->ns));
if (!this->socket_xfrm)
{
destroy(this);
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
index 9d9f15974..a431e49b7 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
@@ -1538,6 +1538,7 @@ typedef struct {
u_int8_t dst_len;
u_int32_t table;
u_int32_t oif;
+ u_int32_t priority;
} rt_entry_t;
/**
@@ -1573,6 +1574,7 @@ static rt_entry_t *parse_route(struct nlmsghdr *hdr, rt_entry_t *route)
route->dst_len = msg->rtm_dst_len;
route->table = msg->rtm_table;
route->oif = 0;
+ route->priority = 0;
}
else
{
@@ -1601,6 +1603,12 @@ static rt_entry_t *parse_route(struct nlmsghdr *hdr, rt_entry_t *route)
route->oif = *(u_int32_t*)RTA_DATA(rta);
}
break;
+ case RTA_PRIORITY:
+ if (RTA_PAYLOAD(rta) == sizeof(route->priority))
+ {
+ route->priority = *(u_int32_t*)RTA_DATA(rta);
+ }
+ break;
#ifdef HAVE_RTA_TABLE
case RTA_TABLE:
if (RTA_PAYLOAD(rta) == sizeof(route->table))
@@ -1724,11 +1732,16 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
}
route->src_host = src;
}
- /* insert route, sorted by decreasing network prefix */
+ /* insert route, sorted by priority and network prefix */
enumerator = routes->create_enumerator(routes);
while (enumerator->enumerate(enumerator, &other))
{
- if (route->dst_len > other->dst_len)
+ if (route->priority < other->priority)
+ {
+ break;
+ }
+ if (route->priority == other->priority &&
+ route->dst_len > other->dst_len)
{
break;
}
@@ -1975,6 +1988,8 @@ METHOD(kernel_net_t, add_ip, status_t,
if (iface)
{
addr_entry_t *addr;
+ char *ifname;
+ int ifi;
INIT(addr,
.ip = virtual_ip->clone(virtual_ip),
@@ -1983,26 +1998,30 @@ METHOD(kernel_net_t, add_ip, status_t,
);
iface->addrs->insert_last(iface->addrs, addr);
addr_map_entry_add(this->vips, addr, iface);
+ ifi = iface->ifindex;
+ this->lock->unlock(this->lock);
if (manage_ipaddr(this, RTM_NEWADDR, NLM_F_CREATE | NLM_F_EXCL,
- iface->ifindex, virtual_ip, prefix) == SUCCESS)
+ ifi, virtual_ip, prefix) == SUCCESS)
{
+ this->lock->write_lock(this->lock);
while (!is_vip_installed_or_gone(this, virtual_ip, &entry))
{ /* wait until address appears */
this->condvar->wait(this->condvar, this->lock);
}
if (entry)
{ /* we fail if the interface got deleted in the meantime */
- DBG2(DBG_KNL, "virtual IP %H installed on %s", virtual_ip,
- entry->iface->ifname);
+ ifname = strdup(entry->iface->ifname);
this->lock->unlock(this->lock);
+ DBG2(DBG_KNL, "virtual IP %H installed on %s",
+ virtual_ip, ifname);
/* during IKEv1 reauthentication, children get moved from
* old the new SA before the virtual IP is available. This
* kills the route for our virtual IP, reinstall. */
- queue_route_reinstall(this, strdup(entry->iface->ifname));
+ queue_route_reinstall(this, ifname);
return SUCCESS;
}
+ this->lock->unlock(this->lock);
}
- this->lock->unlock(this->lock);
DBG1(DBG_KNL, "adding virtual IP %H failed", virtual_ip);
return FAILED;
}
@@ -2048,20 +2067,23 @@ METHOD(kernel_net_t, del_ip, status_t,
if (entry->addr->refcount == 1)
{
status_t status;
+ int ifi;
/* we set this flag so that threads calling add_ip will block and wait
* until the entry is gone, also so we can wait below */
entry->addr->installed = FALSE;
- status = manage_ipaddr(this, RTM_DELADDR, 0, entry->iface->ifindex,
- virtual_ip, prefix);
+ ifi = entry->iface->ifindex;
+ this->lock->unlock(this->lock);
+ status = manage_ipaddr(this, RTM_DELADDR, 0, ifi, virtual_ip, prefix);
if (status == SUCCESS && wait)
{ /* wait until the address is really gone */
+ this->lock->write_lock(this->lock);
while (is_known_vip(this, virtual_ip))
{
this->condvar->wait(this->condvar, this->lock);
}
+ this->lock->unlock(this->lock);
}
- this->lock->unlock(this->lock);
return status;
}
else
@@ -2490,7 +2512,9 @@ kernel_netlink_net_t *kernel_netlink_net_create()
.destroy = _destroy,
},
},
- .socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names),
+ .socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names,
+ lib->settings->get_bool(lib->settings,
+ "%s.plugins.kernel-netlink.parallel_route", FALSE, lib->ns)),
.rt_exclude = linked_list_create(),
.routes = hashtable_create((hashtable_hash_t)route_entry_hash,
(hashtable_equals_t)route_entry_equals, 16),
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c
index b4cece720..a9adfe091 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
* Copyright (C) 2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
@@ -16,6 +18,7 @@
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
+#include <linux/xfrm.h>
#include <errno.h>
#include <unistd.h>
@@ -23,6 +26,9 @@
#include <utils/debug.h>
#include <threading/mutex.h>
+#include <threading/condvar.h>
+#include <collections/array.h>
+#include <collections/hashtable.h>
typedef struct private_netlink_socket_t private_netlink_socket_t;
@@ -30,20 +36,26 @@ typedef struct private_netlink_socket_t private_netlink_socket_t;
* Private variables and functions of netlink_socket_t class.
*/
struct private_netlink_socket_t {
+
/**
* public part of the netlink_socket_t object.
*/
netlink_socket_t public;
/**
- * mutex to lock access to netlink socket
+ * mutex to lock access entries
*/
mutex_t *mutex;
/**
- * current sequence number for netlink request
+ * Netlink request entries currently active, uintptr_t seq => entry_t
+ */
+ hashtable_t *entries;
+
+ /**
+ * Current sequence number for Netlink requests
*/
- int seq;
+ refcount_t seq;
/**
* netlink socket
@@ -51,119 +63,420 @@ struct private_netlink_socket_t {
int socket;
/**
+ * Netlink protocol
+ */
+ int protocol;
+
+ /**
* Enum names for Netlink messages
*/
enum_name_t *names;
+
+ /**
+ * Timeout for Netlink replies, in ms
+ */
+ u_int timeout;
+
+ /**
+ * Number of times to repeat timed out queries
+ */
+ u_int retries;
+
+ /**
+ * Use parallel netlink queries
+ */
+ bool parallel;
+
+ /**
+ * Ignore errors potentially resulting from a retransmission
+ */
+ bool ignore_retransmit_errors;
};
/**
- * Imported from kernel_netlink_ipsec.c
+ * #definable hook to simulate request message loss
*/
-extern enum_name_t *xfrm_msg_names;
-
-METHOD(netlink_socket_t, netlink_send, status_t,
- private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out,
- size_t *out_len)
-{
- union {
- struct nlmsghdr hdr;
- u_char bytes[4096];
- } response;
- struct sockaddr_nl addr;
- chunk_t result = chunk_empty;
- int len;
+#ifdef NETLINK_MSG_LOSS_HOOK
+bool NETLINK_MSG_LOSS_HOOK(struct nlmsghdr *msg);
+#define msg_loss_hook(msg) NETLINK_MSG_LOSS_HOOK(msg)
+#else
+#define msg_loss_hook(msg) FALSE
+#endif
- this->mutex->lock(this->mutex);
+/**
+ * Request entry the answer for a waiting thread is collected in
+ */
+typedef struct {
+ /** Condition variable thread is waiting */
+ condvar_t *condvar;
+ /** Array of hdrs in a multi-message response, as struct nlmsghdr* */
+ array_t *hdrs;
+ /** All response messages received? */
+ bool complete;
+} entry_t;
- in->nlmsg_seq = ++this->seq;
- in->nlmsg_pid = getpid();
+/**
+ * Clean up a thread waiting entry
+ */
+static void destroy_entry(entry_t *entry)
+{
+ entry->condvar->destroy(entry->condvar);
+ array_destroy_function(entry->hdrs, (void*)free, NULL);
+ free(entry);
+}
- memset(&addr, 0, sizeof(addr));
- addr.nl_family = AF_NETLINK;
- addr.nl_pid = 0;
- addr.nl_groups = 0;
+/**
+ * Write a Netlink message to socket
+ */
+static bool write_msg(private_netlink_socket_t *this, struct nlmsghdr *msg)
+{
+ struct sockaddr_nl addr = {
+ .nl_family = AF_NETLINK,
+ };
+ int len;
- if (this->names)
+ if (msg_loss_hook(msg))
{
- DBG3(DBG_KNL, "sending %N: %b",
- this->names, in->nlmsg_type, in, in->nlmsg_len);
+ return TRUE;
}
+
while (TRUE)
{
- len = sendto(this->socket, in, in->nlmsg_len, 0,
+ len = sendto(this->socket, msg, msg->nlmsg_len, 0,
(struct sockaddr*)&addr, sizeof(addr));
-
- if (len != in->nlmsg_len)
+ if (len != msg->nlmsg_len)
{
if (errno == EINTR)
{
- /* interrupted, try again */
continue;
}
- this->mutex->unlock(this->mutex);
- DBG1(DBG_KNL, "error sending to netlink socket: %s", strerror(errno));
- return FAILED;
+ DBG1(DBG_KNL, "netlink write error: %s", strerror(errno));
+ return FALSE;
}
- break;
+ return TRUE;
}
+}
- while (TRUE)
+/**
+ * Read a single Netlink message from socket, return 0 on error, -1 on timeout
+ */
+static ssize_t read_msg(private_netlink_socket_t *this,
+ char buf[4096], size_t buflen, bool block)
+{
+ ssize_t len;
+
+ if (block)
{
- len = recv(this->socket, &response, sizeof(response), 0);
- if (len < 0)
+ fd_set set;
+ timeval_t tv = {};
+
+ FD_ZERO(&set);
+ FD_SET(this->socket, &set);
+ timeval_add_ms(&tv, this->timeout);
+
+ if (select(this->socket + 1, &set, NULL, NULL,
+ this->timeout ? &tv : NULL) <= 0)
{
- if (errno == EINTR)
+ return -1;
+ }
+ }
+ len = recv(this->socket, buf, buflen, block ? 0 : MSG_DONTWAIT);
+ if (len == buflen)
+ {
+ DBG1(DBG_KNL, "netlink response exceeds buffer size");
+ return 0;
+ }
+ if (len < 0)
+ {
+ if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
+ {
+ DBG1(DBG_KNL, "netlink read error: %s", strerror(errno));
+ }
+ return 0;
+ }
+ return len;
+}
+
+/**
+ * Queue received response message
+ */
+static bool queue(private_netlink_socket_t *this, struct nlmsghdr *buf)
+{
+ struct nlmsghdr *hdr;
+ entry_t *entry;
+ uintptr_t seq;
+
+ seq = (uintptr_t)buf->nlmsg_seq;
+
+ this->mutex->lock(this->mutex);
+ entry = this->entries->get(this->entries, (void*)seq);
+ if (entry)
+ {
+ hdr = malloc(buf->nlmsg_len);
+ memcpy(hdr, buf, buf->nlmsg_len);
+ array_insert(entry->hdrs, ARRAY_TAIL, hdr);
+ if (hdr->nlmsg_type == NLMSG_DONE || !(hdr->nlmsg_flags & NLM_F_MULTI))
+ {
+ entry->complete = TRUE;
+ entry->condvar->signal(entry->condvar);
+ }
+ }
+ else
+ {
+ DBG1(DBG_KNL, "received unknown netlink seq %u, ignored", seq);
+ }
+ this->mutex->unlock(this->mutex);
+
+ return entry != NULL;
+}
+
+/**
+ * Read and queue response message, optionally blocking, returns TRUE on timeout
+ */
+static bool read_and_queue(private_netlink_socket_t *this, bool block)
+{
+ struct nlmsghdr *hdr;
+ union {
+ struct nlmsghdr hdr;
+ char bytes[4096];
+ } buf;
+ ssize_t len;
+
+ len = read_msg(this, buf.bytes, sizeof(buf.bytes), block);
+ if (len == -1)
+ {
+ return TRUE;
+ }
+ if (len)
+ {
+ hdr = &buf.hdr;
+ while (NLMSG_OK(hdr, len))
+ {
+ if (!queue(this, hdr))
{
- DBG1(DBG_KNL, "got interrupted");
- /* interrupted, try again */
- continue;
+ break;
}
- DBG1(DBG_KNL, "error reading from netlink socket: %s", strerror(errno));
- this->mutex->unlock(this->mutex);
- free(result.ptr);
- return FAILED;
+ hdr = NLMSG_NEXT(hdr, len);
}
- if (!NLMSG_OK(&response.hdr, len))
+ }
+ return FALSE;
+}
+
+CALLBACK(watch, bool,
+ private_netlink_socket_t *this, int fd, watcher_event_t event)
+{
+ if (event == WATCHER_READ)
+ {
+ read_and_queue(this, FALSE);
+ }
+ return TRUE;
+}
+
+/**
+ * Send a netlink request, try once
+ */
+static status_t send_once(private_netlink_socket_t *this, struct nlmsghdr *in,
+ uintptr_t seq, struct nlmsghdr **out, size_t *out_len)
+{
+ struct nlmsghdr *hdr;
+ chunk_t result = {};
+ entry_t *entry;
+
+ in->nlmsg_seq = seq;
+ in->nlmsg_pid = getpid();
+
+ if (this->names)
+ {
+ DBG3(DBG_KNL, "sending %N %u: %b", this->names, in->nlmsg_type,
+ (u_int)seq, in, in->nlmsg_len);
+ }
+
+ this->mutex->lock(this->mutex);
+ if (!write_msg(this, in))
+ {
+ this->mutex->unlock(this->mutex);
+ return FAILED;
+ }
+
+ INIT(entry,
+ .condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
+ .hdrs = array_create(0, 0),
+ );
+ this->entries->put(this->entries, (void*)seq, entry);
+
+ while (!entry->complete)
+ {
+ if (this->parallel &&
+ lib->watcher->get_state(lib->watcher) == WATCHER_RUNNING)
{
- DBG1(DBG_KNL, "received corrupted netlink message");
- this->mutex->unlock(this->mutex);
- free(result.ptr);
- return FAILED;
+ if (this->timeout)
+ {
+ if (entry->condvar->timed_wait(entry->condvar, this->mutex,
+ this->timeout))
+ {
+ break;
+ }
+ }
+ else
+ {
+ entry->condvar->wait(entry->condvar, this->mutex);
+ }
}
- if (response.hdr.nlmsg_seq != this->seq)
- {
- DBG1(DBG_KNL, "received invalid netlink sequence number");
- if (response.hdr.nlmsg_seq < this->seq)
+ else
+ { /* During (de-)initialization, no watcher thread is active.
+ * collect responses ourselves. */
+ if (read_and_queue(this, TRUE))
{
- continue;
+ break;
}
- this->mutex->unlock(this->mutex);
- free(result.ptr);
- return FAILED;
}
+ }
+ this->entries->remove(this->entries, (void*)seq);
- result = chunk_cat("mc", result, chunk_create(response.bytes, len));
+ this->mutex->unlock(this->mutex);
- /* NLM_F_MULTI flag does not seem to be set correctly, we use sequence
- * numbers to detect multi header messages */
- len = recv(this->socket, &response.hdr, sizeof(response.hdr),
- MSG_PEEK | MSG_DONTWAIT);
- if (len == sizeof(response.hdr) && response.hdr.nlmsg_seq == this->seq)
+ if (!entry->complete)
+ { /* timeout */
+ destroy_entry(entry);
+ return OUT_OF_RES;
+ }
+
+ while (array_remove(entry->hdrs, ARRAY_HEAD, &hdr))
+ {
+ if (this->names)
{
- /* seems to be multipart */
- continue;
+ DBG3(DBG_KNL, "received %N %u: %b", this->names, hdr->nlmsg_type,
+ hdr->nlmsg_seq, hdr, hdr->nlmsg_len);
}
- break;
+ result = chunk_cat("mm", result,
+ chunk_create((char*)hdr, hdr->nlmsg_len));
}
+ destroy_entry(entry);
*out_len = result.len;
*out = (struct nlmsghdr*)result.ptr;
- this->mutex->unlock(this->mutex);
-
return SUCCESS;
}
+/**
+ * Ignore errors for message types that might have completed previously
+ */
+static void ignore_retransmit_error(private_netlink_socket_t *this,
+ struct nlmsgerr *err, int type)
+{
+ switch (err->error)
+ {
+ case -EEXIST:
+ switch (this->protocol)
+ {
+ case NETLINK_XFRM:
+ switch (type)
+ {
+ case XFRM_MSG_NEWPOLICY:
+ case XFRM_MSG_NEWSA:
+ err->error = 0;
+ break;
+ }
+ break;
+ case NETLINK_ROUTE:
+ switch (type)
+ {
+ case RTM_NEWADDR:
+ case RTM_NEWLINK:
+ case RTM_NEWNEIGH:
+ case RTM_NEWROUTE:
+ case RTM_NEWRULE:
+ err->error = 0;
+ break;
+ }
+ break;
+ }
+ break;
+ case -ENOENT:
+ switch (this->protocol)
+ {
+ case NETLINK_XFRM:
+ switch (type)
+ {
+ case XFRM_MSG_DELPOLICY:
+ case XFRM_MSG_DELSA:
+ err->error = 0;
+ break;
+ }
+ break;
+ case NETLINK_ROUTE:
+ switch (type)
+ {
+ case RTM_DELADDR:
+ case RTM_DELLINK:
+ case RTM_DELNEIGH:
+ case RTM_DELROUTE:
+ case RTM_DELRULE:
+ err->error = 0;
+ break;
+ }
+ break;
+ }
+ break;
+ }
+}
+
+METHOD(netlink_socket_t, netlink_send, status_t,
+ private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out,
+ size_t *out_len)
+{
+ uintptr_t seq;
+ u_int try;
+
+ seq = ref_get(&this->seq);
+
+ for (try = 0; try <= this->retries; ++try)
+ {
+ struct nlmsghdr *hdr;
+ status_t status;
+ size_t len;
+
+ if (try > 0)
+ {
+ DBG1(DBG_KNL, "retransmitting Netlink request (%u/%u)",
+ try, this->retries);
+ }
+ status = send_once(this, in, seq, &hdr, &len);
+ switch (status)
+ {
+ case SUCCESS:
+ break;
+ case OUT_OF_RES:
+ continue;
+ default:
+ return status;
+ }
+ if (hdr->nlmsg_type == NLMSG_ERROR)
+ {
+ struct nlmsgerr* err;
+
+ err = NLMSG_DATA(hdr);
+ if (err->error == -EBUSY)
+ {
+ free(hdr);
+ try--;
+ continue;
+ }
+ if (this->ignore_retransmit_errors && try > 0)
+ {
+ ignore_retransmit_error(this, err, in->nlmsg_type);
+ }
+ }
+ *out = hdr;
+ *out_len = len;
+ return SUCCESS;
+ }
+ DBG1(DBG_KNL, "Netlink request timed out after %u retransmits",
+ this->retries);
+ return OUT_OF_RES;
+}
+
METHOD(netlink_socket_t, netlink_send_ack, status_t,
private_netlink_socket_t *this, struct nlmsghdr *in)
{
@@ -221,8 +534,13 @@ METHOD(netlink_socket_t, destroy, void,
{
if (this->socket != -1)
{
+ if (this->parallel)
+ {
+ lib->watcher->remove(lib->watcher, this->socket);
+ }
close(this->socket);
}
+ this->entries->destroy(this->entries);
this->mutex->destroy(this->mutex);
free(this);
}
@@ -230,7 +548,8 @@ METHOD(netlink_socket_t, destroy, void,
/**
* Described in header.
*/
-netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
+netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
+ bool parallel)
{
private_netlink_socket_t *this;
struct sockaddr_nl addr = {
@@ -244,9 +563,19 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
.destroy = _destroy,
},
.seq = 200,
- .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .mutex = mutex_create(MUTEX_TYPE_RECURSIVE),
.socket = socket(AF_NETLINK, SOCK_RAW, protocol),
+ .entries = hashtable_create(hashtable_hash_ptr, hashtable_equals_ptr, 4),
+ .protocol = protocol,
.names = names,
+ .timeout = lib->settings->get_int(lib->settings,
+ "%s.plugins.kernel-netlink.timeout", 0, lib->ns),
+ .retries = lib->settings->get_int(lib->settings,
+ "%s.plugins.kernel-netlink.retries", 0, lib->ns),
+ .ignore_retransmit_errors = lib->settings->get_bool(lib->settings,
+ "%s.plugins.kernel-netlink.ignore_retransmit_errors",
+ FALSE, lib->ns),
+ .parallel = parallel,
);
if (this->socket == -1)
@@ -261,6 +590,10 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names)
destroy(this);
return NULL;
}
+ if (this->parallel)
+ {
+ lib->watcher->add(lib->watcher, this->socket, WATCHER_READ, watch, this);
+ }
return &this->public;
}
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h
index 069f746d1..66682907d 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h
@@ -66,8 +66,10 @@ struct netlink_socket_t {
*
* @param protocol protocol type (e.g. NETLINK_XFRM or NETLINK_ROUTE)
* @param names optional enum names for Netlink messages
+ * @param parallel support parallel queries on this Netlink socket
*/
-netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names);
+netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names,
+ bool parallel);
/**
* Creates an rtattr and adds it to the given netlink message.
diff --git a/src/libhydra/plugins/kernel_netlink/suites/test_socket.c b/src/libhydra/plugins/kernel_netlink/suites/test_socket.c
new file mode 100644
index 000000000..3e8facd0a
--- /dev/null
+++ b/src/libhydra/plugins/kernel_netlink/suites/test_socket.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 <threading/thread.h>
+
+#include "../kernel_netlink_shared.h"
+
+/**
+ * Netlink message drop configuration
+ */
+static int drop_interval = 0;
+
+/**
+ * Netlink message drop hook
+ */
+bool netlink_msg_loss(struct nlmsghdr *hdr)
+{
+ static refcount_t i;
+
+ if (drop_interval)
+ {
+ return ref_get(&i) % drop_interval == drop_interval - 1;
+ }
+ return FALSE;
+}
+
+START_TEST(test_echo)
+{
+ netlink_socket_t *s;
+ struct nlmsghdr *out;
+ struct rtmsg *msg;
+ char dst[] = {
+ 127,0,0,1
+ };
+ size_t len;
+ netlink_buf_t request = {
+ .hdr = {
+ .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)),
+ .nlmsg_flags = NLM_F_REQUEST,
+ .nlmsg_type = RTM_GETROUTE,
+ },
+ };
+
+ msg = NLMSG_DATA(&request.hdr);
+ msg->rtm_family = AF_INET;
+ netlink_add_attribute(&request.hdr, RTA_DST,
+ chunk_from_thing(dst), sizeof(request));
+
+ s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+
+ ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
+ ck_assert_int_eq(out->nlmsg_type, RTM_NEWROUTE);
+ free(out);
+ s->destroy(s);
+}
+END_TEST
+
+START_TEST(test_echo_dump)
+{
+ netlink_socket_t *s;
+ struct nlmsghdr *out, *current;
+ struct rtgenmsg *msg;
+ size_t len;
+ netlink_buf_t request = {
+ .hdr = {
+ .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+ .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT,
+ .nlmsg_type = RTM_GETLINK,
+ },
+ };
+
+ s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+ msg = NLMSG_DATA(&request.hdr);
+ msg->rtgen_family = AF_UNSPEC;
+
+ ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
+ current = out;
+ while (TRUE)
+ {
+ ck_assert(NLMSG_OK(current, len));
+ if (current->nlmsg_type == NLMSG_DONE)
+ {
+ break;
+ }
+ ck_assert_int_eq(current->nlmsg_type, RTM_NEWLINK);
+ current = NLMSG_NEXT(current, len);
+ }
+ free(out);
+ s->destroy(s);
+}
+END_TEST
+
+CALLBACK(stress, void*,
+ netlink_socket_t *s)
+{
+ struct nlmsghdr *out;
+ struct rtmsg *msg;
+ char dst[] = {
+ 127,0,0,1
+ };
+ size_t len;
+ int i;
+ netlink_buf_t request = {
+ .hdr = {
+ .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)),
+ .nlmsg_flags = NLM_F_REQUEST,
+ .nlmsg_type = RTM_GETROUTE,
+ },
+ };
+
+ for (i = 0; i < 10; i++)
+ {
+ msg = NLMSG_DATA(&request.hdr);
+ msg->rtm_family = AF_INET;
+ netlink_add_attribute(&request.hdr, RTA_DST,
+ chunk_from_thing(dst), sizeof(request));
+
+ ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
+ ck_assert_int_eq(out->nlmsg_type, RTM_NEWROUTE);
+ free(out);
+ }
+ return NULL;
+}
+
+CALLBACK(stress_dump, void*,
+ netlink_socket_t *s)
+{
+ struct nlmsghdr *out, *current;
+ struct rtgenmsg *msg;
+ size_t len;
+ int i;
+ netlink_buf_t request = {
+ .hdr = {
+ .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+ .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT,
+ .nlmsg_type = RTM_GETLINK,
+ },
+ };
+
+ msg = NLMSG_DATA(&request.hdr);
+ msg->rtgen_family = AF_UNSPEC;
+
+ for (i = 0; i < 10; i++)
+ {
+ ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
+ current = out;
+ while (TRUE)
+ {
+ ck_assert(NLMSG_OK(current, len));
+ if (current->nlmsg_type == NLMSG_DONE)
+ {
+ break;
+ }
+ ck_assert_int_eq(current->nlmsg_type, RTM_NEWLINK);
+ current = NLMSG_NEXT(current, len);
+ }
+ free(out);
+ }
+ return NULL;
+}
+
+START_TEST(test_stress)
+{
+ thread_t *threads[10];
+ netlink_socket_t *s;
+ int i;
+
+ s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+ for (i = 0; i < countof(threads); i++)
+ {
+ threads[i] = thread_create(stress, s);
+ }
+ for (i = 0; i < countof(threads); i++)
+ {
+ threads[i]->join(threads[i]);
+ }
+ s->destroy(s);
+}
+END_TEST
+
+START_TEST(test_stress_dump)
+{
+ thread_t *threads[10];
+ netlink_socket_t *s;
+ int i;
+
+ s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+ for (i = 0; i < countof(threads); i++)
+ {
+ threads[i] = thread_create(stress_dump, s);
+ }
+ for (i = 0; i < countof(threads); i++)
+ {
+ threads[i]->join(threads[i]);
+ }
+ s->destroy(s);
+}
+END_TEST
+
+START_TEST(test_retransmit_success)
+{
+ netlink_socket_t *s;
+ struct nlmsghdr *out;
+ struct rtgenmsg *msg;
+ size_t len;
+ netlink_buf_t request = {
+ .hdr = {
+ .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+ .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT,
+ .nlmsg_type = RTM_GETLINK,
+ },
+ };
+
+ drop_interval = 2;
+
+ lib->settings->set_int(lib->settings,
+ "%s.plugins.kernel-netlink.timeout", 100, lib->ns);
+ lib->settings->set_int(lib->settings,
+ "%s.plugins.kernel-netlink.retries", 1, lib->ns);
+
+ s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+ msg = NLMSG_DATA(&request.hdr);
+ msg->rtgen_family = AF_UNSPEC;
+
+ ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
+ free(out);
+ s->destroy(s);
+
+ drop_interval = 0;
+}
+END_TEST
+
+START_TEST(test_retransmit_fail)
+{
+ netlink_socket_t *s;
+ struct nlmsghdr *out;
+ struct rtgenmsg *msg;
+ size_t len;
+ netlink_buf_t request = {
+ .hdr = {
+ .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+ .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT,
+ .nlmsg_type = RTM_GETLINK,
+ },
+ };
+
+ drop_interval = 1;
+
+ lib->settings->set_int(lib->settings,
+ "%s.plugins.kernel-netlink.timeout", 50, lib->ns);
+ lib->settings->set_int(lib->settings,
+ "%s.plugins.kernel-netlink.retries", 3, lib->ns);
+
+ s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0);
+ msg = NLMSG_DATA(&request.hdr);
+ msg->rtgen_family = AF_UNSPEC;
+
+ ck_assert(s->send(s, &request.hdr, &out, &len) == OUT_OF_RES);
+ s->destroy(s);
+
+ drop_interval = 0;
+}
+END_TEST
+
+Suite *socket_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("netlink socket");
+
+ tc = tcase_create("echo");
+ tcase_add_loop_test(tc, test_echo, 0, 2);
+ tcase_add_loop_test(tc, test_echo_dump, 0, 2);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("stress");
+ tcase_add_loop_test(tc, test_stress, 0, 2);
+ tcase_add_loop_test(tc, test_stress_dump, 0, 2);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("retransmit");
+ tcase_add_loop_test(tc, test_retransmit_success, 0, 2);
+ tcase_add_loop_test(tc, test_retransmit_fail, 0, 2);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libhydra/plugins/kernel_netlink/tests.c b/src/libhydra/plugins/kernel_netlink/tests.c
new file mode 100644
index 000000000..136b34d29
--- /dev/null
+++ b/src/libhydra/plugins/kernel_netlink/tests.c
@@ -0,0 +1,51 @@
+/*
+ * 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>
+
+/* declare test suite constructors */
+#define TEST_SUITE(x) test_suite_t* x();
+#include "tests.h"
+#undef TEST_SUITE
+
+static test_configuration_t tests[] = {
+#define TEST_SUITE(x) \
+ { .suite = x, },
+#include "tests.h"
+ { .suite = NULL, }
+};
+
+static bool test_runner_init(bool init)
+{
+ if (init)
+ {
+ dbg_default_set_level(0);
+ lib->processor->set_threads(lib->processor, 8);
+ dbg_default_set_level(1);
+ }
+ else
+ {
+ lib->processor->set_threads(lib->processor, 0);
+ lib->processor->cancel(lib->processor);
+ }
+ return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_runner_run("kernel-netlink", tests, test_runner_init);
+}
diff --git a/src/libhydra/plugins/kernel_netlink/tests.h b/src/libhydra/plugins/kernel_netlink/tests.h
new file mode 100644
index 000000000..2b6715a78
--- /dev/null
+++ b/src/libhydra/plugins/kernel_netlink/tests.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2014 Martin Willi
+ * Copyright (C) 2014 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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(socket_suite_create)
diff --git a/src/libhydra/plugins/kernel_pfkey/Makefile.in b/src/libhydra/plugins/kernel_pfkey/Makefile.in
index 821ad7710..177d2f23f 100644
--- a/src/libhydra/plugins/kernel_pfkey/Makefile.in
+++ b/src/libhydra/plugins/kernel_pfkey/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/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index 00ab5ab5a..3b32ba553 100644
--- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -1296,7 +1296,8 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this,
{
pfkey_msg_t response;
u_int8_t protocol;
- u_int32_t spi, reqid;
+ u_int32_t spi;
+ host_t *dst;
bool hard;
DBG2(DBG_KNL, "received an SADB_EXPIRE");
@@ -1309,18 +1310,18 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this,
protocol = satype2proto(msg->sadb_msg_satype);
spi = response.sa->sadb_sa_spi;
- reqid = response.x_sa2->sadb_x_sa2_reqid;
hard = response.lft_hard != NULL;
- if (protocol != IPPROTO_ESP && protocol != IPPROTO_AH)
+ if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH)
{
- DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and "
- "reqid {%u} which is not a CHILD_SA", ntohl(spi), reqid);
- return;
+ dst = host_create_from_sockaddr((sockaddr_t*)(response.dst + 1));
+ if (dst)
+ {
+ hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+ spi, dst, hard);
+ dst->destroy(dst);
+ }
}
-
- hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol,
- spi, hard);
}
#ifdef SADB_X_MIGRATE
@@ -1387,9 +1388,9 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this,
struct sadb_msg* msg)
{
pfkey_msg_t response;
- u_int32_t spi, reqid;
+ u_int32_t spi;
sockaddr_t *sa;
- host_t *host;
+ host_t *dst, *new;
DBG2(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING");
@@ -1407,7 +1408,6 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this,
}
spi = response.sa->sadb_sa_spi;
- reqid = response.x_sa2->sadb_x_sa2_reqid;
if (satype2proto(msg->sadb_msg_satype) != IPPROTO_ESP)
{
@@ -1415,6 +1415,7 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this,
}
sa = (sockaddr_t*)(response.dst + 1);
+ dst = host_create_from_sockaddr(sa);
switch (sa->sa_family)
{
case AF_INET:
@@ -1432,12 +1433,16 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this,
default:
break;
}
-
- host = host_create_from_sockaddr(sa);
- if (host)
+ if (dst)
{
- hydra->kernel_interface->mapping(hydra->kernel_interface, reqid,
- spi, host);
+ new = host_create_from_sockaddr(sa);
+ if (new)
+ {
+ hydra->kernel_interface->mapping(hydra->kernel_interface,
+ IPPROTO_ESP, spi, dst, new);
+ new->destroy(new);
+ }
+ dst->destroy(dst);
}
}
#endif /*SADB_X_NAT_T_NEW_MAPPING*/
@@ -1518,11 +1523,10 @@ static bool receive_events(private_kernel_pfkey_ipsec_t *this, int fd,
static status_t get_spi_internal(private_kernel_pfkey_ipsec_t *this,
host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max,
- u_int32_t reqid, u_int32_t *spi)
+ u_int32_t *spi)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
- struct sadb_x_sa2 *sa2;
struct sadb_spirange *range;
pfkey_msg_t response;
u_int32_t received_spi = 0;
@@ -1536,12 +1540,6 @@ static status_t get_spi_internal(private_kernel_pfkey_ipsec_t *this,
msg->sadb_msg_satype = proto2satype(proto);
msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
- sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg);
- sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange));
- sa2->sadb_x_sa2_reqid = reqid;
- PFKEY_EXT_ADD(msg, sa2);
-
add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE);
add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE);
@@ -1577,39 +1575,37 @@ static status_t get_spi_internal(private_kernel_pfkey_ipsec_t *this,
METHOD(kernel_ipsec_t, get_spi, status_t,
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
- u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+ u_int8_t protocol, u_int32_t *spi)
{
- DBG2(DBG_KNL, "getting SPI for reqid {%u}", reqid);
-
if (get_spi_internal(this, src, dst, protocol,
- 0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS)
+ 0xc0000000, 0xcFFFFFFF, spi) != SUCCESS)
{
- DBG1(DBG_KNL, "unable to get SPI for reqid {%u}", reqid);
+ DBG1(DBG_KNL, "unable to get SPI");
return FAILED;
}
- DBG2(DBG_KNL, "got SPI %.8x for reqid {%u}", ntohl(*spi), reqid);
+ DBG2(DBG_KNL, "got SPI %.8x", ntohl(*spi));
return SUCCESS;
}
METHOD(kernel_ipsec_t, get_cpi, status_t,
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
+ u_int16_t *cpi)
{
u_int32_t received_spi = 0;
- DBG2(DBG_KNL, "getting CPI for reqid {%u}", reqid);
+ DBG2(DBG_KNL, "getting CPI");
if (get_spi_internal(this, src, dst, IPPROTO_COMP,
- 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS)
+ 0x100, 0xEFFF, &received_spi) != SUCCESS)
{
- DBG1(DBG_KNL, "unable to get CPI for reqid {%u}", reqid);
+ DBG1(DBG_KNL, "unable to get CPI");
return FAILED;
}
*cpi = htons((u_int16_t)ntohl(received_spi));
- DBG2(DBG_KNL, "got CPI %.4x for reqid {%u}", ntohs(*cpi), reqid);
+ DBG2(DBG_KNL, "got CPI %.4x", ntohs(*cpi));
return SUCCESS;
}
@@ -1619,8 +1615,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
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)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -1638,12 +1634,29 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,
chunk_empty, mode, ipcomp, 0, 0, FALSE, FALSE, FALSE, inbound,
- NULL, NULL);
+ update, NULL, NULL);
ipcomp = IPCOMP_NONE;
/* use transport mode ESP SA, IPComp uses tunnel mode */
mode = MODE_TRANSPORT;
}
+ if (update)
+ {
+ /* As we didn't know the reqid during SPI allocation, we used reqid
+ * zero. Unfortunately we can't SADB_UPDATE to the new reqid, hence we
+ * have to delete the SPI allocation state manually. The reqid
+ * selector does not count for that, therefore we have to delete
+ * that state before installing the new SA to avoid deleting the
+ * the new state after installing it. */
+ mark_t zeromark = {0, 0};
+
+ if (this->public.interface.del_sa(&this->public.interface,
+ src, dst, spi, protocol, 0, zeromark) != SUCCESS)
+ {
+ DBG1(DBG_KNL, "deleting SPI allocation SA failed");
+ }
+ }
+
memset(&request, 0, sizeof(request));
DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}",
@@ -1651,7 +1664,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
msg = (struct sadb_msg*)request;
msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = inbound ? SADB_UPDATE : SADB_ADD;
+ msg->sadb_msg_type = SADB_ADD;
msg->sadb_msg_satype = proto2satype(protocol);
msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
@@ -1680,7 +1693,13 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
}
else
{
+ /* Linux interprets sadb_sa_replay as number of packets/bits in the
+ * replay window, whereas on BSD it's the size of the window in bytes */
+#ifdef __linux__
sa->sadb_sa_replay = min(replay_window, 32);
+#else
+ sa->sadb_sa_replay = (replay_window + 7) / 8;
+#endif
sa->sadb_sa_auth = lookup_algorithm(INTEGRITY_ALGORITHM, int_alg);
sa->sadb_sa_encrypt = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg);
}
@@ -2969,6 +2988,7 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
{
private_kernel_pfkey_ipsec_t *this;
bool register_for_events = TRUE;
+ int rcv_buffer;
INIT(this,
.public = {
@@ -3025,6 +3045,18 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
return NULL;
}
+ rcv_buffer = lib->settings->get_int(lib->settings,
+ "%s.plugins.kernel-pfkey.events_buffer_size", 0, lib->ns);
+ if (rcv_buffer > 0)
+ {
+ if (setsockopt(this->socket_events, SOL_SOCKET, SO_RCVBUF,
+ &rcv_buffer, sizeof(rcv_buffer)) == -1)
+ {
+ DBG1(DBG_KNL, "unable to set receive buffer size on PF_KEY "
+ "event socket: %s", strerror(errno));
+ }
+ }
+
/* register the event socket */
if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS ||
register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS)
diff --git a/src/libhydra/plugins/kernel_pfroute/Makefile.in b/src/libhydra/plugins/kernel_pfroute/Makefile.in
index 662f2fd7d..9f676d21d 100644
--- a/src/libhydra/plugins/kernel_pfroute/Makefile.in
+++ b/src/libhydra/plugins/kernel_pfroute/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/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
index 26fae0d6b..0f7802270 100644
--- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
+++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
@@ -830,6 +830,15 @@ static void process_link(private_kernel_pfroute_net_t *this,
DBG1(DBG_KNL, "interface %s deactivated", iface->ifname);
}
}
+#ifdef __APPLE__
+ /* There seems to be a race condition on 10.10, where we get
+ * the RTM_IFINFO, but getifaddrs() does not return the virtual
+ * IP installed on a tun device, but we also don't get a
+ * RTM_NEWADDR. We therefore could miss the new address, letting
+ * virtual IP installation fail. Delaying getifaddrs() helps,
+ * but is obviously not a clean fix. */
+ usleep(50000);
+#endif
iface->flags = msg->ifm_flags;
repopulate_iface(this, iface);
found = TRUE;
diff --git a/src/libhydra/tests/Makefile.am b/src/libhydra/tests/Makefile.am
new file mode 100644
index 000000000..5acd5c28c
--- /dev/null
+++ b/src/libhydra/tests/Makefile.am
@@ -0,0 +1,18 @@
+TESTS = hydra_tests
+
+check_PROGRAMS = $(TESTS)
+
+hydra_tests_SOURCES = \
+ hydra_tests.h hydra_tests.c
+
+hydra_tests_CFLAGS = \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libstrongswan/tests \
+ @COVERAGE_CFLAGS@
+
+hydra_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+hydra_tests_LDADD = \
+ $(top_builddir)/src/libhydra/libhydra.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la
diff --git a/src/libhydra/tests/Makefile.in b/src/libhydra/tests/Makefile.in
new file mode 100644
index 000000000..1fa889d67
--- /dev/null
+++ b/src/libhydra/tests/Makefile.in
@@ -0,0 +1,839 @@
+# 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 = hydra_tests$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = src/libhydra/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 = hydra_tests$(EXEEXT)
+am_hydra_tests_OBJECTS = hydra_tests-hydra_tests.$(OBJEXT)
+hydra_tests_OBJECTS = $(am_hydra_tests_OBJECTS)
+hydra_tests_DEPENDENCIES = $(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 =
+hydra_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(hydra_tests_CFLAGS) \
+ $(CFLAGS) $(hydra_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 = $(hydra_tests_SOURCES)
+DIST_SOURCES = $(hydra_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@
+hydra_tests_SOURCES = \
+ hydra_tests.h hydra_tests.c
+
+hydra_tests_CFLAGS = \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libstrongswan/tests \
+ @COVERAGE_CFLAGS@
+
+hydra_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+hydra_tests_LDADD = \
+ $(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/libhydra/tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libhydra/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
+
+hydra_tests$(EXEEXT): $(hydra_tests_OBJECTS) $(hydra_tests_DEPENDENCIES) $(EXTRA_hydra_tests_DEPENDENCIES)
+ @rm -f hydra_tests$(EXEEXT)
+ $(AM_V_CCLD)$(hydra_tests_LINK) $(hydra_tests_OBJECTS) $(hydra_tests_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hydra_tests-hydra_tests.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 $@ $<
+
+hydra_tests-hydra_tests.o: hydra_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hydra_tests_CFLAGS) $(CFLAGS) -MT hydra_tests-hydra_tests.o -MD -MP -MF $(DEPDIR)/hydra_tests-hydra_tests.Tpo -c -o hydra_tests-hydra_tests.o `test -f 'hydra_tests.c' || echo '$(srcdir)/'`hydra_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hydra_tests-hydra_tests.Tpo $(DEPDIR)/hydra_tests-hydra_tests.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hydra_tests.c' object='hydra_tests-hydra_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) $(hydra_tests_CFLAGS) $(CFLAGS) -c -o hydra_tests-hydra_tests.o `test -f 'hydra_tests.c' || echo '$(srcdir)/'`hydra_tests.c
+
+hydra_tests-hydra_tests.obj: hydra_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hydra_tests_CFLAGS) $(CFLAGS) -MT hydra_tests-hydra_tests.obj -MD -MP -MF $(DEPDIR)/hydra_tests-hydra_tests.Tpo -c -o hydra_tests-hydra_tests.obj `if test -f 'hydra_tests.c'; then $(CYGPATH_W) 'hydra_tests.c'; else $(CYGPATH_W) '$(srcdir)/hydra_tests.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hydra_tests-hydra_tests.Tpo $(DEPDIR)/hydra_tests-hydra_tests.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hydra_tests.c' object='hydra_tests-hydra_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) $(hydra_tests_CFLAGS) $(CFLAGS) -c -o hydra_tests-hydra_tests.obj `if test -f 'hydra_tests.c'; then $(CYGPATH_W) 'hydra_tests.c'; else $(CYGPATH_W) '$(srcdir)/hydra_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)
+
+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)
+ -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)
+ -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/libhydra/tests/hydra_tests.c b/src/libhydra/tests/hydra_tests.c
new file mode 100644
index 000000000..90abd8369
--- /dev/null
+++ b/src/libhydra/tests/hydra_tests.c
@@ -0,0 +1,53 @@
+/*
+ * 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_runner.h>
+#include <hydra.h>
+
+/* declare test suite constructors */
+#define TEST_SUITE(x) test_suite_t* x();
+#define TEST_SUITE_DEPEND(x, ...) TEST_SUITE(x)
+#include "hydra_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 "hydra_tests.h"
+ { .suite = NULL, }
+};
+
+static bool test_runner_init(bool init)
+{
+ if (init)
+ {
+ libhydra_init();
+ }
+ else
+ {
+ lib->processor->set_threads(lib->processor, 0);
+ lib->processor->cancel(lib->processor);
+ libhydra_deinit();
+ }
+ return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_runner_run("libhydra", tests, test_runner_init);
+}
diff --git a/src/libhydra/tests/hydra_tests.h b/src/libhydra/tests/hydra_tests.h
new file mode 100644
index 000000000..6b213d026
--- /dev/null
+++ b/src/libhydra/tests/hydra_tests.h
@@ -0,0 +1,14 @@
+/*
+ * 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.
+ */
diff --git a/src/libimcv/Makefile.am b/src/libimcv/Makefile.am
index d9a5cd50d..a61382723 100644
--- a/src/libimcv/Makefile.am
+++ b/src/libimcv/Makefile.am
@@ -127,7 +127,8 @@ imv_policy_manager_SOURCES = \
imv/imv_policy_manager.c \
imv/imv_policy_manager_usage.h imv/imv_policy_manager_usage.c
imv_policy_manager_LDADD = \
- $(top_builddir)/src/libstrongswan/libstrongswan.la
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libtncif/libtncif.la
#imv/imv_policy_manager.o : $(top_builddir)/config.status
SUBDIRS = .
diff --git a/src/libimcv/Makefile.in b/src/libimcv/Makefile.in
index 239e62a17..03778a22c 100644
--- a/src/libimcv/Makefile.in
+++ b/src/libimcv/Makefile.in
@@ -237,7 +237,8 @@ am_imv_policy_manager_OBJECTS = imv/imv_policy_manager.$(OBJEXT) \
imv/imv_policy_manager_usage.$(OBJEXT)
imv_policy_manager_OBJECTS = $(am_imv_policy_manager_OBJECTS)
imv_policy_manager_DEPENDENCIES = \
- $(top_builddir)/src/libstrongswan/libstrongswan.la
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libtncif/libtncif.la
SCRIPTS = $(ipsec_SCRIPTS)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -395,6 +396,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@
@@ -455,10 +457,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@
@@ -532,6 +536,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@
@@ -708,7 +714,8 @@ imv_policy_manager_SOURCES = \
imv/imv_policy_manager_usage.h imv/imv_policy_manager_usage.c
imv_policy_manager_LDADD = \
- $(top_builddir)/src/libstrongswan/libstrongswan.la
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libtncif/libtncif.la
#imv/imv_policy_manager.o : $(top_builddir)/config.status
SUBDIRS = . $(am__append_3) $(am__append_4) $(am__append_5) \
diff --git a/src/libimcv/imv/data.sql b/src/libimcv/imv/data.sql
index 425748f59..ff6191117 100644
--- a/src/libimcv/imv/data.sql
+++ b/src/libimcv/imv/data.sql
@@ -323,6 +323,71 @@ INSERT INTO products ( /* 54 */
'Debian 7.6 armv6l'
);
+INSERT INTO products ( /* 55 */
+ name
+) VALUES (
+ 'Debian 7.7 i686'
+);
+
+INSERT INTO products ( /* 56 */
+ name
+) VALUES (
+ 'Debian 7.7 x86_64'
+);
+INSERT INTO products ( /* 57 */
+ name
+) VALUES (
+ 'Debian 7.7 armv6l'
+);
+
+INSERT INTO products ( /* 58 */
+ name
+) VALUES (
+ 'Debian 7.8 i686'
+);
+
+INSERT INTO products ( /* 59 */
+ name
+) VALUES (
+ 'Debian 7.8 x86_64'
+);
+
+INSERT INTO products ( /* 60 */
+ name
+) VALUES (
+ 'Debian 7.8 armv6l'
+);
+
+INSERT INTO products ( /* 61 */
+ name
+) VALUES (
+ 'Ubuntu 14.10 i686'
+);
+
+INSERT INTO products ( /* 62 */
+ name
+) VALUES (
+ 'Ubuntu 14.10 x86_64'
+);
+
+INSERT INTO products ( /* 63 */
+ name
+) VALUES (
+ 'Android 5.0'
+);
+
+INSERT INTO products ( /* 64 */
+ name
+) VALUES (
+ 'Android 5.0.1'
+);
+
+INSERT INTO products ( /* 65 */
+ name
+) VALUES (
+ 'Debian 7.8 armv7l'
+);
+
/* Directories */
INSERT INTO directories ( /* 1 */
@@ -741,6 +806,18 @@ INSERT INTO groups ( /* 14 */
'Debian armv6l', 2
);
+INSERT INTO groups ( /* 15 */
+ name, parent
+) VALUES (
+ 'Debian armv7l', 2
+);
+
+INSERT INTO groups ( /* 16 */
+ name
+) VALUES (
+ 'TPM TBOOT'
+);
+
/* Default Product Groups */
INSERT INTO groups_product_defaults (
@@ -800,6 +877,18 @@ INSERT INTO groups_product_defaults (
INSERT INTO groups_product_defaults (
group_id, product_id
) VALUES (
+ 4, 55
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
+ 4, 58
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
5, 2
);
@@ -854,6 +943,18 @@ INSERT INTO groups_product_defaults (
INSERT INTO groups_product_defaults (
group_id, product_id
) VALUES (
+ 5, 56
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
+ 5, 59
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
6, 9
);
@@ -902,6 +1003,12 @@ INSERT INTO groups_product_defaults (
INSERT INTO groups_product_defaults (
group_id, product_id
) VALUES (
+ 6, 61
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
7, 8
);
@@ -956,6 +1063,12 @@ INSERT INTO groups_product_defaults (
INSERT INTO groups_product_defaults (
group_id, product_id
) VALUES (
+ 7, 62
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
3, 21
);
@@ -1016,6 +1129,18 @@ INSERT INTO groups_product_defaults (
INSERT INTO groups_product_defaults (
group_id, product_id
) VALUES (
+ 3, 63
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
+ 3, 64
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
3, 51
);
@@ -1061,6 +1186,24 @@ INSERT INTO groups_product_defaults (
14, 54
);
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
+ 14, 57
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
+ 14, 60
+);
+
+INSERT INTO groups_product_defaults (
+ group_id, product_id
+) VALUES (
+ 15, 65
+);
+
/* Policies */
INSERT INTO policies ( /* 1 */
@@ -1189,6 +1332,12 @@ INSERT INTO policies ( /* 21 */
16, 'TPM BIOS/IMA Measurements', 'BI', 2, 2
);
+INSERT INTO policies ( /* 22 */
+ type, name, argument, rec_fail, rec_noresult
+) VALUES (
+ 16, 'TPM TBOOT Measurements', 'T', 2, 2
+);
+
/* Enforcements */
INSERT INTO enforcements ( /* 1 */
@@ -1293,6 +1442,12 @@ INSERT INTO enforcements ( /* 17 */
21, 13, 60
);
+INSERT INTO enforcements ( /* 18 */
+ policy, group_id, max_age
+) VALUES (
+ 22, 16, 60
+);
+
/* swid_entities */
INSERT INTO "swid_entities" ( /* 1 */
diff --git a/src/libimcv/imv/imv_agent.c b/src/libimcv/imv/imv_agent.c
index 6b24f4b28..d0508624d 100644
--- a/src/libimcv/imv/imv_agent.c
+++ b/src/libimcv/imv/imv_agent.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -412,14 +412,10 @@ METHOD(imv_agent_t, create_state, TNC_Result,
{
TNC_ConnectionID conn_id;
char *tnccs_p = NULL, *tnccs_v = NULL, *t_p = NULL, *t_v = NULL;
- bool has_long = FALSE, has_excl = FALSE, has_soh = FALSE, first = TRUE;
+ bool has_long = FALSE, has_excl = FALSE, has_soh = FALSE;
linked_list_t *ar_identities;
- enumerator_t *enumerator;
- tncif_identity_t *tnc_id;
imv_session_t *session;
uint32_t max_msg_len;
- uint32_t ar_id_type = TNC_ID_UNKNOWN;
- chunk_t ar_id_value = chunk_empty;
conn_id = state->get_connection_id(state);
if (find_connection(this, conn_id))
@@ -431,15 +427,24 @@ METHOD(imv_agent_t, create_state, TNC_Result,
}
/* Get and display attributes from TNCS via IF-IMV */
- has_long = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_LONG_TYPES);
- has_excl = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_EXCLUSIVE);
- has_soh = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_SOH);
- tnccs_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL);
- tnccs_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_VERSION);
- t_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_PROTOCOL);
- t_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_VERSION);
- max_msg_len = get_uint_attribute(this, conn_id, TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE);
- ar_identities = get_identity_attribute(this, conn_id, TNC_ATTRIBUTEID_AR_IDENTITIES);
+ has_long = get_bool_attribute(this, conn_id,
+ TNC_ATTRIBUTEID_HAS_LONG_TYPES);
+ has_excl = get_bool_attribute(this, conn_id,
+ TNC_ATTRIBUTEID_HAS_EXCLUSIVE);
+ has_soh = get_bool_attribute(this, conn_id,
+ TNC_ATTRIBUTEID_HAS_SOH);
+ tnccs_p = get_str_attribute(this, conn_id,
+ TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL);
+ tnccs_v = get_str_attribute(this, conn_id,
+ TNC_ATTRIBUTEID_IFTNCCS_VERSION);
+ t_p = get_str_attribute(this, conn_id,
+ TNC_ATTRIBUTEID_IFT_PROTOCOL);
+ t_v = get_str_attribute(this, conn_id,
+ TNC_ATTRIBUTEID_IFT_VERSION);
+ max_msg_len = get_uint_attribute(this, conn_id,
+ TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE);
+ ar_identities = get_identity_attribute(this, conn_id,
+ TNC_ATTRIBUTEID_AR_IDENTITIES);
state->set_flags(state, has_long, has_excl);
state->set_max_msg_len(state, max_msg_len);
@@ -451,48 +456,9 @@ METHOD(imv_agent_t, create_state, TNC_Result,
DBG2(DBG_IMV, " over %s %s with maximum PA-TNC message size of %u bytes",
t_p ? t_p:"?", t_v ? t_v :"?", max_msg_len);
- enumerator = ar_identities->create_enumerator(ar_identities);
- while (enumerator->enumerate(enumerator, &tnc_id))
- {
- pen_type_t id_type, subject_type, auth_type;
- uint32_t tcg_id_type, tcg_subject_type, tcg_auth_type;
- chunk_t id_value;
-
- id_type = tnc_id->get_identity_type(tnc_id);
- id_value = tnc_id->get_identity_value(tnc_id);
- subject_type = tnc_id->get_subject_type(tnc_id);
- auth_type = tnc_id->get_auth_type(tnc_id);
-
- tcg_id_type = (id_type.vendor_id == PEN_TCG) ?
- id_type.type : TNC_ID_UNKNOWN;
- tcg_subject_type = (subject_type.vendor_id == PEN_TCG) ?
- subject_type.type : TNC_SUBJECT_UNKNOWN;
- tcg_auth_type = (auth_type.vendor_id == PEN_TCG) ?
- auth_type.type : TNC_AUTH_UNKNOWN;
-
-
- DBG2(DBG_IMV, " %N AR identity '%.*s' authenticated by %N",
- TNC_Subject_names, tcg_subject_type,
- id_value.len, id_value.ptr,
- TNC_Authentication_names, tcg_auth_type);
-
- /* keep the first access requestor ID */
- if (first)
- {
- ar_id_type = tcg_id_type;
- ar_id_value = id_value;
- first = FALSE;
- }
- }
- enumerator->destroy(enumerator);
-
- session = imcv_sessions->add_session(imcv_sessions, conn_id,
- ar_id_type, ar_id_value);
+ session = imcv_sessions->add_session(imcv_sessions, conn_id, ar_identities);
state->set_session(state, session);
- /* clean up temporary variables */
- ar_identities->destroy_offset(ar_identities,
- offsetof(tncif_identity_t, destroy));
free(tnccs_p);
free(tnccs_v);
free(t_p);
diff --git a/src/libimcv/imv/imv_database.c b/src/libimcv/imv/imv_database.c
index 0c4bb7514..0a18cd71b 100644
--- a/src/libimcv/imv/imv_database.c
+++ b/src/libimcv/imv/imv_database.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2013-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -22,6 +22,8 @@
#include "imv_database.h"
+#include <tncif_identity.h>
+
#include <utils/debug.h>
#include <threading/mutex.h>
@@ -60,41 +62,14 @@ METHOD(imv_database_t, get_database, database_t*,
*/
static bool create_session(private_imv_database_t *this, imv_session_t *session)
{
- enumerator_t *e;
+ enumerator_t *enumerator, *e;
imv_os_info_t *os_info;
- chunk_t device_id, ar_id_value;
+ chunk_t device_id;
+ tncif_identity_t *tnc_id;
TNC_ConnectionID conn_id;
- uint32_t ar_id_type;
char *product, *device;
- int session_id = 0, ar_id = 0, pid = 0, did = 0, trusted = 0, created;
-
- ar_id_value = session->get_ar_id(session, &ar_id_type);
- if (ar_id_value.len)
- {
- /* get primary key of AR identity if it exists */
- e = this->db->query(this->db,
- "SELECT id FROM identities WHERE type = ? AND value = ?",
- DB_INT, ar_id_type, DB_BLOB, ar_id_value, DB_INT);
- if (e)
- {
- e->enumerate(e, &ar_id);
- e->destroy(e);
- }
-
- /* if AR identity has not been found - register it */
- if (!ar_id)
- {
- this->db->execute(this->db, &ar_id,
- "INSERT INTO identities (type, value) VALUES (?, ?)",
- DB_INT, ar_id_type, DB_BLOB, ar_id_value);
- }
-
- if (!ar_id)
- {
- DBG1(DBG_IMV, "imv_db: registering access requestor failed");
- return FALSE;
- }
- }
+ int session_id = 0, pid = 0, did = 0, trusted = 0, created;
+ bool first = TRUE, success = TRUE;
/* get product info string */
os_info = session->get_os_info(session);
@@ -170,10 +145,9 @@ static bool create_session(private_imv_database_t *this, imv_session_t *session)
created = session->get_creation_time(session);
conn_id = session->get_connection_id(session);
this->db->execute(this->db, &session_id,
- "INSERT INTO sessions (time, connection, identity, product, device) "
- "VALUES (?, ?, ?, ?, ?)",
- DB_INT, created, DB_INT, conn_id, DB_INT, ar_id,
- DB_INT, pid, DB_INT, did);
+ "INSERT INTO sessions (time, connection, product, device) "
+ "VALUES (?, ?, ?, ?)",
+ DB_INT, created, DB_INT, conn_id, DB_INT, pid, DB_INT, did);
if (session_id)
{
@@ -187,7 +161,68 @@ static bool create_session(private_imv_database_t *this, imv_session_t *session)
}
session->set_session_id(session, session_id, pid, did);
- return TRUE;
+ enumerator = session->create_ar_identities_enumerator(session);
+ while (enumerator->enumerate(enumerator, &tnc_id))
+ {
+ pen_type_t ar_id_type;
+ chunk_t ar_id_value;
+ int ar_id = 0, si_id = 0;
+
+ ar_id_type = tnc_id->get_identity_type(tnc_id);
+ ar_id_value = tnc_id->get_identity_value(tnc_id);
+
+ if (ar_id_type.vendor_id != PEN_TCG || ar_id_value.len == 0)
+ {
+ continue;
+ }
+
+ /* get primary key of AR identity if it exists */
+ e = this->db->query(this->db,
+ "SELECT id FROM identities WHERE type = ? AND value = ?",
+ DB_INT, ar_id_type.type, DB_BLOB, ar_id_value, DB_INT);
+ if (e)
+ {
+ e->enumerate(e, &ar_id);
+ e->destroy(e);
+ }
+
+ /* if AR identity has not been found - register it */
+ if (!ar_id)
+ {
+ this->db->execute(this->db, &ar_id,
+ "INSERT INTO identities (type, value) VALUES (?, ?)",
+ DB_INT, ar_id_type.type, DB_BLOB, ar_id_value);
+ }
+ if (!ar_id)
+ {
+ DBG1(DBG_IMV, "imv_db: registering access requestor failed");
+ success = FALSE;
+ break;
+ }
+
+ this->db->execute(this->db, &si_id,
+ "INSERT INTO sessions_identities (session_id, identity_id) "
+ "VALUES (?, ?)",
+ DB_INT, session_id, DB_INT, ar_id);
+
+ if (!si_id)
+ {
+ DBG1(DBG_IMV, "imv_db: assigning identity to session failed");
+ success = FALSE;
+ break;
+ }
+
+ if (first)
+ {
+ this->db->execute(this->db, NULL,
+ "UPDATE sessions SET identity = ? WHERE id = ?",
+ DB_INT, ar_id, DB_INT, session_id);
+ first = FALSE;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return success;
}
static bool add_workitems(private_imv_database_t *this, imv_session_t *session)
diff --git a/src/libimcv/imv/imv_policy_manager.c b/src/libimcv/imv/imv_policy_manager.c
index 50f7f2e39..9f7e4e8f4 100644
--- a/src/libimcv/imv/imv_policy_manager.c
+++ b/src/libimcv/imv/imv_policy_manager.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -19,6 +19,8 @@
#include <library.h>
#include <utils/debug.h>
+#include <tncif_names.h>
+
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
@@ -251,9 +253,12 @@ static bool policy_start(database_t *db, int session_id)
static bool policy_stop(database_t *db, int session_id)
{
enumerator_t *e;
- int rec, policy;
- char *result;
+ int rec, policy, final_rec, id_type;
+ chunk_t id_value;
+ char *result, *ip_address = NULL;
+ bool success = TRUE;
+ /* store all workitem results for this session in the results table */
e = db->query(db,
"SELECT w.rec_final, w.result, e.policy FROM workitems AS w "
"JOIN enforcements AS e ON w.enforcement = e.id "
@@ -270,9 +275,68 @@ static bool policy_stop(database_t *db, int session_id)
}
e->destroy(e);
}
- return db->execute(db, NULL,
- "DELETE FROM workitems WHERE session = ?",
- DB_UINT, session_id) >= 0;
+ else
+ {
+ success = FALSE;
+ }
+
+ /* delete all workitems for this session from the database */
+ if (db->execute(db, NULL,
+ "DELETE FROM workitems WHERE session = ?",
+ DB_UINT, session_id) < 0)
+ {
+ success = FALSE;
+ }
+
+ final_rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION;
+
+ /* retrieve the final recommendation for this session */
+ e = db->query(db,
+ "SELECT rec FROM sessions WHERE id = ?",
+ DB_INT, session_id, DB_INT);
+ if (e)
+ {
+ if (!e->enumerate(e, &final_rec))
+ {
+ success = FALSE;
+ }
+ e->destroy(e);
+ }
+ else
+ {
+ success = FALSE;
+ }
+
+ /* retrieve client IP address for this session */
+ e = db->query(db,
+ "SELECT i.type, i.value FROM identities AS i "
+ "JOIN sessions_identities AS si ON si.identity_id = i.id "
+ "WHERE si.session_id = ? AND (i.type = ? OR i.type = ?)",
+ DB_INT, session_id, DB_INT, TNC_ID_IPV4_ADDR, DB_INT,
+ TNC_ID_IPV6_ADDR, DB_INT, DB_BLOB);
+ if (e)
+ {
+ if (e->enumerate(e, &id_type, &id_value))
+ {
+ ip_address = strndup(id_value.ptr, id_value.len);
+ }
+ else
+ {
+ success = FALSE;
+ }
+ e->destroy(e);
+ }
+ else
+ {
+ success = FALSE;
+ }
+
+ fprintf(stderr, "recommendation for access requestor %s is %N\n",
+ ip_address ? ip_address : "0.0.0.0",
+ TNC_IMV_Action_Recommendation_names, final_rec);
+ free(ip_address);
+
+ return success;
}
int main(int argc, char *argv[])
diff --git a/src/libimcv/imv/imv_session.c b/src/libimcv/imv/imv_session.c
index 1f0d8cf14..bc6b5a8d1 100644
--- a/src/libimcv/imv/imv_session.c
+++ b/src/libimcv/imv/imv_session.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,6 +15,8 @@
#include "imv_session.h"
+#include <tncif_identity.h>
+
#include <utils/debug.h>
typedef struct private_imv_session_t private_imv_session_t;
@@ -55,14 +57,9 @@ struct private_imv_session_t {
time_t created;
/**
- * Access Requestor ID type
- */
- uint32_t ar_id_type;
-
- /**
- * Access Requestor ID value
+ * List of Access Requestor identities
*/
- chunk_t ar_id_value;
+ linked_list_t *ar_identities;
/**
* OS information
@@ -130,14 +127,10 @@ METHOD(imv_session_t, get_creation_time, time_t,
return this->created;
}
-METHOD(imv_session_t, get_ar_id, chunk_t,
- private_imv_session_t *this, uint32_t *ar_id_type)
+METHOD(imv_session_t, create_ar_identities_enumerator, enumerator_t*,
+ private_imv_session_t *this)
{
- if (ar_id_type)
- {
- *ar_id_type = this->ar_id_type;
- }
- return this->ar_id_value;
+ return this->ar_identities->create_enumerator(this->ar_identities);
}
METHOD(imv_session_t, get_os_info, imv_os_info_t*,
@@ -256,7 +249,8 @@ METHOD(imv_session_t, destroy, void,
this->workitems->destroy_offset(this->workitems,
offsetof(imv_workitem_t, destroy));
this->os_info->destroy(this->os_info);
- free(this->ar_id_value.ptr);
+ this->ar_identities->destroy_offset(this->ar_identities,
+ offsetof(tncif_identity_t, destroy));
free(this->device_id.ptr);
free(this);
}
@@ -266,7 +260,7 @@ METHOD(imv_session_t, destroy, void,
* See header
*/
imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created,
- uint32_t ar_id_type, chunk_t ar_id_value)
+ linked_list_t *ar_identities)
{
private_imv_session_t *this;
@@ -276,7 +270,7 @@ imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created,
.get_session_id = _get_session_id,
.get_connection_id = _get_connection_id,
.get_creation_time = _get_creation_time,
- .get_ar_id = _get_ar_id,
+ .create_ar_identities_enumerator = _create_ar_identities_enumerator,
.get_os_info = _get_os_info,
.set_device_id = _set_device_id,
.get_device_id = _get_device_id,
@@ -293,8 +287,7 @@ imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created,
},
.conn_id = conn_id,
.created = created,
- .ar_id_type = ar_id_type,
- .ar_id_value = chunk_clone(ar_id_value),
+ .ar_identities = ar_identities,
.os_info = imv_os_info_create(),
.workitems = linked_list_create(),
.ref = 1,
diff --git a/src/libimcv/imv/imv_session.h b/src/libimcv/imv/imv_session.h
index 42b9118a6..107716f30 100644
--- a/src/libimcv/imv/imv_session.h
+++ b/src/libimcv/imv/imv_session.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2013-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -70,12 +70,11 @@ struct imv_session_t {
time_t (*get_creation_time)(imv_session_t *this);
/**
- * Get Access Requestor ID
+ * Get list of Access Requestor identities
*
- * @param id_type Access Requestor TCG Standard ID Type
- * @return Access Requestor TCG Standard ID Value
+ * @return List of Access Requestor identities
*/
- chunk_t (*get_ar_id)(imv_session_t *this, uint32_t *id_type);
+ enumerator_t* (*create_ar_identities_enumerator)(imv_session_t *this);
/**
* Get OS Information
@@ -172,10 +171,9 @@ struct imv_session_t {
*
* @param id Associated Connection ID
* @param created Session creation time
- * @param ar_id_type Access Requestor ID type
- * @param ar_id_value Access Requestor ID value
+ * @param ar_identities List of Access Requestor identities
*/
imv_session_t* imv_session_create(TNC_ConnectionID id, time_t created,
- uint32_t ar_id_type, chunk_t ar_id_value);
+ linked_list_t *ar_identities);
#endif /** IMV_SESSION_H_ @}*/
diff --git a/src/libimcv/imv/imv_session_manager.c b/src/libimcv/imv/imv_session_manager.c
index 0fb8de45e..c97602998 100644
--- a/src/libimcv/imv/imv_session_manager.c
+++ b/src/libimcv/imv/imv_session_manager.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2014-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,6 +15,9 @@
#include "imv_session_manager.h"
+#include <tncif_names.h>
+#include <tncif_identity.h>
+
#include <threading/mutex.h>
typedef struct private_imv_session_manager_t private_imv_session_manager_t;
@@ -43,9 +46,10 @@ struct private_imv_session_manager_t {
METHOD(imv_session_manager_t, add_session, imv_session_t*,
private_imv_session_manager_t *this, TNC_ConnectionID conn_id,
- uint32_t ar_id_type, chunk_t ar_id_value)
+ linked_list_t *ar_identities)
{
enumerator_t *enumerator;
+ tncif_identity_t *tnc_id;
imv_session_t *current, *session = NULL;
time_t created;
@@ -66,13 +70,43 @@ METHOD(imv_session_manager_t, add_session, imv_session_t*,
/* session already exists */
if (session)
{
+ ar_identities->destroy_offset(ar_identities,
+ offsetof(tncif_identity_t, destroy));
this->mutex->unlock(this->mutex);
return session->get_ref(session);
}
+ /* Output list of Access Requestor identities */
+ enumerator = ar_identities->create_enumerator(ar_identities);
+ while (enumerator->enumerate(enumerator, &tnc_id))
+ {
+ pen_type_t id_type, subject_type, auth_type;
+ uint32_t tcg_id_type, tcg_subject_type, tcg_auth_type;
+ chunk_t id_value;
+
+ id_type = tnc_id->get_identity_type(tnc_id);
+ id_value = tnc_id->get_identity_value(tnc_id);
+ subject_type = tnc_id->get_subject_type(tnc_id);
+ auth_type = tnc_id->get_auth_type(tnc_id);
+
+ tcg_id_type = (subject_type.vendor_id == PEN_TCG) ?
+ id_type.type : TNC_SUBJECT_UNKNOWN;
+ tcg_subject_type = (subject_type.vendor_id == PEN_TCG) ?
+ subject_type.type : TNC_SUBJECT_UNKNOWN;
+ tcg_auth_type = (auth_type.vendor_id == PEN_TCG) ?
+ auth_type.type : TNC_AUTH_UNKNOWN;
+
+ DBG2(DBG_IMV, " %N AR identity '%.*s' of type %N authenticated by %N",
+ TNC_Subject_names, tcg_subject_type,
+ id_value.len, id_value.ptr,
+ TNC_Identity_names, tcg_id_type,
+ TNC_Authentication_names, tcg_auth_type);
+ }
+ enumerator->destroy(enumerator);
+
/* create a new session entry */
created = time(NULL);
- session = imv_session_create(conn_id, created, ar_id_type, ar_id_value);
+ session = imv_session_create(conn_id, created, ar_identities);
this->sessions->insert_last(this->sessions, session);
this->mutex->unlock(this->mutex);
diff --git a/src/libimcv/imv/imv_session_manager.h b/src/libimcv/imv/imv_session_manager.h
index 8a733accb..cfae23bc9 100644
--- a/src/libimcv/imv/imv_session_manager.h
+++ b/src/libimcv/imv/imv_session_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2014-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -39,13 +39,12 @@ struct imv_session_manager_t {
* Create or get a session associated with a TNCCS connection
*
* @param conn_id TNCCS Connection ID
- * @param ar_id_type Access Requestor identity type
- * @param ar_id_value Access Requestor identity value
+ * @param ar_identities List of Access Requestor identities
* @return Session associated with TNCCS Connection
*/
imv_session_t* (*add_session)(imv_session_manager_t *this,
TNC_ConnectionID conn_id,
- uint32_t ar_id_type, chunk_t ar_id_value);
+ linked_list_t *ar_identities);
/**
* Remove a session
diff --git a/src/libimcv/imv/tables-mysql.sql b/src/libimcv/imv/tables-mysql.sql
index 47ee41c86..cf50742c3 100644
--- a/src/libimcv/imv/tables-mysql.sql
+++ b/src/libimcv/imv/tables-mysql.sql
@@ -99,6 +99,14 @@ CREATE TABLE `sessions` (
`rec` INTEGER DEFAULT 3
);
+DROP TABLE IF EXISTS `sessions_identities`;
+CREATE TABLE `sessions_identities` (
+ `id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ `session_id` INTEGER NOT NULL REFERENCES `sessions`(`id`),
+ `identity_id` INTEGER NOT NULL REFERENCES `identities`(`id`),
+ UNIQUE (`session_id`, `identity_id`)
+);
+
DROP TABLE IF EXISTS `workitems`;
CREATE TABLE `workitems` (
`id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
diff --git a/src/libimcv/imv/tables.sql b/src/libimcv/imv/tables.sql
index f7324896e..5c2a6563b 100644
--- a/src/libimcv/imv/tables.sql
+++ b/src/libimcv/imv/tables.sql
@@ -104,6 +104,14 @@ CREATE TABLE sessions (
rec INTEGER DEFAULT 3
);
+DROP TABLE IF EXISTS sessions_identities;
+CREATE TABLE sessions_identities (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ session_id INTEGER NOT NULL REFERENCES sessions(id),
+ identity_id INTEGER NOT NULL REFERENCES identities(id),
+ UNIQUE (session_id, identity_id)
+);
+
DROP TABLE IF EXISTS workitems;
CREATE TABLE workitems (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
diff --git a/src/libimcv/plugins/imc_attestation/Makefile.in b/src/libimcv/plugins/imc_attestation/Makefile.in
index 3c5017f32..8ad56181e 100644
--- a/src/libimcv/plugins/imc_attestation/Makefile.in
+++ b/src/libimcv/plugins/imc_attestation/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/libimcv/plugins/imc_attestation/imc_attestation_process.c b/src/libimcv/plugins/imc_attestation/imc_attestation_process.c
index 2fc2998e1..f24aec881 100644
--- a/src/libimcv/plugins/imc_attestation/imc_attestation_process.c
+++ b/src/libimcv/plugins/imc_attestation/imc_attestation_process.c
@@ -137,7 +137,11 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg,
{
return FALSE;
}
- pts->get_my_public_value(pts, &responder_value, &responder_nonce);
+ if (!pts->get_my_public_value(pts, &responder_value,
+ &responder_nonce))
+ {
+ return FALSE;
+ }
/* Send DH Nonce Parameters Response attribute */
attr = tcg_pts_attr_dh_nonce_params_resp_create(selected_dh_group,
@@ -174,8 +178,10 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg,
return FALSE;
}
- pts->set_peer_public_value(pts, initiator_value, initiator_nonce);
- if (!pts->calculate_secret(pts))
+
+ if (!pts->set_peer_public_value(pts, initiator_value,
+ initiator_nonce) ||
+ !pts->calculate_secret(pts))
{
return FALSE;
}
diff --git a/src/libimcv/plugins/imc_os/Makefile.in b/src/libimcv/plugins/imc_os/Makefile.in
index 3f4cf41a9..3b7538688 100644
--- a/src/libimcv/plugins/imc_os/Makefile.in
+++ b/src/libimcv/plugins/imc_os/Makefile.in
@@ -224,6 +224,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@
@@ -284,10 +285,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@
@@ -361,6 +364,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/libimcv/plugins/imc_scanner/Makefile.in b/src/libimcv/plugins/imc_scanner/Makefile.in
index a192b0a41..7b696896f 100644
--- a/src/libimcv/plugins/imc_scanner/Makefile.in
+++ b/src/libimcv/plugins/imc_scanner/Makefile.in
@@ -225,6 +225,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@
@@ -285,10 +286,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@
@@ -362,6 +365,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/libimcv/plugins/imc_swid/Makefile.in b/src/libimcv/plugins/imc_swid/Makefile.in
index f1859a2cb..2847f09b4 100644
--- a/src/libimcv/plugins/imc_swid/Makefile.in
+++ b/src/libimcv/plugins/imc_swid/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/libimcv/plugins/imc_test/Makefile.in b/src/libimcv/plugins/imc_test/Makefile.in
index 3e1d0232f..2048caa4d 100644
--- a/src/libimcv/plugins/imc_test/Makefile.in
+++ b/src/libimcv/plugins/imc_test/Makefile.in
@@ -224,6 +224,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@
@@ -284,10 +285,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@
@@ -361,6 +364,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/libimcv/plugins/imv_attestation/Makefile.in b/src/libimcv/plugins/imv_attestation/Makefile.in
index 3ba7c8c88..09a0ab0ce 100644
--- a/src/libimcv/plugins/imv_attestation/Makefile.in
+++ b/src/libimcv/plugins/imv_attestation/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/libimcv/plugins/imv_attestation/attest_db.c b/src/libimcv/plugins/imv_attestation/attest_db.c
index f85a02b3d..f1a1f923e 100644
--- a/src/libimcv/plugins/imv_attestation/attest_db.c
+++ b/src/libimcv/plugins/imv_attestation/attest_db.c
@@ -849,29 +849,31 @@ METHOD(attest_db_t, list_devices, void,
{
enumerator_t *e, *e_ar;
chunk_t ar_id_value = chunk_empty;
- char *product, *device;
+ char *product, *device, *description;
time_t timestamp;
- int id, last_id = 0, ar_id = 0, last_ar_id = 0, device_count = 0;
+ int id, last_id = 0, ar_id = 0, last_ar_id = 0, device_count = 0, trusted;
int session_id, rec;
u_int32_t ar_id_type;
u_int tstamp;
e = this->db->query(this->db,
- "SELECT d.id, d.value, s.id, s.time, s.identity, s.rec, p.name "
+ "SELECT d.id, d.value, d.trusted, d.description, "
+ "s.id, s.time, s.identity, s.rec, p.name "
"FROM devices AS d "
"JOIN sessions AS s ON d.id = s.device "
"JOIN products AS p ON p.id = s.product "
- "ORDER BY d.value, s.time DESC", DB_INT, DB_TEXT, DB_INT, DB_UINT,
- DB_INT, DB_INT, DB_TEXT);
+ "ORDER BY d.value, s.time DESC", DB_INT, DB_TEXT, DB_INT, DB_TEXT,
+ DB_INT, DB_UINT, DB_INT, DB_INT, DB_TEXT);
if (e)
{
- while (e->enumerate(e, &id, &device, &session_id, &tstamp, &ar_id, &rec,
- &product))
+ while (e->enumerate(e, &id, &device, &trusted, &description,
+ &session_id, &tstamp, &ar_id, &rec, &product))
{
if (id != last_id)
{
- printf("%4d: %s - %s\n", id, device, product);
+ printf("%4d: %s %s - %s - %s\n", id, trusted ? "+" : "-",
+ device, product, description);
device_count++;
last_id = id;
}
diff --git a/src/libimcv/plugins/imv_attestation/build-database.sh b/src/libimcv/plugins/imv_attestation/build-database.sh
index ca2939b49..0babb5366 100755
--- a/src/libimcv/plugins/imv_attestation/build-database.sh
+++ b/src/libimcv/plugins/imv_attestation/build-database.sh
@@ -2,7 +2,7 @@
p="Ubuntu 14.04 x86_64"
a="x86_64-linux-gnu"
-k="3.13.0-37-generic"
+k="3.13.0-46-generic"
for hash in sha1 sha256
do
diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_build.c b/src/libimcv/plugins/imv_attestation/imv_attestation_build.c
index c39fe8d47..db93ac45f 100644
--- a/src/libimcv/plugins/imv_attestation/imv_attestation_build.c
+++ b/src/libimcv/plugins/imv_attestation/imv_attestation_build.c
@@ -69,7 +69,11 @@ bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
/* Send DH nonce finish attribute */
selected_algorithm = pts->get_meas_algorithm(pts);
- pts->get_my_public_value(pts, &initiator_value, &initiator_nonce);
+ if (!pts->get_my_public_value(pts, &initiator_value,
+ &initiator_nonce))
+ {
+ return FALSE;
+ }
attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm,
initiator_value, initiator_nonce);
attr->set_noskip_flag(attr, TRUE);
diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_process.c b/src/libimcv/plugins/imv_attestation/imv_attestation_process.c
index 89a1f02cf..fbeb6618e 100644
--- a/src/libimcv/plugins/imv_attestation/imv_attestation_process.c
+++ b/src/libimcv/plugins/imv_attestation/imv_attestation_process.c
@@ -134,11 +134,11 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
}
responder_value = attr_cast->get_responder_value(attr_cast);
- pts->set_peer_public_value(pts, responder_value,
- responder_nonce);
/* Calculate secret assessment value */
- if (!pts->calculate_secret(pts))
+ if (!pts->set_peer_public_value(pts, responder_value,
+ responder_nonce) ||
+ !pts->calculate_secret(pts))
{
return FALSE;
}
@@ -198,7 +198,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
e = pts_credmgr->create_trusted_enumerator(pts_credmgr,
KEY_ANY, aik->get_issuer(aik), FALSE);
- while (e->enumerate(e, &issuer))
+ while (e->enumerate(e, &issuer, NULL))
{
if (aik->issued_by(aik, issuer, NULL))
{
diff --git a/src/libimcv/plugins/imv_os/Makefile.in b/src/libimcv/plugins/imv_os/Makefile.in
index 36e708fc9..ec3488992 100644
--- a/src/libimcv/plugins/imv_os/Makefile.in
+++ b/src/libimcv/plugins/imv_os/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/libimcv/plugins/imv_scanner/Makefile.in b/src/libimcv/plugins/imv_scanner/Makefile.in
index 2677b339a..08abbf596 100644
--- a/src/libimcv/plugins/imv_scanner/Makefile.in
+++ b/src/libimcv/plugins/imv_scanner/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/libimcv/plugins/imv_swid/Makefile.in b/src/libimcv/plugins/imv_swid/Makefile.in
index 815722f9c..936bee86e 100644
--- a/src/libimcv/plugins/imv_swid/Makefile.in
+++ b/src/libimcv/plugins/imv_swid/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/libimcv/plugins/imv_test/Makefile.in b/src/libimcv/plugins/imv_test/Makefile.in
index 66da75a1e..8e0e22353 100644
--- a/src/libimcv/plugins/imv_test/Makefile.in
+++ b/src/libimcv/plugins/imv_test/Makefile.in
@@ -225,6 +225,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@
@@ -285,10 +286,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@
@@ -362,6 +365,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/libimcv/pts/components/ita/ita_comp_tboot.c b/src/libimcv/pts/components/ita/ita_comp_tboot.c
index 273c18f31..ce318ec84 100644
--- a/src/libimcv/pts/components/ita/ita_comp_tboot.c
+++ b/src/libimcv/pts/components/ita/ita_comp_tboot.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -61,11 +61,6 @@ struct pts_ita_comp_tboot_t {
int cid;
/**
- * Primary key for AIK database entry
- */
- int kid;
-
- /**
* Component is registering measurements
*/
bool is_registering;
@@ -243,7 +238,7 @@ METHOD(pts_component_t, verify, status_t,
else
{
status = this->pts_db->check_comp_measurement(this->pts_db,
- measurement, this->cid, this->kid,
+ measurement, this->cid, this->aik_id,
++this->seq_no, extended_pcr, algo);
if (status != SUCCESS)
{
diff --git a/src/libimcv/pts/pts.c b/src/libimcv/pts/pts.c
index 2fff4c901..1ca72098e 100644
--- a/src/libimcv/pts/pts.c
+++ b/src/libimcv/pts/pts.c
@@ -224,17 +224,24 @@ METHOD(pts_t, create_dh_nonce, bool,
return TRUE;
}
-METHOD(pts_t, get_my_public_value, void,
+METHOD(pts_t, get_my_public_value, bool,
private_pts_t *this, chunk_t *value, chunk_t *nonce)
{
- this->dh->get_my_public_value(this->dh, value);
+ if (!this->dh->get_my_public_value(this->dh, value))
+ {
+ return FALSE;
+ }
*nonce = this->is_imc ? this->responder_nonce : this->initiator_nonce;
+ return TRUE;
}
-METHOD(pts_t, set_peer_public_value, void,
+METHOD(pts_t, set_peer_public_value, bool,
private_pts_t *this, chunk_t value, chunk_t nonce)
{
- this->dh->set_other_public_value(this->dh, value);
+ if (!this->dh->set_other_public_value(this->dh, value))
+ {
+ return FALSE;
+ }
nonce = chunk_clone(nonce);
if (this->is_imc)
@@ -245,6 +252,7 @@ METHOD(pts_t, set_peer_public_value, void,
{
this->responder_nonce = nonce;
}
+ return TRUE;
}
METHOD(pts_t, calculate_secret, bool,
@@ -264,7 +272,7 @@ METHOD(pts_t, calculate_secret, bool,
DBG3(DBG_PTS, "responder nonce: %B", &this->responder_nonce);
/* Calculate the DH secret */
- if (this->dh->get_shared_secret(this->dh, &shared_secret) != SUCCESS)
+ if (!this->dh->get_shared_secret(this->dh, &shared_secret))
{
DBG1(DBG_PTS, "shared DH secret computation failed");
return FALSE;
diff --git a/src/libimcv/pts/pts.h b/src/libimcv/pts/pts.h
index be32a3464..d525306dd 100644
--- a/src/libimcv/pts/pts.h
+++ b/src/libimcv/pts/pts.h
@@ -143,16 +143,18 @@ struct pts_t {
*
* @param value My public DH value
* @param nonce My DH nonce
+ * @return TRUE if public value retrieved successfully
*/
- void (*get_my_public_value)(pts_t *this, chunk_t *value, chunk_t *nonce);
+ bool (*get_my_public_value)(pts_t *this, chunk_t *value, chunk_t *nonce);
/**
* Set peer Diffie.Hellman public value
*
* @param value Peer public DH value
* @param nonce Peer DH nonce
+ * @return TRUE if public value set successfully
*/
- void (*set_peer_public_value) (pts_t *this, chunk_t value, chunk_t nonce);
+ bool (*set_peer_public_value) (pts_t *this, chunk_t value, chunk_t nonce);
/**
* Calculates assessment secret to be used for TPM Quote as ExternalData
diff --git a/src/libimcv/seg/seg_env.c b/src/libimcv/seg/seg_env.c
index c47ce2934..f38419248 100644
--- a/src/libimcv/seg/seg_env.c
+++ b/src/libimcv/seg/seg_env.c
@@ -219,6 +219,7 @@ seg_env_t *seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
if (max_seg_size < PA_TNC_ATTR_HEADER_SIZE ||
max_seg_size >= PA_TNC_ATTR_HEADER_SIZE + value.len)
{
+ base_attr->destroy(base_attr);
return NULL;
}
@@ -233,7 +234,7 @@ seg_env_t *seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
.destroy = _destroy,
},
.base_attr_id = base_attr_id,
- .base_attr = base_attr->get_ref(base_attr),
+ .base_attr = base_attr,
.max_seg_size = max_seg_size,
.data = base_attr->get_value(base_attr),
);
diff --git a/src/libimcv/seg/seg_env.h b/src/libimcv/seg/seg_env.h
index 08d33d752..611f9a98a 100644
--- a/src/libimcv/seg/seg_env.h
+++ b/src/libimcv/seg/seg_env.h
@@ -98,7 +98,7 @@ struct seg_env_t {
* Create a PA-TNC attribute segment envelope object
*
* @param base_attr_id Base Attribute ID
- * @param base_attr Base Attribute to be segmented
+ * @param base_attr Base Attribute to be segmented, owned by seg_env_t
* @param max_seg_size Maximum segment size
*/
seg_env_t* seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr,
diff --git a/src/libimcv/suites/test_imcv_seg.c b/src/libimcv/suites/test_imcv_seg.c
index 469b1110d..8b51eda05 100644
--- a/src/libimcv/suites/test_imcv_seg.c
+++ b/src/libimcv/suites/test_imcv_seg.c
@@ -64,10 +64,11 @@ START_TEST(test_imcv_seg_env)
libimcv_init(FALSE);
max_seg_size = seg_env_tests[_i].max_seg_size;
last_seg_size = seg_env_tests[_i].last_seg_size;
+
base_attr = ita_attr_command_create(command);
base_attr->build(base_attr);
-
seg_env = seg_env_create(id, base_attr, max_seg_size);
+
if (seg_env_tests[_i].next_segs == 0)
{
ck_assert(seg_env == NULL);
@@ -156,7 +157,6 @@ START_TEST(test_imcv_seg_env)
seg_env1->destroy(seg_env1);
base_attr1->destroy(base_attr1);
}
- base_attr->destroy(base_attr);
libimcv_deinit();
}
END_TEST
@@ -226,7 +226,6 @@ START_TEST(test_imcv_seg_env_special)
/* cleanup */
attr->destroy(attr);
seg_env->destroy(seg_env);
- base_attr->destroy(base_attr);
}
END_TEST
@@ -306,7 +305,8 @@ START_TEST(test_imcv_seg_contract)
TRUE, issuer_id, FALSE);
contract_r = seg_contract_create(msg_type, max_attr_size, max_seg_size,
FALSE, issuer_id, TRUE);
- attr = contract_r->first_segment(contract_r, base_attr_r);
+ attr = contract_r->first_segment(contract_r,
+ base_attr_r->get_ref(base_attr_r));
if (seg_env_tests[_i].next_segs == 0)
{
@@ -422,8 +422,8 @@ START_TEST(test_imcv_seg_contract_special)
ck_assert(!oversize);
/* get first segment of each base attribute */
- attr1_f = contract_r->first_segment(contract_r, base_attr1_r);
- attr2_f = contract_r->first_segment(contract_r, base_attr2_r);
+ attr1_f = contract_r->first_segment(contract_r, base_attr1_r->get_ref(base_attr1_r));
+ attr2_f = contract_r->first_segment(contract_r, base_attr2_r->get_ref(base_attr2_r));
ck_assert(attr1_f);
ck_assert(attr2_f);
seg_env_attr1 = (tcg_seg_attr_seg_env_t*)attr1_f;
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c b/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c
index 5b4cc273b..397882926 100644
--- a/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c
@@ -242,6 +242,8 @@ METHOD(pa_tnc_attr_t, process, status_t,
this->count--;
}
+ status = SUCCESS;
+
if (this->length != this->offset)
{
DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_TCG,
@@ -249,7 +251,6 @@ METHOD(pa_tnc_attr_t, process, status_t,
*offset = this->offset;
status = FAILED;
}
- status = SUCCESS;
end:
reader->destroy(reader);
diff --git a/src/libipsec/Makefile.in b/src/libipsec/Makefile.in
index 3663cf825..a80d28ac6 100644
--- a/src/libipsec/Makefile.in
+++ b/src/libipsec/Makefile.in
@@ -266,6 +266,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@
@@ -326,10 +327,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@
@@ -403,6 +406,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/libipsec/ip_packet.c b/src/libipsec/ip_packet.c
index 0998efa9d..21dbd5e89 100644
--- a/src/libipsec/ip_packet.c
+++ b/src/libipsec/ip_packet.c
@@ -443,7 +443,7 @@ ip_packet_t *ip_packet_create_from_data(host_t *src, host_t *dst,
{
struct ip6_hdr ip = {
.ip6_flow = htonl(6),
- .ip6_plen = htons(40 + data.len),
+ .ip6_plen = htons(data.len),
.ip6_nxt = next_header,
.ip6_hlim = 0x80,
};
diff --git a/src/libipsec/ipsec_event_listener.h b/src/libipsec/ipsec_event_listener.h
index c5c39b0f1..f15f6fe52 100644
--- a/src/libipsec/ipsec_event_listener.h
+++ b/src/libipsec/ipsec_event_listener.h
@@ -35,14 +35,12 @@ struct ipsec_event_listener_t {
/**
* Called when the lifetime of an IPsec SA expired
*
- * @param reqid reqid of the expired SA
* @param protocol protocol of the expired SA
* @param spi spi of the expired SA
+ * @param dst destination address of expired SA
* @param hard TRUE if this is a hard expire, FALSE otherwise
*/
- void (*expire)(u_int32_t reqid, u_int8_t protocol, u_int32_t spi,
- bool hard);
-
+ void (*expire)(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard);
};
#endif /** IPSEC_EVENT_LISTENER_H_ @}*/
diff --git a/src/libipsec/ipsec_event_relay.c b/src/libipsec/ipsec_event_relay.c
index c6b2a550d..048063053 100644
--- a/src/libipsec/ipsec_event_relay.c
+++ b/src/libipsec/ipsec_event_relay.c
@@ -65,9 +65,9 @@ typedef struct {
} type;
/**
- * Reqid of the SA, if any
+ * Protocol of the SA
*/
- u_int32_t reqid;
+ u_int8_t protocol;
/**
* SPI of the SA, if any
@@ -75,13 +75,16 @@ typedef struct {
u_int32_t spi;
/**
+ * SA destination address
+ */
+ host_t *dst;
+
+ /**
* Additional data for specific event types
*/
union {
struct {
- /** Protocol of the SA */
- u_int8_t protocol;
/** TRUE in case of a hard expire */
bool hard;
} expire;
@@ -91,6 +94,15 @@ typedef struct {
} ipsec_event_t;
/**
+ * Destroy IPsec event data
+ */
+static void ipsec_event_destroy(ipsec_event_t *event)
+{
+ event->dst->destroy(event->dst);
+ free(event);
+}
+
+/**
* Dequeue events and relay them to listeners
*/
static job_requeue_t handle_events(private_ipsec_event_relay_t *this)
@@ -110,31 +122,31 @@ static job_requeue_t handle_events(private_ipsec_event_relay_t *this)
case IPSEC_EVENT_EXPIRE:
if (current->expire)
{
- current->expire(event->reqid, event->data.expire.protocol,
- event->spi, event->data.expire.hard);
+ current->expire(event->protocol, event->spi, event->dst,
+ event->data.expire.hard);
}
break;
}
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
- free(event);
+ ipsec_event_destroy(event);
return JOB_REQUEUE_DIRECT;
}
METHOD(ipsec_event_relay_t, expire, void,
- private_ipsec_event_relay_t *this, u_int32_t reqid, u_int8_t protocol,
- u_int32_t spi, bool hard)
+ private_ipsec_event_relay_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard)
{
ipsec_event_t *event;
INIT(event,
.type = IPSEC_EVENT_EXPIRE,
- .reqid = reqid,
+ .protocol = protocol,
.spi = spi,
+ .dst = dst->clone(dst),
.data = {
.expire = {
- .protocol = protocol,
.hard = hard,
},
},
diff --git a/src/libipsec/ipsec_event_relay.h b/src/libipsec/ipsec_event_relay.h
index c6935d546..1dddf121b 100644
--- a/src/libipsec/ipsec_event_relay.h
+++ b/src/libipsec/ipsec_event_relay.h
@@ -38,13 +38,13 @@ struct ipsec_event_relay_t {
/**
* Raise an expire event.
*
- * @param reqid reqid of the expired IPsec SA
* @param protocol protocol (e.g ESP) of the expired SA
* @param spi SPI of the expired SA
+ * @param dst destination address of expired SA
* @param hard TRUE for a hard expire, FALSE otherwise
*/
- void (*expire)(ipsec_event_relay_t *this, u_int32_t reqid,
- u_int8_t protocol, u_int32_t spi, bool hard);
+ void (*expire)(ipsec_event_relay_t *this, u_int8_t protocol, u_int32_t spi,
+ host_t *dst, bool hard);
/**
* Register a listener to events raised by this manager
diff --git a/src/libipsec/ipsec_sa.c b/src/libipsec/ipsec_sa.c
index 6ec8bd25e..ccbbb1b3c 100644
--- a/src/libipsec/ipsec_sa.c
+++ b/src/libipsec/ipsec_sa.c
@@ -194,8 +194,8 @@ METHOD(ipsec_sa_t, expire, void,
if (!this->hard_expired)
{
this->hard_expired = TRUE;
- ipsec->events->expire(ipsec->events, this->reqid, this->protocol,
- this->spi, TRUE);
+ ipsec->events->expire(ipsec->events, this->protocol, this->spi,
+ this->dst, TRUE);
}
}
else
@@ -203,8 +203,8 @@ METHOD(ipsec_sa_t, expire, void,
if (!this->hard_expired && !this->soft_expired)
{
this->soft_expired = TRUE;
- ipsec->events->expire(ipsec->events, this->reqid, this->protocol,
- this->spi, FALSE);
+ ipsec->events->expire(ipsec->events, this->protocol, this->spi,
+ this->dst, FALSE);
}
}
}
@@ -275,8 +275,7 @@ ipsec_sa_t *ipsec_sa_create(u_int32_t spi, host_t *src, host_t *dst,
u_int8_t protocol, u_int32_t reqid, mark_t mark, u_int32_t tfc,
lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
- u_int16_t ipcomp, u_int16_t cpi, bool encap, bool esn, bool inbound,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+ u_int16_t ipcomp, u_int16_t cpi, bool encap, bool esn, bool inbound)
{
private_ipsec_sa_t *this;
diff --git a/src/libipsec/ipsec_sa.h b/src/libipsec/ipsec_sa.h
index 5e69f18cf..8dad29ac5 100644
--- a/src/libipsec/ipsec_sa.h
+++ b/src/libipsec/ipsec_sa.h
@@ -197,8 +197,6 @@ struct ipsec_sa_t {
* @param encap enable UDP encapsulation (must be TRUE)
* @param esn Extended Sequence Numbers (currently not supported)
* @param inbound TRUE if this is an inbound SA, FALSE otherwise
- * @param src_ts source traffic selector
- * @param dst_ts destination traffic selector
* @return the IPsec SA, or NULL if the creation failed
*/
ipsec_sa_t *ipsec_sa_create(u_int32_t spi, host_t *src, host_t *dst,
@@ -207,8 +205,6 @@ ipsec_sa_t *ipsec_sa_create(u_int32_t spi, host_t *src, host_t *dst,
u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key,
ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
- bool encap, bool esn, bool inbound,
- traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts);
+ bool encap, bool esn, bool inbound);
#endif /** IPSEC_SA_H_ @}*/
diff --git a/src/libipsec/ipsec_sa_mgr.c b/src/libipsec/ipsec_sa_mgr.c
index 1db1776c0..07ffa9e4f 100644
--- a/src/libipsec/ipsec_sa_mgr.c
+++ b/src/libipsec/ipsec_sa_mgr.c
@@ -396,12 +396,10 @@ static bool allocate_spi(private_ipsec_sa_mgr_t *this, u_int32_t spi)
METHOD(ipsec_sa_mgr_t, get_spi, status_t,
private_ipsec_sa_mgr_t *this, host_t *src, host_t *dst, u_int8_t protocol,
- u_int32_t reqid, u_int32_t *spi)
+ u_int32_t *spi)
{
u_int32_t spi_new;
- DBG2(DBG_ESP, "allocating SPI for reqid {%u}", reqid);
-
this->mutex->lock(this->mutex);
if (!this->rng)
{
@@ -420,7 +418,7 @@ METHOD(ipsec_sa_mgr_t, get_spi, status_t,
(u_int8_t*)&spi_new))
{
this->mutex->unlock(this->mutex);
- DBG1(DBG_ESP, "failed to allocate SPI for reqid {%u}", reqid);
+ DBG1(DBG_ESP, "failed to allocate SPI");
return FAILED;
}
/* make sure the SPI is valid (not in range 0-255) */
@@ -432,7 +430,7 @@ METHOD(ipsec_sa_mgr_t, get_spi, status_t,
*spi = spi_new;
- DBG2(DBG_ESP, "allocated SPI %.8x for reqid {%u}", ntohl(*spi), reqid);
+ DBG2(DBG_ESP, "allocated SPI %.8x", ntohl(*spi));
return SUCCESS;
}
@@ -442,7 +440,7 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t,
lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
u_int16_t cpi, bool initiator, bool encap, bool esn, bool inbound,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+ bool update)
{
ipsec_sa_entry_t *entry;
ipsec_sa_t *sa_new;
@@ -456,7 +454,7 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t,
sa_new = ipsec_sa_create(spi, src, dst, protocol, reqid, mark, tfc,
lifetime, enc_alg, enc_key, int_alg, int_key, mode,
- ipcomp, cpi, encap, esn, inbound, src_ts, dst_ts);
+ ipcomp, cpi, encap, esn, inbound);
if (!sa_new)
{
DBG1(DBG_ESP, "failed to create SAD entry");
@@ -465,7 +463,7 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t,
this->mutex->lock(this->mutex);
- if (inbound)
+ if (update)
{ /* remove any pre-allocated SPIs */
u_int32_t *spi_alloc;
diff --git a/src/libipsec/ipsec_sa_mgr.h b/src/libipsec/ipsec_sa_mgr.h
index 8c234cefa..a57eab4e7 100644
--- a/src/libipsec/ipsec_sa_mgr.h
+++ b/src/libipsec/ipsec_sa_mgr.h
@@ -45,12 +45,11 @@ struct ipsec_sa_mgr_t {
* @param src source address of the SA
* @param dst destination address of the SA
* @param protocol protocol of the SA (only ESP supported)
- * @param reqid reqid for the SA
* @param spi the allocated SPI
* @return SUCCESS of operation successful
*/
status_t (*get_spi)(ipsec_sa_mgr_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);
/**
* Add a new SA
@@ -74,8 +73,7 @@ struct ipsec_sa_mgr_t {
* @param encap enable UDP encapsulation (must be TRUE)
* @param esn Extended Sequence Numbers (currently not supported)
* @param inbound TRUE if this is an inbound SA, FALSE otherwise
- * @param src_ts source traffic selector
- * @param dst_ts destination traffic selector
+ * @param update TRUE if an SPI has already been allocated for SA
* @return SUCCESS if operation completed
*/
status_t (*add_sa)(ipsec_sa_mgr_t *this, host_t *src, host_t *dst,
@@ -84,8 +82,7 @@ struct ipsec_sa_mgr_t {
u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg,
chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
u_int16_t cpi, bool initiator, bool encap, bool esn,
- bool inbound, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts);
+ bool inbound, bool update);
/**
* Update the hosts on an installed SA.
diff --git a/src/libpttls/Makefile.in b/src/libpttls/Makefile.in
index 74cd8084a..96d1ae4aa 100644
--- a/src/libpttls/Makefile.in
+++ b/src/libpttls/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/libradius/Makefile.in b/src/libradius/Makefile.in
index faaae70fe..5dd8ac56b 100644
--- a/src/libradius/Makefile.in
+++ b/src/libradius/Makefile.in
@@ -222,6 +222,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@
@@ -282,10 +283,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@
@@ -359,6 +362,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/libradius/radius_socket.c b/src/libradius/radius_socket.c
index f432151c0..fe9cf3c01 100644
--- a/src/libradius/radius_socket.c
+++ b/src/libradius/radius_socket.c
@@ -129,7 +129,7 @@ METHOD(radius_socket_t, request, radius_message_t*,
private_radius_socket_t *this, radius_message_t *request)
{
chunk_t data;
- int i, *fd;
+ int i, *fd, retransmit = 0;
u_int16_t port;
rng_t *rng = NULL;
@@ -166,64 +166,59 @@ METHOD(radius_socket_t, request, radius_message_t*,
for (i = 2; i <= 5; i++)
{
radius_message_t *response;
- bool retransmit = FALSE;
- struct timeval tv;
char buf[4096];
- fd_set fds;
int res;
+ struct pollfd pfd = {
+ .fd = *fd,
+ .events = POLLIN,
+ };
+ if (retransmit)
+ {
+ DBG1(DBG_CFG, "retransmitting RADIUS %N (attempt %d)",
+ radius_message_code_names, request->get_code(request),
+ retransmit);
+ }
if (send(*fd, data.ptr, data.len, 0) != data.len)
{
DBG1(DBG_CFG, "sending RADIUS message failed: %s", strerror(errno));
return NULL;
}
- tv.tv_sec = i;
- tv.tv_usec = 0;
-
- while (TRUE)
+ res = poll(&pfd, 1, i * 1000);
+ if (res < 0)
{
- FD_ZERO(&fds);
- FD_SET(*fd, &fds);
- res = select((*fd) + 1, &fds, NULL, NULL, &tv);
- /* TODO: updated tv to time not waited. Linux does this for us. */
- if (res < 0)
- { /* failed */
- DBG1(DBG_CFG, "waiting for RADIUS message failed: %s",
- strerror(errno));
- break;
- }
- if (res == 0)
- { /* timeout */
- DBG1(DBG_CFG, "retransmitting RADIUS message");
- retransmit = TRUE;
- break;
- }
- res = recv(*fd, buf, sizeof(buf), MSG_DONTWAIT);
- if (res <= 0)
- {
- DBG1(DBG_CFG, "receiving RADIUS message failed: %s",
- strerror(errno));
- break;
- }
- response = radius_message_parse(chunk_create(buf, res));
- if (response)
- {
- if (response->verify(response,
- request->get_authenticator(request), this->secret,
- this->hasher, this->signer))
- {
- return response;
- }
- response->destroy(response);
- }
- DBG1(DBG_CFG, "received invalid RADIUS message, ignored");
+ DBG1(DBG_CFG, "waiting for RADIUS message failed: %s",
+ strerror(errno));
+ return NULL;
+ }
+ if (res == 0)
+ { /* timeout */
+ retransmit++;
+ continue;
}
- if (!retransmit)
+ res = recv(*fd, buf, sizeof(buf), MSG_DONTWAIT);
+ if (res <= 0)
{
- break;
+ DBG1(DBG_CFG, "receiving RADIUS message failed: %s",
+ strerror(errno));
+ return NULL;
}
+ response = radius_message_parse(chunk_create(buf, res));
+ if (response)
+ {
+ if (response->verify(response,
+ request->get_authenticator(request), this->secret,
+ this->hasher, this->signer))
+ {
+ return response;
+ }
+ response->destroy(response);
+ }
+ DBG1(DBG_CFG, "received invalid RADIUS message, ignored");
+ return NULL;
}
- DBG1(DBG_CFG, "RADIUS server is not responding");
+ DBG1(DBG_CFG, "RADIUS %N timed out after %d retransmits",
+ radius_message_code_names, request->get_code(request), retransmit - 1);
return NULL;
}
diff --git a/src/libsimaka/Makefile.in b/src/libsimaka/Makefile.in
index a16991927..79962d3bd 100644
--- a/src/libsimaka/Makefile.in
+++ b/src/libsimaka/Makefile.in
@@ -222,6 +222,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@
@@ -282,10 +283,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@
@@ -359,6 +362,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/libstrongswan/Android.mk b/src/libstrongswan/Android.mk
index 9b775f9b3..2a8894b0e 100644
--- a/src/libstrongswan/Android.mk
+++ b/src/libstrongswan/Android.mk
@@ -8,12 +8,14 @@ asn1/asn1.c asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c bio/bio_writer.c \
collections/blocking_queue.c collections/enumerator.c collections/hashtable.c \
collections/array.c \
collections/linked_list.c crypto/crypters/crypter.c crypto/hashers/hasher.c \
+crypto/hashers/hash_algorithm_set.c \
crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \
crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \
crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \
crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \
crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \
crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \
+crypto/mgf1/mgf1.c crypto/mgf1/mgf1_bitspender.c \
credentials/credential_factory.c credentials/builder.c \
credentials/cred_encoding.c credentials/keys/private_key.c \
credentials/keys/public_key.c credentials/keys/shared_key.c \
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am
index 0083ffe6b..fbc752687 100644
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
@@ -6,12 +6,14 @@ asn1/asn1.c asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c bio/bio_writer.c \
collections/blocking_queue.c collections/enumerator.c collections/hashtable.c \
collections/array.c \
collections/linked_list.c crypto/crypters/crypter.c crypto/hashers/hasher.c \
+crypto/hashers/hash_algorithm_set.c \
crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \
crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \
crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \
crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \
crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \
crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \
+crypto/mgf1/mgf1.c crypto/mgf1/mgf1_bitspender.c \
credentials/credential_factory.c credentials/builder.c \
credentials/cred_encoding.c credentials/keys/private_key.c \
credentials/keys/public_key.c credentials/keys/shared_key.c \
@@ -60,13 +62,15 @@ library.h \
asn1/asn1.h asn1/asn1_parser.h asn1/oid.h bio/bio_reader.h bio/bio_writer.h \
collections/blocking_queue.h collections/enumerator.h collections/hashtable.h \
collections/linked_list.h collections/array.h collections/dictionary.h \
-crypto/crypters/crypter.h crypto/hashers/hasher.h crypto/mac.h \
+crypto/crypters/crypter.h crypto/hashers/hasher.h \
+crypto/hashers/hash_algorithm_set.h crypto/mac.h \
crypto/proposal/proposal_keywords.h crypto/proposal/proposal_keywords_static.h \
crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \
crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \
crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \
crypto/aead.h crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \
crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h \
+crypto/mgf1/mgf1.h crypto/mgf1/mgf1_bitspender.h \
credentials/credential_factory.h credentials/builder.h \
credentials/cred_encoding.h credentials/keys/private_key.h \
credentials/keys/public_key.h credentials/keys/shared_key.h \
@@ -101,8 +105,8 @@ utils/utils.h utils/chunk.h utils/debug.h utils/enum.h utils/identification.h \
utils/lexparser.h utils/optionsfrom.h utils/capabilities.h utils/backtrace.h \
utils/leak_detective.h utils/printf_hook/printf_hook.h \
utils/printf_hook/printf_hook_vstr.h utils/printf_hook/printf_hook_builtin.h \
-utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/windows.h \
-utils/process.h utils/utils/strerror.h
+utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/process.h \
+utils/utils/strerror.h utils/compat/windows.h utils/compat/apple.h
endif
library.lo : $(top_builddir)/config.status
@@ -133,7 +137,7 @@ if USE_WINDOWS
threading/windows/rwlock.c \
threading/windows/spinlock.c \
threading/windows/semaphore.c \
- utils/windows.c
+ utils/compat/windows.c
else
libstrongswan_la_LIBADD += $(PTHREADLIB)
endif
@@ -425,6 +429,13 @@ if MONOLITHIC
endif
endif
+if USE_FILES
+ SUBDIRS += plugins/files
+if MONOLITHIC
+ libstrongswan_la_LIBADD += plugins/files/libstrongswan-files.la
+endif
+endif
+
if USE_WINHTTP
SUBDIRS += plugins/winhttp
if MONOLITHIC
@@ -544,6 +555,13 @@ if MONOLITHIC
endif
endif
+if USE_BLISS
+ SUBDIRS += plugins/bliss
+if MONOLITHIC
+ libstrongswan_la_LIBADD += plugins/bliss/libstrongswan-bliss.la
+endif
+endif
+
if USE_TEST_VECTORS
SUBDIRS += plugins/test_vectors
if MONOLITHIC
@@ -555,3 +573,6 @@ if MONOLITHIC
SUBDIRS += .
endif
SUBDIRS += tests
+if USE_BLISS
+ SUBDIRS += plugins/bliss/tests
+endif
diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in
index 40678cbde..99b18a757 100644
--- a/src/libstrongswan/Makefile.in
+++ b/src/libstrongswan/Makefile.in
@@ -97,7 +97,7 @@ host_triplet = @host@
@USE_WINDOWS_TRUE@ threading/windows/rwlock.c \
@USE_WINDOWS_TRUE@ threading/windows/spinlock.c \
@USE_WINDOWS_TRUE@ threading/windows/semaphore.c \
-@USE_WINDOWS_TRUE@ utils/windows.c
+@USE_WINDOWS_TRUE@ utils/compat/windows.c
@USE_WINDOWS_FALSE@am__append_4 = $(PTHREADLIB)
@USE_DBGHELP_TRUE@am__append_5 = -ldbghelp
@@ -173,42 +173,47 @@ host_triplet = @host@
@MONOLITHIC_TRUE@@USE_PEM_TRUE@am__append_75 = plugins/pem/libstrongswan-pem.la
@USE_CURL_TRUE@am__append_76 = plugins/curl
@MONOLITHIC_TRUE@@USE_CURL_TRUE@am__append_77 = plugins/curl/libstrongswan-curl.la
-@USE_WINHTTP_TRUE@am__append_78 = plugins/winhttp
-@MONOLITHIC_TRUE@@USE_WINHTTP_TRUE@am__append_79 = plugins/winhttp/libstrongswan-winhttp.la
-@USE_UNBOUND_TRUE@am__append_80 = plugins/unbound
-@MONOLITHIC_TRUE@@USE_UNBOUND_TRUE@am__append_81 = plugins/unbound/libstrongswan-unbound.la
-@USE_SOUP_TRUE@am__append_82 = plugins/soup
-@MONOLITHIC_TRUE@@USE_SOUP_TRUE@am__append_83 = plugins/soup/libstrongswan-soup.la
-@USE_LDAP_TRUE@am__append_84 = plugins/ldap
-@MONOLITHIC_TRUE@@USE_LDAP_TRUE@am__append_85 = plugins/ldap/libstrongswan-ldap.la
-@USE_MYSQL_TRUE@am__append_86 = plugins/mysql
-@MONOLITHIC_TRUE@@USE_MYSQL_TRUE@am__append_87 = plugins/mysql/libstrongswan-mysql.la
-@USE_SQLITE_TRUE@am__append_88 = plugins/sqlite
-@MONOLITHIC_TRUE@@USE_SQLITE_TRUE@am__append_89 = plugins/sqlite/libstrongswan-sqlite.la
-@USE_PADLOCK_TRUE@am__append_90 = plugins/padlock
-@MONOLITHIC_TRUE@@USE_PADLOCK_TRUE@am__append_91 = plugins/padlock/libstrongswan-padlock.la
-@USE_OPENSSL_TRUE@am__append_92 = plugins/openssl
-@MONOLITHIC_TRUE@@USE_OPENSSL_TRUE@am__append_93 = plugins/openssl/libstrongswan-openssl.la
-@USE_GCRYPT_TRUE@am__append_94 = plugins/gcrypt
-@MONOLITHIC_TRUE@@USE_GCRYPT_TRUE@am__append_95 = plugins/gcrypt/libstrongswan-gcrypt.la
-@USE_FIPS_PRF_TRUE@am__append_96 = plugins/fips_prf
-@MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE@am__append_97 = plugins/fips_prf/libstrongswan-fips-prf.la
-@USE_AGENT_TRUE@am__append_98 = plugins/agent
-@MONOLITHIC_TRUE@@USE_AGENT_TRUE@am__append_99 = plugins/agent/libstrongswan-agent.la
-@USE_KEYCHAIN_TRUE@am__append_100 = plugins/keychain
-@MONOLITHIC_TRUE@@USE_KEYCHAIN_TRUE@am__append_101 = plugins/keychain/libstrongswan-keychain.la
-@USE_PKCS11_TRUE@am__append_102 = plugins/pkcs11
-@MONOLITHIC_TRUE@@USE_PKCS11_TRUE@am__append_103 = plugins/pkcs11/libstrongswan-pkcs11.la
-@USE_CTR_TRUE@am__append_104 = plugins/ctr
-@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_105 = plugins/ctr/libstrongswan-ctr.la
-@USE_CCM_TRUE@am__append_106 = plugins/ccm
-@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_107 = plugins/ccm/libstrongswan-ccm.la
-@USE_GCM_TRUE@am__append_108 = plugins/gcm
-@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_109 = plugins/gcm/libstrongswan-gcm.la
-@USE_NTRU_TRUE@am__append_110 = plugins/ntru
-@MONOLITHIC_TRUE@@USE_NTRU_TRUE@am__append_111 = plugins/ntru/libstrongswan-ntru.la
-@USE_TEST_VECTORS_TRUE@am__append_112 = plugins/test_vectors
-@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_113 = plugins/test_vectors/libstrongswan-test-vectors.la
+@USE_FILES_TRUE@am__append_78 = plugins/files
+@MONOLITHIC_TRUE@@USE_FILES_TRUE@am__append_79 = plugins/files/libstrongswan-files.la
+@USE_WINHTTP_TRUE@am__append_80 = plugins/winhttp
+@MONOLITHIC_TRUE@@USE_WINHTTP_TRUE@am__append_81 = plugins/winhttp/libstrongswan-winhttp.la
+@USE_UNBOUND_TRUE@am__append_82 = plugins/unbound
+@MONOLITHIC_TRUE@@USE_UNBOUND_TRUE@am__append_83 = plugins/unbound/libstrongswan-unbound.la
+@USE_SOUP_TRUE@am__append_84 = plugins/soup
+@MONOLITHIC_TRUE@@USE_SOUP_TRUE@am__append_85 = plugins/soup/libstrongswan-soup.la
+@USE_LDAP_TRUE@am__append_86 = plugins/ldap
+@MONOLITHIC_TRUE@@USE_LDAP_TRUE@am__append_87 = plugins/ldap/libstrongswan-ldap.la
+@USE_MYSQL_TRUE@am__append_88 = plugins/mysql
+@MONOLITHIC_TRUE@@USE_MYSQL_TRUE@am__append_89 = plugins/mysql/libstrongswan-mysql.la
+@USE_SQLITE_TRUE@am__append_90 = plugins/sqlite
+@MONOLITHIC_TRUE@@USE_SQLITE_TRUE@am__append_91 = plugins/sqlite/libstrongswan-sqlite.la
+@USE_PADLOCK_TRUE@am__append_92 = plugins/padlock
+@MONOLITHIC_TRUE@@USE_PADLOCK_TRUE@am__append_93 = plugins/padlock/libstrongswan-padlock.la
+@USE_OPENSSL_TRUE@am__append_94 = plugins/openssl
+@MONOLITHIC_TRUE@@USE_OPENSSL_TRUE@am__append_95 = plugins/openssl/libstrongswan-openssl.la
+@USE_GCRYPT_TRUE@am__append_96 = plugins/gcrypt
+@MONOLITHIC_TRUE@@USE_GCRYPT_TRUE@am__append_97 = plugins/gcrypt/libstrongswan-gcrypt.la
+@USE_FIPS_PRF_TRUE@am__append_98 = plugins/fips_prf
+@MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE@am__append_99 = plugins/fips_prf/libstrongswan-fips-prf.la
+@USE_AGENT_TRUE@am__append_100 = plugins/agent
+@MONOLITHIC_TRUE@@USE_AGENT_TRUE@am__append_101 = plugins/agent/libstrongswan-agent.la
+@USE_KEYCHAIN_TRUE@am__append_102 = plugins/keychain
+@MONOLITHIC_TRUE@@USE_KEYCHAIN_TRUE@am__append_103 = plugins/keychain/libstrongswan-keychain.la
+@USE_PKCS11_TRUE@am__append_104 = plugins/pkcs11
+@MONOLITHIC_TRUE@@USE_PKCS11_TRUE@am__append_105 = plugins/pkcs11/libstrongswan-pkcs11.la
+@USE_CTR_TRUE@am__append_106 = plugins/ctr
+@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_107 = plugins/ctr/libstrongswan-ctr.la
+@USE_CCM_TRUE@am__append_108 = plugins/ccm
+@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_109 = plugins/ccm/libstrongswan-ccm.la
+@USE_GCM_TRUE@am__append_110 = plugins/gcm
+@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_111 = plugins/gcm/libstrongswan-gcm.la
+@USE_NTRU_TRUE@am__append_112 = plugins/ntru
+@MONOLITHIC_TRUE@@USE_NTRU_TRUE@am__append_113 = plugins/ntru/libstrongswan-ntru.la
+@USE_BLISS_TRUE@am__append_114 = plugins/bliss
+@MONOLITHIC_TRUE@@USE_BLISS_TRUE@am__append_115 = plugins/bliss/libstrongswan-bliss.la
+@USE_TEST_VECTORS_TRUE@am__append_116 = plugins/test_vectors
+@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_117 = plugins/test_vectors/libstrongswan-test-vectors.la
+@USE_BLISS_TRUE@am__append_118 = plugins/bliss/tests
subdir = src/libstrongswan
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
settings/settings_parser.h settings/settings_parser.c \
@@ -287,13 +292,14 @@ libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__append_95) $(am__append_97) $(am__append_99) \
$(am__append_101) $(am__append_103) $(am__append_105) \
$(am__append_107) $(am__append_109) $(am__append_111) \
- $(am__append_113)
+ $(am__append_113) $(am__append_115) $(am__append_117)
am__libstrongswan_la_SOURCES_DIST = library.c asn1/asn1.c \
asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c \
bio/bio_writer.c collections/blocking_queue.c \
collections/enumerator.c collections/hashtable.c \
collections/array.c collections/linked_list.c \
crypto/crypters/crypter.c crypto/hashers/hasher.c \
+ crypto/hashers/hash_algorithm_set.c \
crypto/proposal/proposal_keywords.c \
crypto/proposal/proposal_keywords_static.c crypto/prfs/prf.c \
crypto/prfs/mac_prf.c crypto/pkcs5.c crypto/rngs/rng.c \
@@ -301,7 +307,8 @@ am__libstrongswan_la_SOURCES_DIST = library.c asn1/asn1.c \
crypto/signers/mac_signer.c crypto/crypto_factory.c \
crypto/crypto_tester.c crypto/diffie_hellman.c crypto/aead.c \
crypto/transform.c crypto/iv/iv_gen_rand.c \
- crypto/iv/iv_gen_seq.c credentials/credential_factory.c \
+ crypto/iv/iv_gen_seq.c crypto/mgf1/mgf1.c \
+ crypto/mgf1/mgf1_bitspender.c credentials/credential_factory.c \
credentials/builder.c credentials/cred_encoding.c \
credentials/keys/private_key.c credentials/keys/public_key.c \
credentials/keys/shared_key.c \
@@ -342,7 +349,7 @@ am__libstrongswan_la_SOURCES_DIST = library.c asn1/asn1.c \
threading/windows/thread.c threading/windows/thread_value.c \
threading/windows/mutex.c threading/windows/rwlock.c \
threading/windows/spinlock.c threading/windows/semaphore.c \
- utils/windows.c utils/leak_detective.c \
+ utils/compat/windows.c utils/leak_detective.c \
utils/integrity_checker.c utils/printf_hook/printf_hook_vstr.c \
utils/printf_hook/printf_hook_builtin.c \
utils/printf_hook/printf_hook_glibc.c
@@ -360,7 +367,7 @@ am__dirstamp = $(am__leading_dot)dirstamp
@USE_WINDOWS_TRUE@ threading/windows/rwlock.lo \
@USE_WINDOWS_TRUE@ threading/windows/spinlock.lo \
@USE_WINDOWS_TRUE@ threading/windows/semaphore.lo \
-@USE_WINDOWS_TRUE@ utils/windows.lo
+@USE_WINDOWS_TRUE@ utils/compat/windows.lo
@USE_LEAK_DETECTIVE_TRUE@am__objects_3 = utils/leak_detective.lo
@USE_INTEGRITY_TEST_TRUE@am__objects_4 = utils/integrity_checker.lo
@USE_VSTR_TRUE@am__objects_5 = utils/printf_hook/printf_hook_vstr.lo
@@ -372,6 +379,7 @@ am_libstrongswan_la_OBJECTS = library.lo asn1/asn1.lo \
collections/enumerator.lo collections/hashtable.lo \
collections/array.lo collections/linked_list.lo \
crypto/crypters/crypter.lo crypto/hashers/hasher.lo \
+ crypto/hashers/hash_algorithm_set.lo \
crypto/proposal/proposal_keywords.lo \
crypto/proposal/proposal_keywords_static.lo crypto/prfs/prf.lo \
crypto/prfs/mac_prf.lo crypto/pkcs5.lo crypto/rngs/rng.lo \
@@ -379,10 +387,11 @@ am_libstrongswan_la_OBJECTS = library.lo asn1/asn1.lo \
crypto/signers/mac_signer.lo crypto/crypto_factory.lo \
crypto/crypto_tester.lo crypto/diffie_hellman.lo \
crypto/aead.lo crypto/transform.lo crypto/iv/iv_gen_rand.lo \
- crypto/iv/iv_gen_seq.lo credentials/credential_factory.lo \
- credentials/builder.lo credentials/cred_encoding.lo \
- credentials/keys/private_key.lo credentials/keys/public_key.lo \
- credentials/keys/shared_key.lo \
+ crypto/iv/iv_gen_seq.lo crypto/mgf1/mgf1.lo \
+ crypto/mgf1/mgf1_bitspender.lo \
+ credentials/credential_factory.lo credentials/builder.lo \
+ credentials/cred_encoding.lo credentials/keys/private_key.lo \
+ credentials/keys/public_key.lo credentials/keys/shared_key.lo \
credentials/certificates/certificate.lo \
credentials/certificates/crl.lo \
credentials/certificates/ocsp_response.lo \
@@ -493,8 +502,8 @@ am__nobase_strongswan_include_HEADERS_DIST = library.h asn1/asn1.h \
collections/enumerator.h collections/hashtable.h \
collections/linked_list.h collections/array.h \
collections/dictionary.h crypto/crypters/crypter.h \
- crypto/hashers/hasher.h crypto/mac.h \
- crypto/proposal/proposal_keywords.h \
+ crypto/hashers/hasher.h crypto/hashers/hash_algorithm_set.h \
+ crypto/mac.h crypto/proposal/proposal_keywords.h \
crypto/proposal/proposal_keywords_static.h crypto/prfs/prf.h \
crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \
crypto/prf_plus.h crypto/signers/signer.h \
@@ -502,6 +511,7 @@ am__nobase_strongswan_include_HEADERS_DIST = library.h asn1/asn1.h \
crypto/crypto_tester.h crypto/diffie_hellman.h crypto/aead.h \
crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \
crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h \
+ crypto/mgf1/mgf1.h crypto/mgf1/mgf1_bitspender.h \
credentials/credential_factory.h credentials/builder.h \
credentials/cred_encoding.h credentials/keys/private_key.h \
credentials/keys/public_key.h credentials/keys/shared_key.h \
@@ -548,8 +558,9 @@ am__nobase_strongswan_include_HEADERS_DIST = library.h asn1/asn1.h \
utils/printf_hook/printf_hook.h \
utils/printf_hook/printf_hook_vstr.h \
utils/printf_hook/printf_hook_builtin.h utils/parser_helper.h \
- utils/test.h utils/integrity_checker.h utils/windows.h \
- utils/process.h utils/utils/strerror.h
+ utils/test.h utils/integrity_checker.h utils/process.h \
+ utils/utils/strerror.h utils/compat/windows.h \
+ utils/compat/apple.h
HEADERS = $(nobase_strongswan_include_HEADERS) $(noinst_HEADERS)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
@@ -586,11 +597,12 @@ DIST_SUBDIRS = . plugins/af_alg plugins/aes plugins/des \
plugins/constraints plugins/acert plugins/pubkey plugins/pkcs1 \
plugins/pkcs7 plugins/pkcs8 plugins/pkcs12 plugins/pgp \
plugins/dnskey plugins/sshkey plugins/pem plugins/curl \
- plugins/winhttp plugins/unbound plugins/soup plugins/ldap \
- plugins/mysql plugins/sqlite plugins/padlock plugins/openssl \
- plugins/gcrypt plugins/fips_prf plugins/agent plugins/keychain \
- plugins/pkcs11 plugins/ctr plugins/ccm plugins/gcm \
- plugins/ntru plugins/test_vectors tests
+ plugins/files plugins/winhttp plugins/unbound plugins/soup \
+ plugins/ldap plugins/mysql plugins/sqlite plugins/padlock \
+ plugins/openssl plugins/gcrypt plugins/fips_prf plugins/agent \
+ plugins/keychain plugins/pkcs11 plugins/ctr plugins/ccm \
+ plugins/gcm plugins/ntru plugins/bliss plugins/test_vectors \
+ tests plugins/bliss/tests
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -642,6 +654,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@
@@ -702,10 +715,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@
@@ -779,6 +794,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@
@@ -843,14 +860,16 @@ libstrongswan_la_SOURCES = library.c asn1/asn1.c asn1/asn1_parser.c \
collections/blocking_queue.c collections/enumerator.c \
collections/hashtable.c collections/array.c \
collections/linked_list.c crypto/crypters/crypter.c \
- crypto/hashers/hasher.c crypto/proposal/proposal_keywords.c \
+ crypto/hashers/hasher.c crypto/hashers/hash_algorithm_set.c \
+ crypto/proposal/proposal_keywords.c \
crypto/proposal/proposal_keywords_static.c crypto/prfs/prf.c \
crypto/prfs/mac_prf.c crypto/pkcs5.c crypto/rngs/rng.c \
crypto/prf_plus.c crypto/signers/signer.c \
crypto/signers/mac_signer.c crypto/crypto_factory.c \
crypto/crypto_tester.c crypto/diffie_hellman.c crypto/aead.c \
crypto/transform.c crypto/iv/iv_gen_rand.c \
- crypto/iv/iv_gen_seq.c credentials/credential_factory.c \
+ crypto/iv/iv_gen_seq.c crypto/mgf1/mgf1.c \
+ crypto/mgf1/mgf1_bitspender.c credentials/credential_factory.c \
credentials/builder.c credentials/cred_encoding.c \
credentials/keys/private_key.c credentials/keys/public_key.c \
credentials/keys/shared_key.c \
@@ -898,13 +917,15 @@ settings/settings_types.h
@USE_DEV_HEADERS_TRUE@asn1/asn1.h asn1/asn1_parser.h asn1/oid.h bio/bio_reader.h bio/bio_writer.h \
@USE_DEV_HEADERS_TRUE@collections/blocking_queue.h collections/enumerator.h collections/hashtable.h \
@USE_DEV_HEADERS_TRUE@collections/linked_list.h collections/array.h collections/dictionary.h \
-@USE_DEV_HEADERS_TRUE@crypto/crypters/crypter.h crypto/hashers/hasher.h crypto/mac.h \
+@USE_DEV_HEADERS_TRUE@crypto/crypters/crypter.h crypto/hashers/hasher.h \
+@USE_DEV_HEADERS_TRUE@crypto/hashers/hash_algorithm_set.h crypto/mac.h \
@USE_DEV_HEADERS_TRUE@crypto/proposal/proposal_keywords.h crypto/proposal/proposal_keywords_static.h \
@USE_DEV_HEADERS_TRUE@crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \
@USE_DEV_HEADERS_TRUE@crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \
@USE_DEV_HEADERS_TRUE@crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \
@USE_DEV_HEADERS_TRUE@crypto/aead.h crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \
@USE_DEV_HEADERS_TRUE@crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h \
+@USE_DEV_HEADERS_TRUE@crypto/mgf1/mgf1.h crypto/mgf1/mgf1_bitspender.h \
@USE_DEV_HEADERS_TRUE@credentials/credential_factory.h credentials/builder.h \
@USE_DEV_HEADERS_TRUE@credentials/cred_encoding.h credentials/keys/private_key.h \
@USE_DEV_HEADERS_TRUE@credentials/keys/public_key.h credentials/keys/shared_key.h \
@@ -939,8 +960,8 @@ settings/settings_types.h
@USE_DEV_HEADERS_TRUE@utils/lexparser.h utils/optionsfrom.h utils/capabilities.h utils/backtrace.h \
@USE_DEV_HEADERS_TRUE@utils/leak_detective.h utils/printf_hook/printf_hook.h \
@USE_DEV_HEADERS_TRUE@utils/printf_hook/printf_hook_vstr.h utils/printf_hook/printf_hook_builtin.h \
-@USE_DEV_HEADERS_TRUE@utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/windows.h \
-@USE_DEV_HEADERS_TRUE@utils/process.h utils/utils/strerror.h
+@USE_DEV_HEADERS_TRUE@utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/process.h \
+@USE_DEV_HEADERS_TRUE@utils/utils/strerror.h utils/compat/windows.h utils/compat/apple.h
libstrongswan_la_LIBADD = $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) \
$(BFDLIB) $(UNWINDLIB) $(am__append_2) $(am__append_4) \
@@ -961,7 +982,7 @@ libstrongswan_la_LIBADD = $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) \
$(am__append_95) $(am__append_97) $(am__append_99) \
$(am__append_101) $(am__append_103) $(am__append_105) \
$(am__append_107) $(am__append_109) $(am__append_111) \
- $(am__append_113)
+ $(am__append_113) $(am__append_115) $(am__append_117)
AM_CPPFLAGS = -I$(top_srcdir)/src/libstrongswan \
-DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_LIB_DIR=\"${ipseclibdir}\" \
-DPLUGINDIR=\"${plugindir}\" \
@@ -1011,7 +1032,9 @@ $(srcdir)/crypto/proposal/proposal_keywords_static.c
@MONOLITHIC_FALSE@ $(am__append_98) $(am__append_100) \
@MONOLITHIC_FALSE@ $(am__append_102) $(am__append_104) \
@MONOLITHIC_FALSE@ $(am__append_106) $(am__append_108) \
-@MONOLITHIC_FALSE@ $(am__append_110) $(am__append_112) tests
+@MONOLITHIC_FALSE@ $(am__append_110) $(am__append_112) \
+@MONOLITHIC_FALSE@ $(am__append_114) $(am__append_116) tests \
+@MONOLITHIC_FALSE@ $(am__append_118)
# build plugins with their own Makefile
#######################################
@@ -1038,7 +1061,9 @@ $(srcdir)/crypto/proposal/proposal_keywords_static.c
@MONOLITHIC_TRUE@ $(am__append_98) $(am__append_100) \
@MONOLITHIC_TRUE@ $(am__append_102) $(am__append_104) \
@MONOLITHIC_TRUE@ $(am__append_106) $(am__append_108) \
-@MONOLITHIC_TRUE@ $(am__append_110) $(am__append_112) . tests
+@MONOLITHIC_TRUE@ $(am__append_110) $(am__append_112) \
+@MONOLITHIC_TRUE@ $(am__append_114) $(am__append_116) . tests \
+@MONOLITHIC_TRUE@ $(am__append_118)
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -1159,6 +1184,8 @@ crypto/hashers/$(DEPDIR)/$(am__dirstamp):
@: > crypto/hashers/$(DEPDIR)/$(am__dirstamp)
crypto/hashers/hasher.lo: crypto/hashers/$(am__dirstamp) \
crypto/hashers/$(DEPDIR)/$(am__dirstamp)
+crypto/hashers/hash_algorithm_set.lo: crypto/hashers/$(am__dirstamp) \
+ crypto/hashers/$(DEPDIR)/$(am__dirstamp)
crypto/proposal/$(am__dirstamp):
@$(MKDIR_P) crypto/proposal
@: > crypto/proposal/$(am__dirstamp)
@@ -1228,6 +1255,16 @@ crypto/iv/iv_gen_rand.lo: crypto/iv/$(am__dirstamp) \
crypto/iv/$(DEPDIR)/$(am__dirstamp)
crypto/iv/iv_gen_seq.lo: crypto/iv/$(am__dirstamp) \
crypto/iv/$(DEPDIR)/$(am__dirstamp)
+crypto/mgf1/$(am__dirstamp):
+ @$(MKDIR_P) crypto/mgf1
+ @: > crypto/mgf1/$(am__dirstamp)
+crypto/mgf1/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) crypto/mgf1/$(DEPDIR)
+ @: > crypto/mgf1/$(DEPDIR)/$(am__dirstamp)
+crypto/mgf1/mgf1.lo: crypto/mgf1/$(am__dirstamp) \
+ crypto/mgf1/$(DEPDIR)/$(am__dirstamp)
+crypto/mgf1/mgf1_bitspender.lo: crypto/mgf1/$(am__dirstamp) \
+ crypto/mgf1/$(DEPDIR)/$(am__dirstamp)
credentials/$(am__dirstamp):
@$(MKDIR_P) credentials
@: > credentials/$(am__dirstamp)
@@ -1517,8 +1554,14 @@ threading/windows/spinlock.lo: threading/windows/$(am__dirstamp) \
threading/windows/$(DEPDIR)/$(am__dirstamp)
threading/windows/semaphore.lo: threading/windows/$(am__dirstamp) \
threading/windows/$(DEPDIR)/$(am__dirstamp)
-utils/windows.lo: utils/$(am__dirstamp) \
- utils/$(DEPDIR)/$(am__dirstamp)
+utils/compat/$(am__dirstamp):
+ @$(MKDIR_P) utils/compat
+ @: > utils/compat/$(am__dirstamp)
+utils/compat/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) utils/compat/$(DEPDIR)
+ @: > utils/compat/$(DEPDIR)/$(am__dirstamp)
+utils/compat/windows.lo: utils/compat/$(am__dirstamp) \
+ utils/compat/$(DEPDIR)/$(am__dirstamp)
utils/leak_detective.lo: utils/$(am__dirstamp) \
utils/$(DEPDIR)/$(am__dirstamp)
utils/integrity_checker.lo: utils/$(am__dirstamp) \
@@ -1568,6 +1611,8 @@ mostlyclean-compile:
-rm -f crypto/hashers/*.lo
-rm -f crypto/iv/*.$(OBJEXT)
-rm -f crypto/iv/*.lo
+ -rm -f crypto/mgf1/*.$(OBJEXT)
+ -rm -f crypto/mgf1/*.lo
-rm -f crypto/prfs/*.$(OBJEXT)
-rm -f crypto/prfs/*.lo
-rm -f crypto/proposal/*.$(OBJEXT)
@@ -1608,6 +1653,8 @@ mostlyclean-compile:
-rm -f threading/windows/*.lo
-rm -f utils/*.$(OBJEXT)
-rm -f utils/*.lo
+ -rm -f utils/compat/*.$(OBJEXT)
+ -rm -f utils/compat/*.lo
-rm -f utils/printf_hook/*.$(OBJEXT)
-rm -f utils/printf_hook/*.lo
-rm -f utils/utils/*.$(OBJEXT)
@@ -1653,9 +1700,12 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@crypto/$(DEPDIR)/prf_plus.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@crypto/$(DEPDIR)/transform.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@crypto/crypters/$(DEPDIR)/crypter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@crypto/hashers/$(DEPDIR)/hash_algorithm_set.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@crypto/hashers/$(DEPDIR)/hasher.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@crypto/iv/$(DEPDIR)/iv_gen_rand.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@crypto/iv/$(DEPDIR)/iv_gen_seq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@crypto/mgf1/$(DEPDIR)/mgf1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@crypto/mgf1/$(DEPDIR)/mgf1_bitspender.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@crypto/prfs/$(DEPDIR)/mac_prf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@crypto/prfs/$(DEPDIR)/prf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@crypto/proposal/$(DEPDIR)/proposal_keywords.Plo@am__quote@
@@ -1721,7 +1771,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/process.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/test.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/utils.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/windows.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@utils/compat/$(DEPDIR)/windows.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@utils/printf_hook/$(DEPDIR)/printf_hook_builtin.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@utils/printf_hook/$(DEPDIR)/printf_hook_glibc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@utils/printf_hook/$(DEPDIR)/printf_hook_vstr.Plo@am__quote@
@@ -1774,6 +1824,7 @@ clean-libtool:
-rm -rf crypto/crypters/.libs crypto/crypters/_libs
-rm -rf crypto/hashers/.libs crypto/hashers/_libs
-rm -rf crypto/iv/.libs crypto/iv/_libs
+ -rm -rf crypto/mgf1/.libs crypto/mgf1/_libs
-rm -rf crypto/prfs/.libs crypto/prfs/_libs
-rm -rf crypto/proposal/.libs crypto/proposal/_libs
-rm -rf crypto/rngs/.libs crypto/rngs/_libs
@@ -1794,6 +1845,7 @@ clean-libtool:
-rm -rf threading/.libs threading/_libs
-rm -rf threading/windows/.libs threading/windows/_libs
-rm -rf utils/.libs utils/_libs
+ -rm -rf utils/compat/.libs utils/compat/_libs
-rm -rf utils/printf_hook/.libs utils/printf_hook/_libs
-rm -rf utils/utils/.libs utils/utils/_libs
install-nobase_strongswan_includeHEADERS: $(nobase_strongswan_include_HEADERS)
@@ -2035,6 +2087,8 @@ distclean-generic:
-rm -f crypto/hashers/$(am__dirstamp)
-rm -f crypto/iv/$(DEPDIR)/$(am__dirstamp)
-rm -f crypto/iv/$(am__dirstamp)
+ -rm -f crypto/mgf1/$(DEPDIR)/$(am__dirstamp)
+ -rm -f crypto/mgf1/$(am__dirstamp)
-rm -f crypto/prfs/$(DEPDIR)/$(am__dirstamp)
-rm -f crypto/prfs/$(am__dirstamp)
-rm -f crypto/proposal/$(DEPDIR)/$(am__dirstamp)
@@ -2075,6 +2129,8 @@ distclean-generic:
-rm -f threading/windows/$(am__dirstamp)
-rm -f utils/$(DEPDIR)/$(am__dirstamp)
-rm -f utils/$(am__dirstamp)
+ -rm -f utils/compat/$(DEPDIR)/$(am__dirstamp)
+ -rm -f utils/compat/$(am__dirstamp)
-rm -f utils/printf_hook/$(DEPDIR)/$(am__dirstamp)
-rm -f utils/printf_hook/$(am__dirstamp)
-rm -f utils/utils/$(DEPDIR)/$(am__dirstamp)
@@ -2094,7 +2150,7 @@ clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-recursive
- -rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) networking/$(DEPDIR) networking/streams/$(DEPDIR) pen/$(DEPDIR) plugins/$(DEPDIR) processing/$(DEPDIR) processing/jobs/$(DEPDIR) resolver/$(DEPDIR) selectors/$(DEPDIR) settings/$(DEPDIR) threading/$(DEPDIR) threading/windows/$(DEPDIR) utils/$(DEPDIR) utils/printf_hook/$(DEPDIR) utils/utils/$(DEPDIR)
+ -rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/mgf1/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) networking/$(DEPDIR) networking/streams/$(DEPDIR) pen/$(DEPDIR) plugins/$(DEPDIR) processing/$(DEPDIR) processing/jobs/$(DEPDIR) resolver/$(DEPDIR) selectors/$(DEPDIR) settings/$(DEPDIR) threading/$(DEPDIR) threading/windows/$(DEPDIR) utils/$(DEPDIR) utils/compat/$(DEPDIR) utils/printf_hook/$(DEPDIR) utils/utils/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -2141,7 +2197,7 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
- -rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) networking/$(DEPDIR) networking/streams/$(DEPDIR) pen/$(DEPDIR) plugins/$(DEPDIR) processing/$(DEPDIR) processing/jobs/$(DEPDIR) resolver/$(DEPDIR) selectors/$(DEPDIR) settings/$(DEPDIR) threading/$(DEPDIR) threading/windows/$(DEPDIR) utils/$(DEPDIR) utils/printf_hook/$(DEPDIR) utils/utils/$(DEPDIR)
+ -rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/mgf1/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) networking/$(DEPDIR) networking/streams/$(DEPDIR) pen/$(DEPDIR) plugins/$(DEPDIR) processing/$(DEPDIR) processing/jobs/$(DEPDIR) resolver/$(DEPDIR) selectors/$(DEPDIR) settings/$(DEPDIR) threading/$(DEPDIR) threading/windows/$(DEPDIR) utils/$(DEPDIR) utils/compat/$(DEPDIR) utils/printf_hook/$(DEPDIR) utils/utils/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
diff --git a/src/libstrongswan/asn1/oid.c b/src/libstrongswan/asn1/oid.c
index b479b0f4b..a750f7fcb 100644
--- a/src/libstrongswan/asn1/oid.c
+++ b/src/libstrongswan/asn1/oid.c
@@ -199,12 +199,12 @@ const oid_t oid_names[] = {
{ 0x02, 187, 0, 7, "ecdsa-with-SHA256" }, /* 186 */
{ 0x03, 188, 0, 7, "ecdsa-with-SHA384" }, /* 187 */
{ 0x04, 0, 0, 7, "ecdsa-with-SHA512" }, /* 188 */
- {0x2B, 391, 1, 0, "" }, /* 189 */
- { 0x06, 305, 1, 1, "dod" }, /* 190 */
+ {0x2B, 413, 1, 0, "" }, /* 189 */
+ { 0x06, 327, 1, 1, "dod" }, /* 190 */
{ 0x01, 0, 1, 2, "internet" }, /* 191 */
- { 0x04, 256, 1, 3, "private" }, /* 192 */
+ { 0x04, 278, 1, 3, "private" }, /* 192 */
{ 0x01, 0, 1, 4, "enterprise" }, /* 193 */
- { 0x82, 210, 1, 5, "" }, /* 194 */
+ { 0x82, 228, 1, 5, "" }, /* 194 */
{ 0x37, 207, 1, 6, "Microsoft" }, /* 195 */
{ 0x0A, 200, 1, 7, "" }, /* 196 */
{ 0x03, 0, 1, 8, "" }, /* 197 */
@@ -219,248 +219,270 @@ const oid_t oid_names[] = {
{ 0x0A, 0, 0, 8, "msApplicationCertPolicies" }, /* 206 */
{ 0xA0, 0, 1, 6, "" }, /* 207 */
{ 0x2A, 0, 1, 7, "ITA" }, /* 208 */
- { 0x01, 0, 0, 8, "strongSwan" }, /* 209 */
- { 0x89, 217, 1, 5, "" }, /* 210 */
- { 0x31, 0, 1, 6, "" }, /* 211 */
- { 0x01, 0, 1, 7, "" }, /* 212 */
- { 0x01, 0, 1, 8, "" }, /* 213 */
- { 0x02, 0, 1, 9, "" }, /* 214 */
- { 0x02, 0, 1, 10, "" }, /* 215 */
- { 0x4B, 0, 0, 11, "TCGID" }, /* 216 */
- { 0xC1, 0, 1, 5, "" }, /* 217 */
- { 0x16, 0, 1, 6, "ntruCryptosystems" }, /* 218 */
- { 0x01, 0, 1, 7, "eess" }, /* 219 */
- { 0x01, 0, 1, 8, "eess1" }, /* 220 */
- { 0x01, 225, 1, 9, "eess1-algs" }, /* 221 */
- { 0x01, 223, 0, 10, "ntru-EESS1v1-SVES" }, /* 222 */
- { 0x02, 224, 0, 10, "ntru-EESS1v1-SVSSA" }, /* 223 */
- { 0x03, 0, 0, 10, "ntru-EESS1v1-NTRUSign" }, /* 224 */
- { 0x02, 255, 1, 9, "eess1-params" }, /* 225 */
- { 0x01, 227, 0, 10, "ees251ep1" }, /* 226 */
- { 0x02, 228, 0, 10, "ees347ep1" }, /* 227 */
- { 0x03, 229, 0, 10, "ees503ep1" }, /* 228 */
- { 0x07, 230, 0, 10, "ees251sp2" }, /* 229 */
- { 0x0C, 231, 0, 10, "ees251ep4" }, /* 230 */
- { 0x0D, 232, 0, 10, "ees251ep5" }, /* 231 */
- { 0x0E, 233, 0, 10, "ees251sp3" }, /* 232 */
- { 0x0F, 234, 0, 10, "ees251sp4" }, /* 233 */
- { 0x10, 235, 0, 10, "ees251sp5" }, /* 234 */
- { 0x11, 236, 0, 10, "ees251sp6" }, /* 235 */
- { 0x12, 237, 0, 10, "ees251sp7" }, /* 236 */
- { 0x13, 238, 0, 10, "ees251sp8" }, /* 237 */
- { 0x14, 239, 0, 10, "ees251sp9" }, /* 238 */
- { 0x22, 240, 0, 10, "ees401ep1" }, /* 239 */
- { 0x23, 241, 0, 10, "ees449ep1" }, /* 240 */
- { 0x24, 242, 0, 10, "ees677ep1" }, /* 241 */
- { 0x25, 243, 0, 10, "ees1087ep2" }, /* 242 */
- { 0x26, 244, 0, 10, "ees541ep1" }, /* 243 */
- { 0x27, 245, 0, 10, "ees613ep1" }, /* 244 */
- { 0x28, 246, 0, 10, "ees887ep1" }, /* 245 */
- { 0x29, 247, 0, 10, "ees1171ep1" }, /* 246 */
- { 0x2A, 248, 0, 10, "ees659ep1" }, /* 247 */
- { 0x2B, 249, 0, 10, "ees761ep1" }, /* 248 */
- { 0x2C, 250, 0, 10, "ees1087ep1" }, /* 249 */
- { 0x2D, 251, 0, 10, "ees1499ep1" }, /* 250 */
- { 0x2E, 252, 0, 10, "ees401ep2" }, /* 251 */
- { 0x2F, 253, 0, 10, "ees439ep1" }, /* 252 */
- { 0x30, 254, 0, 10, "ees593ep1" }, /* 253 */
- { 0x31, 0, 0, 10, "ees743ep1" }, /* 254 */
- { 0x03, 0, 0, 9, "eess1-encodingMethods" }, /* 255 */
- { 0x05, 0, 1, 3, "security" }, /* 256 */
- { 0x05, 0, 1, 4, "mechanisms" }, /* 257 */
- { 0x07, 302, 1, 5, "id-pkix" }, /* 258 */
- { 0x01, 263, 1, 6, "id-pe" }, /* 259 */
- { 0x01, 261, 0, 7, "authorityInfoAccess" }, /* 260 */
- { 0x03, 262, 0, 7, "qcStatements" }, /* 261 */
- { 0x07, 0, 0, 7, "ipAddrBlocks" }, /* 262 */
- { 0x02, 266, 1, 6, "id-qt" }, /* 263 */
- { 0x01, 265, 0, 7, "cps" }, /* 264 */
- { 0x02, 0, 0, 7, "unotice" }, /* 265 */
- { 0x03, 276, 1, 6, "id-kp" }, /* 266 */
- { 0x01, 268, 0, 7, "serverAuth" }, /* 267 */
- { 0x02, 269, 0, 7, "clientAuth" }, /* 268 */
- { 0x03, 270, 0, 7, "codeSigning" }, /* 269 */
- { 0x04, 271, 0, 7, "emailProtection" }, /* 270 */
- { 0x05, 272, 0, 7, "ipsecEndSystem" }, /* 271 */
- { 0x06, 273, 0, 7, "ipsecTunnel" }, /* 272 */
- { 0x07, 274, 0, 7, "ipsecUser" }, /* 273 */
- { 0x08, 275, 0, 7, "timeStamping" }, /* 274 */
- { 0x09, 0, 0, 7, "ocspSigning" }, /* 275 */
- { 0x08, 284, 1, 6, "id-otherNames" }, /* 276 */
- { 0x01, 278, 0, 7, "personalData" }, /* 277 */
- { 0x02, 279, 0, 7, "userGroup" }, /* 278 */
- { 0x03, 280, 0, 7, "id-on-permanentIdentifier" }, /* 279 */
- { 0x04, 281, 0, 7, "id-on-hardwareModuleName" }, /* 280 */
- { 0x05, 282, 0, 7, "xmppAddr" }, /* 281 */
- { 0x06, 283, 0, 7, "id-on-SIM" }, /* 282 */
- { 0x07, 0, 0, 7, "id-on-dnsSRV" }, /* 283 */
- { 0x0A, 289, 1, 6, "id-aca" }, /* 284 */
- { 0x01, 286, 0, 7, "authenticationInfo" }, /* 285 */
- { 0x02, 287, 0, 7, "accessIdentity" }, /* 286 */
- { 0x03, 288, 0, 7, "chargingIdentity" }, /* 287 */
- { 0x04, 0, 0, 7, "group" }, /* 288 */
- { 0x0B, 290, 0, 6, "subjectInfoAccess" }, /* 289 */
- { 0x30, 0, 1, 6, "id-ad" }, /* 290 */
- { 0x01, 299, 1, 7, "ocsp" }, /* 291 */
- { 0x01, 293, 0, 8, "basic" }, /* 292 */
- { 0x02, 294, 0, 8, "nonce" }, /* 293 */
- { 0x03, 295, 0, 8, "crl" }, /* 294 */
- { 0x04, 296, 0, 8, "response" }, /* 295 */
- { 0x05, 297, 0, 8, "noCheck" }, /* 296 */
- { 0x06, 298, 0, 8, "archiveCutoff" }, /* 297 */
- { 0x07, 0, 0, 8, "serviceLocator" }, /* 298 */
- { 0x02, 300, 0, 7, "caIssuers" }, /* 299 */
- { 0x03, 301, 0, 7, "timeStamping" }, /* 300 */
- { 0x05, 0, 0, 7, "caRepository" }, /* 301 */
- { 0x08, 0, 1, 5, "ipsec" }, /* 302 */
- { 0x02, 0, 1, 6, "certificate" }, /* 303 */
- { 0x02, 0, 0, 7, "iKEIntermediate" }, /* 304 */
- { 0x0E, 311, 1, 1, "oiw" }, /* 305 */
- { 0x03, 0, 1, 2, "secsig" }, /* 306 */
- { 0x02, 0, 1, 3, "algorithms" }, /* 307 */
- { 0x07, 309, 0, 4, "des-cbc" }, /* 308 */
- { 0x1A, 310, 0, 4, "sha-1" }, /* 309 */
- { 0x1D, 0, 0, 4, "sha-1WithRSASignature" }, /* 310 */
- { 0x24, 357, 1, 1, "TeleTrusT" }, /* 311 */
- { 0x03, 0, 1, 2, "algorithm" }, /* 312 */
- { 0x03, 0, 1, 3, "signatureAlgorithm" }, /* 313 */
- { 0x01, 318, 1, 4, "rsaSignature" }, /* 314 */
- { 0x02, 316, 0, 5, "rsaSigWithripemd160" }, /* 315 */
- { 0x03, 317, 0, 5, "rsaSigWithripemd128" }, /* 316 */
- { 0x04, 0, 0, 5, "rsaSigWithripemd256" }, /* 317 */
- { 0x02, 0, 1, 4, "ecSign" }, /* 318 */
- { 0x01, 320, 0, 5, "ecSignWithsha1" }, /* 319 */
- { 0x02, 321, 0, 5, "ecSignWithripemd160" }, /* 320 */
- { 0x03, 322, 0, 5, "ecSignWithmd2" }, /* 321 */
- { 0x04, 323, 0, 5, "ecSignWithmd5" }, /* 322 */
- { 0x05, 340, 1, 5, "ttt-ecg" }, /* 323 */
- { 0x01, 328, 1, 6, "fieldType" }, /* 324 */
- { 0x01, 0, 1, 7, "characteristictwoField" }, /* 325 */
- { 0x01, 0, 1, 8, "basisType" }, /* 326 */
- { 0x01, 0, 0, 9, "ipBasis" }, /* 327 */
- { 0x02, 330, 1, 6, "keyType" }, /* 328 */
- { 0x01, 0, 0, 7, "ecgPublicKey" }, /* 329 */
- { 0x03, 331, 0, 6, "curve" }, /* 330 */
- { 0x04, 338, 1, 6, "signatures" }, /* 331 */
- { 0x01, 333, 0, 7, "ecgdsa-with-RIPEMD160" }, /* 332 */
- { 0x02, 334, 0, 7, "ecgdsa-with-SHA1" }, /* 333 */
- { 0x03, 335, 0, 7, "ecgdsa-with-SHA224" }, /* 334 */
- { 0x04, 336, 0, 7, "ecgdsa-with-SHA256" }, /* 335 */
- { 0x05, 337, 0, 7, "ecgdsa-with-SHA384" }, /* 336 */
- { 0x06, 0, 0, 7, "ecgdsa-with-SHA512" }, /* 337 */
- { 0x05, 0, 1, 6, "module" }, /* 338 */
- { 0x01, 0, 0, 7, "1" }, /* 339 */
- { 0x08, 0, 1, 5, "ecStdCurvesAndGeneration" }, /* 340 */
- { 0x01, 0, 1, 6, "ellipticCurve" }, /* 341 */
- { 0x01, 0, 1, 7, "versionOne" }, /* 342 */
- { 0x01, 344, 0, 8, "brainpoolP160r1" }, /* 343 */
- { 0x02, 345, 0, 8, "brainpoolP160t1" }, /* 344 */
- { 0x03, 346, 0, 8, "brainpoolP192r1" }, /* 345 */
- { 0x04, 347, 0, 8, "brainpoolP192t1" }, /* 346 */
- { 0x05, 348, 0, 8, "brainpoolP224r1" }, /* 347 */
- { 0x06, 349, 0, 8, "brainpoolP224t1" }, /* 348 */
- { 0x07, 350, 0, 8, "brainpoolP256r1" }, /* 349 */
- { 0x08, 351, 0, 8, "brainpoolP256t1" }, /* 350 */
- { 0x09, 352, 0, 8, "brainpoolP320r1" }, /* 351 */
- { 0x0A, 353, 0, 8, "brainpoolP320t1" }, /* 352 */
- { 0x0B, 354, 0, 8, "brainpoolP384r1" }, /* 353 */
- { 0x0C, 355, 0, 8, "brainpoolP384t1" }, /* 354 */
- { 0x0D, 356, 0, 8, "brainpoolP512r1" }, /* 355 */
- { 0x0E, 0, 0, 8, "brainpoolP512t1" }, /* 356 */
- { 0x81, 0, 1, 1, "" }, /* 357 */
- { 0x04, 0, 1, 2, "Certicom" }, /* 358 */
- { 0x00, 0, 1, 3, "curve" }, /* 359 */
- { 0x01, 361, 0, 4, "sect163k1" }, /* 360 */
- { 0x02, 362, 0, 4, "sect163r1" }, /* 361 */
- { 0x03, 363, 0, 4, "sect239k1" }, /* 362 */
- { 0x04, 364, 0, 4, "sect113r1" }, /* 363 */
- { 0x05, 365, 0, 4, "sect113r2" }, /* 364 */
- { 0x06, 366, 0, 4, "secp112r1" }, /* 365 */
- { 0x07, 367, 0, 4, "secp112r2" }, /* 366 */
- { 0x08, 368, 0, 4, "secp160r1" }, /* 367 */
- { 0x09, 369, 0, 4, "secp160k1" }, /* 368 */
- { 0x0A, 370, 0, 4, "secp256k1" }, /* 369 */
- { 0x0F, 371, 0, 4, "sect163r2" }, /* 370 */
- { 0x10, 372, 0, 4, "sect283k1" }, /* 371 */
- { 0x11, 373, 0, 4, "sect283r1" }, /* 372 */
- { 0x16, 374, 0, 4, "sect131r1" }, /* 373 */
- { 0x17, 375, 0, 4, "sect131r2" }, /* 374 */
- { 0x18, 376, 0, 4, "sect193r1" }, /* 375 */
- { 0x19, 377, 0, 4, "sect193r2" }, /* 376 */
- { 0x1A, 378, 0, 4, "sect233k1" }, /* 377 */
- { 0x1B, 379, 0, 4, "sect233r1" }, /* 378 */
- { 0x1C, 380, 0, 4, "secp128r1" }, /* 379 */
- { 0x1D, 381, 0, 4, "secp128r2" }, /* 380 */
- { 0x1E, 382, 0, 4, "secp160r2" }, /* 381 */
- { 0x1F, 383, 0, 4, "secp192k1" }, /* 382 */
- { 0x20, 384, 0, 4, "secp224k1" }, /* 383 */
- { 0x21, 385, 0, 4, "secp224r1" }, /* 384 */
- { 0x22, 386, 0, 4, "secp384r1" }, /* 385 */
- { 0x23, 387, 0, 4, "secp521r1" }, /* 386 */
- { 0x24, 388, 0, 4, "sect409k1" }, /* 387 */
- { 0x25, 389, 0, 4, "sect409r1" }, /* 388 */
- { 0x26, 390, 0, 4, "sect571k1" }, /* 389 */
- { 0x27, 0, 0, 4, "sect571r1" }, /* 390 */
- {0x60, 445, 1, 0, "" }, /* 391 */
- { 0x86, 0, 1, 1, "" }, /* 392 */
- { 0x48, 0, 1, 2, "" }, /* 393 */
- { 0x01, 0, 1, 3, "organization" }, /* 394 */
- { 0x65, 421, 1, 4, "gov" }, /* 395 */
- { 0x03, 0, 1, 5, "csor" }, /* 396 */
- { 0x04, 0, 1, 6, "nistalgorithm" }, /* 397 */
- { 0x01, 408, 1, 7, "aes" }, /* 398 */
- { 0x02, 400, 0, 8, "id-aes128-CBC" }, /* 399 */
- { 0x06, 401, 0, 8, "id-aes128-GCM" }, /* 400 */
- { 0x07, 402, 0, 8, "id-aes128-CCM" }, /* 401 */
- { 0x16, 403, 0, 8, "id-aes192-CBC" }, /* 402 */
- { 0x1A, 404, 0, 8, "id-aes192-GCM" }, /* 403 */
- { 0x1B, 405, 0, 8, "id-aes192-CCM" }, /* 404 */
- { 0x2A, 406, 0, 8, "id-aes256-CBC" }, /* 405 */
- { 0x2E, 407, 0, 8, "id-aes256-GCM" }, /* 406 */
- { 0x2F, 0, 0, 8, "id-aes256-CCM" }, /* 407 */
- { 0x02, 0, 1, 7, "hashalgs" }, /* 408 */
- { 0x01, 410, 0, 8, "id-sha256" }, /* 409 */
- { 0x02, 411, 0, 8, "id-sha384" }, /* 410 */
- { 0x03, 412, 0, 8, "id-sha512" }, /* 411 */
- { 0x04, 413, 0, 8, "id-sha224" }, /* 412 */
- { 0x05, 414, 0, 8, "id-sha512-224" }, /* 413 */
- { 0x06, 415, 0, 8, "id-sha512-256" }, /* 414 */
- { 0x07, 416, 0, 8, "id-sha3-224" }, /* 415 */
- { 0x08, 417, 0, 8, "id-sha3-256" }, /* 416 */
- { 0x09, 418, 0, 8, "id-sha3-384" }, /* 417 */
- { 0x0A, 419, 0, 8, "id-sha3-512" }, /* 418 */
- { 0x0B, 420, 0, 8, "id-shake128" }, /* 419 */
- { 0x0C, 0, 0, 8, "id-shake256" }, /* 420 */
- { 0x86, 0, 1, 4, "" }, /* 421 */
- { 0xf8, 0, 1, 5, "" }, /* 422 */
- { 0x42, 435, 1, 6, "netscape" }, /* 423 */
- { 0x01, 430, 1, 7, "" }, /* 424 */
- { 0x01, 426, 0, 8, "nsCertType" }, /* 425 */
- { 0x03, 427, 0, 8, "nsRevocationUrl" }, /* 426 */
- { 0x04, 428, 0, 8, "nsCaRevocationUrl" }, /* 427 */
- { 0x08, 429, 0, 8, "nsCaPolicyUrl" }, /* 428 */
- { 0x0d, 0, 0, 8, "nsComment" }, /* 429 */
- { 0x03, 433, 1, 7, "directory" }, /* 430 */
- { 0x01, 0, 1, 8, "" }, /* 431 */
- { 0x03, 0, 0, 9, "employeeNumber" }, /* 432 */
- { 0x04, 0, 1, 7, "policy" }, /* 433 */
- { 0x01, 0, 0, 8, "nsSGC" }, /* 434 */
- { 0x45, 0, 1, 6, "verisign" }, /* 435 */
- { 0x01, 0, 1, 7, "pki" }, /* 436 */
- { 0x09, 0, 1, 8, "attributes" }, /* 437 */
- { 0x02, 439, 0, 9, "messageType" }, /* 438 */
- { 0x03, 440, 0, 9, "pkiStatus" }, /* 439 */
- { 0x04, 441, 0, 9, "failInfo" }, /* 440 */
- { 0x05, 442, 0, 9, "senderNonce" }, /* 441 */
- { 0x06, 443, 0, 9, "recipientNonce" }, /* 442 */
- { 0x07, 444, 0, 9, "transID" }, /* 443 */
- { 0x08, 0, 0, 9, "extensionReq" }, /* 444 */
- {0x67, 0, 1, 0, "" }, /* 445 */
- { 0x81, 0, 1, 1, "" }, /* 446 */
- { 0x05, 0, 1, 2, "" }, /* 447 */
- { 0x02, 0, 1, 3, "tcg-attribute" }, /* 448 */
- { 0x01, 450, 0, 4, "tcg-at-tpmManufacturer" }, /* 449 */
- { 0x02, 451, 0, 4, "tcg-at-tpmModel" }, /* 450 */
- { 0x03, 452, 0, 4, "tcg-at-tpmVersion" }, /* 451 */
- { 0x0F, 0, 0, 4, "tcg-at-tpmIdLabel" } /* 452 */
+ { 0x01, 210, 0, 8, "strongSwan" }, /* 209 */
+ { 0x02, 211, 0, 8, "cps" }, /* 210 */
+ { 0x03, 212, 0, 8, "e-voting" }, /* 211 */
+ { 0x05, 0, 1, 8, "BLISS" }, /* 212 */
+ { 0x01, 215, 1, 9, "keyType" }, /* 213 */
+ { 0x01, 0, 0, 10, "blissPublicKey" }, /* 214 */
+ { 0x02, 224, 1, 9, "parameters" }, /* 215 */
+ { 0x01, 217, 0, 10, "BLISS-I" }, /* 216 */
+ { 0x02, 218, 0, 10, "BLISS-II" }, /* 217 */
+ { 0x03, 219, 0, 10, "BLISS-III" }, /* 218 */
+ { 0x04, 220, 0, 10, "BLISS-IV" }, /* 219 */
+ { 0x05, 221, 0, 10, "BLISS-B-I" }, /* 220 */
+ { 0x06, 222, 0, 10, "BLISS-B-II" }, /* 221 */
+ { 0x07, 223, 0, 10, "BLISS-B-III" }, /* 222 */
+ { 0x08, 0, 0, 10, "BLISS-B-IV" }, /* 223 */
+ { 0x03, 0, 1, 9, "blissSigType" }, /* 224 */
+ { 0x01, 226, 0, 10, "BLISS-with-SHA512" }, /* 225 */
+ { 0x02, 227, 0, 10, "BLISS-with-SHA384" }, /* 226 */
+ { 0x03, 0, 0, 10, "BLISS-with-SHA256" }, /* 227 */
+ { 0x89, 235, 1, 5, "" }, /* 228 */
+ { 0x31, 0, 1, 6, "" }, /* 229 */
+ { 0x01, 0, 1, 7, "" }, /* 230 */
+ { 0x01, 0, 1, 8, "" }, /* 231 */
+ { 0x02, 0, 1, 9, "" }, /* 232 */
+ { 0x02, 0, 1, 10, "" }, /* 233 */
+ { 0x4B, 0, 0, 11, "TCGID" }, /* 234 */
+ { 0x97, 239, 1, 5, "" }, /* 235 */
+ { 0x55, 0, 1, 6, "" }, /* 236 */
+ { 0x01, 0, 1, 7, "" }, /* 237 */
+ { 0x02, 0, 0, 8, "blowfish-cbc" }, /* 238 */
+ { 0xC1, 0, 1, 5, "" }, /* 239 */
+ { 0x16, 0, 1, 6, "ntruCryptosystems" }, /* 240 */
+ { 0x01, 0, 1, 7, "eess" }, /* 241 */
+ { 0x01, 0, 1, 8, "eess1" }, /* 242 */
+ { 0x01, 247, 1, 9, "eess1-algs" }, /* 243 */
+ { 0x01, 245, 0, 10, "ntru-EESS1v1-SVES" }, /* 244 */
+ { 0x02, 246, 0, 10, "ntru-EESS1v1-SVSSA" }, /* 245 */
+ { 0x03, 0, 0, 10, "ntru-EESS1v1-NTRUSign" }, /* 246 */
+ { 0x02, 277, 1, 9, "eess1-params" }, /* 247 */
+ { 0x01, 249, 0, 10, "ees251ep1" }, /* 248 */
+ { 0x02, 250, 0, 10, "ees347ep1" }, /* 249 */
+ { 0x03, 251, 0, 10, "ees503ep1" }, /* 250 */
+ { 0x07, 252, 0, 10, "ees251sp2" }, /* 251 */
+ { 0x0C, 253, 0, 10, "ees251ep4" }, /* 252 */
+ { 0x0D, 254, 0, 10, "ees251ep5" }, /* 253 */
+ { 0x0E, 255, 0, 10, "ees251sp3" }, /* 254 */
+ { 0x0F, 256, 0, 10, "ees251sp4" }, /* 255 */
+ { 0x10, 257, 0, 10, "ees251sp5" }, /* 256 */
+ { 0x11, 258, 0, 10, "ees251sp6" }, /* 257 */
+ { 0x12, 259, 0, 10, "ees251sp7" }, /* 258 */
+ { 0x13, 260, 0, 10, "ees251sp8" }, /* 259 */
+ { 0x14, 261, 0, 10, "ees251sp9" }, /* 260 */
+ { 0x22, 262, 0, 10, "ees401ep1" }, /* 261 */
+ { 0x23, 263, 0, 10, "ees449ep1" }, /* 262 */
+ { 0x24, 264, 0, 10, "ees677ep1" }, /* 263 */
+ { 0x25, 265, 0, 10, "ees1087ep2" }, /* 264 */
+ { 0x26, 266, 0, 10, "ees541ep1" }, /* 265 */
+ { 0x27, 267, 0, 10, "ees613ep1" }, /* 266 */
+ { 0x28, 268, 0, 10, "ees887ep1" }, /* 267 */
+ { 0x29, 269, 0, 10, "ees1171ep1" }, /* 268 */
+ { 0x2A, 270, 0, 10, "ees659ep1" }, /* 269 */
+ { 0x2B, 271, 0, 10, "ees761ep1" }, /* 270 */
+ { 0x2C, 272, 0, 10, "ees1087ep1" }, /* 271 */
+ { 0x2D, 273, 0, 10, "ees1499ep1" }, /* 272 */
+ { 0x2E, 274, 0, 10, "ees401ep2" }, /* 273 */
+ { 0x2F, 275, 0, 10, "ees439ep1" }, /* 274 */
+ { 0x30, 276, 0, 10, "ees593ep1" }, /* 275 */
+ { 0x31, 0, 0, 10, "ees743ep1" }, /* 276 */
+ { 0x03, 0, 0, 9, "eess1-encodingMethods" }, /* 277 */
+ { 0x05, 0, 1, 3, "security" }, /* 278 */
+ { 0x05, 0, 1, 4, "mechanisms" }, /* 279 */
+ { 0x07, 324, 1, 5, "id-pkix" }, /* 280 */
+ { 0x01, 285, 1, 6, "id-pe" }, /* 281 */
+ { 0x01, 283, 0, 7, "authorityInfoAccess" }, /* 282 */
+ { 0x03, 284, 0, 7, "qcStatements" }, /* 283 */
+ { 0x07, 0, 0, 7, "ipAddrBlocks" }, /* 284 */
+ { 0x02, 288, 1, 6, "id-qt" }, /* 285 */
+ { 0x01, 287, 0, 7, "cps" }, /* 286 */
+ { 0x02, 0, 0, 7, "unotice" }, /* 287 */
+ { 0x03, 298, 1, 6, "id-kp" }, /* 288 */
+ { 0x01, 290, 0, 7, "serverAuth" }, /* 289 */
+ { 0x02, 291, 0, 7, "clientAuth" }, /* 290 */
+ { 0x03, 292, 0, 7, "codeSigning" }, /* 291 */
+ { 0x04, 293, 0, 7, "emailProtection" }, /* 292 */
+ { 0x05, 294, 0, 7, "ipsecEndSystem" }, /* 293 */
+ { 0x06, 295, 0, 7, "ipsecTunnel" }, /* 294 */
+ { 0x07, 296, 0, 7, "ipsecUser" }, /* 295 */
+ { 0x08, 297, 0, 7, "timeStamping" }, /* 296 */
+ { 0x09, 0, 0, 7, "ocspSigning" }, /* 297 */
+ { 0x08, 306, 1, 6, "id-otherNames" }, /* 298 */
+ { 0x01, 300, 0, 7, "personalData" }, /* 299 */
+ { 0x02, 301, 0, 7, "userGroup" }, /* 300 */
+ { 0x03, 302, 0, 7, "id-on-permanentIdentifier" }, /* 301 */
+ { 0x04, 303, 0, 7, "id-on-hardwareModuleName" }, /* 302 */
+ { 0x05, 304, 0, 7, "xmppAddr" }, /* 303 */
+ { 0x06, 305, 0, 7, "id-on-SIM" }, /* 304 */
+ { 0x07, 0, 0, 7, "id-on-dnsSRV" }, /* 305 */
+ { 0x0A, 311, 1, 6, "id-aca" }, /* 306 */
+ { 0x01, 308, 0, 7, "authenticationInfo" }, /* 307 */
+ { 0x02, 309, 0, 7, "accessIdentity" }, /* 308 */
+ { 0x03, 310, 0, 7, "chargingIdentity" }, /* 309 */
+ { 0x04, 0, 0, 7, "group" }, /* 310 */
+ { 0x0B, 312, 0, 6, "subjectInfoAccess" }, /* 311 */
+ { 0x30, 0, 1, 6, "id-ad" }, /* 312 */
+ { 0x01, 321, 1, 7, "ocsp" }, /* 313 */
+ { 0x01, 315, 0, 8, "basic" }, /* 314 */
+ { 0x02, 316, 0, 8, "nonce" }, /* 315 */
+ { 0x03, 317, 0, 8, "crl" }, /* 316 */
+ { 0x04, 318, 0, 8, "response" }, /* 317 */
+ { 0x05, 319, 0, 8, "noCheck" }, /* 318 */
+ { 0x06, 320, 0, 8, "archiveCutoff" }, /* 319 */
+ { 0x07, 0, 0, 8, "serviceLocator" }, /* 320 */
+ { 0x02, 322, 0, 7, "caIssuers" }, /* 321 */
+ { 0x03, 323, 0, 7, "timeStamping" }, /* 322 */
+ { 0x05, 0, 0, 7, "caRepository" }, /* 323 */
+ { 0x08, 0, 1, 5, "ipsec" }, /* 324 */
+ { 0x02, 0, 1, 6, "certificate" }, /* 325 */
+ { 0x02, 0, 0, 7, "iKEIntermediate" }, /* 326 */
+ { 0x0E, 333, 1, 1, "oiw" }, /* 327 */
+ { 0x03, 0, 1, 2, "secsig" }, /* 328 */
+ { 0x02, 0, 1, 3, "algorithms" }, /* 329 */
+ { 0x07, 331, 0, 4, "des-cbc" }, /* 330 */
+ { 0x1A, 332, 0, 4, "sha-1" }, /* 331 */
+ { 0x1D, 0, 0, 4, "sha-1WithRSASignature" }, /* 332 */
+ { 0x24, 379, 1, 1, "TeleTrusT" }, /* 333 */
+ { 0x03, 0, 1, 2, "algorithm" }, /* 334 */
+ { 0x03, 0, 1, 3, "signatureAlgorithm" }, /* 335 */
+ { 0x01, 340, 1, 4, "rsaSignature" }, /* 336 */
+ { 0x02, 338, 0, 5, "rsaSigWithripemd160" }, /* 337 */
+ { 0x03, 339, 0, 5, "rsaSigWithripemd128" }, /* 338 */
+ { 0x04, 0, 0, 5, "rsaSigWithripemd256" }, /* 339 */
+ { 0x02, 0, 1, 4, "ecSign" }, /* 340 */
+ { 0x01, 342, 0, 5, "ecSignWithsha1" }, /* 341 */
+ { 0x02, 343, 0, 5, "ecSignWithripemd160" }, /* 342 */
+ { 0x03, 344, 0, 5, "ecSignWithmd2" }, /* 343 */
+ { 0x04, 345, 0, 5, "ecSignWithmd5" }, /* 344 */
+ { 0x05, 362, 1, 5, "ttt-ecg" }, /* 345 */
+ { 0x01, 350, 1, 6, "fieldType" }, /* 346 */
+ { 0x01, 0, 1, 7, "characteristictwoField" }, /* 347 */
+ { 0x01, 0, 1, 8, "basisType" }, /* 348 */
+ { 0x01, 0, 0, 9, "ipBasis" }, /* 349 */
+ { 0x02, 352, 1, 6, "keyType" }, /* 350 */
+ { 0x01, 0, 0, 7, "ecgPublicKey" }, /* 351 */
+ { 0x03, 353, 0, 6, "curve" }, /* 352 */
+ { 0x04, 360, 1, 6, "signatures" }, /* 353 */
+ { 0x01, 355, 0, 7, "ecgdsa-with-RIPEMD160" }, /* 354 */
+ { 0x02, 356, 0, 7, "ecgdsa-with-SHA1" }, /* 355 */
+ { 0x03, 357, 0, 7, "ecgdsa-with-SHA224" }, /* 356 */
+ { 0x04, 358, 0, 7, "ecgdsa-with-SHA256" }, /* 357 */
+ { 0x05, 359, 0, 7, "ecgdsa-with-SHA384" }, /* 358 */
+ { 0x06, 0, 0, 7, "ecgdsa-with-SHA512" }, /* 359 */
+ { 0x05, 0, 1, 6, "module" }, /* 360 */
+ { 0x01, 0, 0, 7, "1" }, /* 361 */
+ { 0x08, 0, 1, 5, "ecStdCurvesAndGeneration" }, /* 362 */
+ { 0x01, 0, 1, 6, "ellipticCurve" }, /* 363 */
+ { 0x01, 0, 1, 7, "versionOne" }, /* 364 */
+ { 0x01, 366, 0, 8, "brainpoolP160r1" }, /* 365 */
+ { 0x02, 367, 0, 8, "brainpoolP160t1" }, /* 366 */
+ { 0x03, 368, 0, 8, "brainpoolP192r1" }, /* 367 */
+ { 0x04, 369, 0, 8, "brainpoolP192t1" }, /* 368 */
+ { 0x05, 370, 0, 8, "brainpoolP224r1" }, /* 369 */
+ { 0x06, 371, 0, 8, "brainpoolP224t1" }, /* 370 */
+ { 0x07, 372, 0, 8, "brainpoolP256r1" }, /* 371 */
+ { 0x08, 373, 0, 8, "brainpoolP256t1" }, /* 372 */
+ { 0x09, 374, 0, 8, "brainpoolP320r1" }, /* 373 */
+ { 0x0A, 375, 0, 8, "brainpoolP320t1" }, /* 374 */
+ { 0x0B, 376, 0, 8, "brainpoolP384r1" }, /* 375 */
+ { 0x0C, 377, 0, 8, "brainpoolP384t1" }, /* 376 */
+ { 0x0D, 378, 0, 8, "brainpoolP512r1" }, /* 377 */
+ { 0x0E, 0, 0, 8, "brainpoolP512t1" }, /* 378 */
+ { 0x81, 0, 1, 1, "" }, /* 379 */
+ { 0x04, 0, 1, 2, "Certicom" }, /* 380 */
+ { 0x00, 0, 1, 3, "curve" }, /* 381 */
+ { 0x01, 383, 0, 4, "sect163k1" }, /* 382 */
+ { 0x02, 384, 0, 4, "sect163r1" }, /* 383 */
+ { 0x03, 385, 0, 4, "sect239k1" }, /* 384 */
+ { 0x04, 386, 0, 4, "sect113r1" }, /* 385 */
+ { 0x05, 387, 0, 4, "sect113r2" }, /* 386 */
+ { 0x06, 388, 0, 4, "secp112r1" }, /* 387 */
+ { 0x07, 389, 0, 4, "secp112r2" }, /* 388 */
+ { 0x08, 390, 0, 4, "secp160r1" }, /* 389 */
+ { 0x09, 391, 0, 4, "secp160k1" }, /* 390 */
+ { 0x0A, 392, 0, 4, "secp256k1" }, /* 391 */
+ { 0x0F, 393, 0, 4, "sect163r2" }, /* 392 */
+ { 0x10, 394, 0, 4, "sect283k1" }, /* 393 */
+ { 0x11, 395, 0, 4, "sect283r1" }, /* 394 */
+ { 0x16, 396, 0, 4, "sect131r1" }, /* 395 */
+ { 0x17, 397, 0, 4, "sect131r2" }, /* 396 */
+ { 0x18, 398, 0, 4, "sect193r1" }, /* 397 */
+ { 0x19, 399, 0, 4, "sect193r2" }, /* 398 */
+ { 0x1A, 400, 0, 4, "sect233k1" }, /* 399 */
+ { 0x1B, 401, 0, 4, "sect233r1" }, /* 400 */
+ { 0x1C, 402, 0, 4, "secp128r1" }, /* 401 */
+ { 0x1D, 403, 0, 4, "secp128r2" }, /* 402 */
+ { 0x1E, 404, 0, 4, "secp160r2" }, /* 403 */
+ { 0x1F, 405, 0, 4, "secp192k1" }, /* 404 */
+ { 0x20, 406, 0, 4, "secp224k1" }, /* 405 */
+ { 0x21, 407, 0, 4, "secp224r1" }, /* 406 */
+ { 0x22, 408, 0, 4, "secp384r1" }, /* 407 */
+ { 0x23, 409, 0, 4, "secp521r1" }, /* 408 */
+ { 0x24, 410, 0, 4, "sect409k1" }, /* 409 */
+ { 0x25, 411, 0, 4, "sect409r1" }, /* 410 */
+ { 0x26, 412, 0, 4, "sect571k1" }, /* 411 */
+ { 0x27, 0, 0, 4, "sect571r1" }, /* 412 */
+ {0x60, 467, 1, 0, "" }, /* 413 */
+ { 0x86, 0, 1, 1, "" }, /* 414 */
+ { 0x48, 0, 1, 2, "" }, /* 415 */
+ { 0x01, 0, 1, 3, "organization" }, /* 416 */
+ { 0x65, 443, 1, 4, "gov" }, /* 417 */
+ { 0x03, 0, 1, 5, "csor" }, /* 418 */
+ { 0x04, 0, 1, 6, "nistalgorithm" }, /* 419 */
+ { 0x01, 430, 1, 7, "aes" }, /* 420 */
+ { 0x02, 422, 0, 8, "id-aes128-CBC" }, /* 421 */
+ { 0x06, 423, 0, 8, "id-aes128-GCM" }, /* 422 */
+ { 0x07, 424, 0, 8, "id-aes128-CCM" }, /* 423 */
+ { 0x16, 425, 0, 8, "id-aes192-CBC" }, /* 424 */
+ { 0x1A, 426, 0, 8, "id-aes192-GCM" }, /* 425 */
+ { 0x1B, 427, 0, 8, "id-aes192-CCM" }, /* 426 */
+ { 0x2A, 428, 0, 8, "id-aes256-CBC" }, /* 427 */
+ { 0x2E, 429, 0, 8, "id-aes256-GCM" }, /* 428 */
+ { 0x2F, 0, 0, 8, "id-aes256-CCM" }, /* 429 */
+ { 0x02, 0, 1, 7, "hashalgs" }, /* 430 */
+ { 0x01, 432, 0, 8, "id-sha256" }, /* 431 */
+ { 0x02, 433, 0, 8, "id-sha384" }, /* 432 */
+ { 0x03, 434, 0, 8, "id-sha512" }, /* 433 */
+ { 0x04, 435, 0, 8, "id-sha224" }, /* 434 */
+ { 0x05, 436, 0, 8, "id-sha512-224" }, /* 435 */
+ { 0x06, 437, 0, 8, "id-sha512-256" }, /* 436 */
+ { 0x07, 438, 0, 8, "id-sha3-224" }, /* 437 */
+ { 0x08, 439, 0, 8, "id-sha3-256" }, /* 438 */
+ { 0x09, 440, 0, 8, "id-sha3-384" }, /* 439 */
+ { 0x0A, 441, 0, 8, "id-sha3-512" }, /* 440 */
+ { 0x0B, 442, 0, 8, "id-shake128" }, /* 441 */
+ { 0x0C, 0, 0, 8, "id-shake256" }, /* 442 */
+ { 0x86, 0, 1, 4, "" }, /* 443 */
+ { 0xf8, 0, 1, 5, "" }, /* 444 */
+ { 0x42, 457, 1, 6, "netscape" }, /* 445 */
+ { 0x01, 452, 1, 7, "" }, /* 446 */
+ { 0x01, 448, 0, 8, "nsCertType" }, /* 447 */
+ { 0x03, 449, 0, 8, "nsRevocationUrl" }, /* 448 */
+ { 0x04, 450, 0, 8, "nsCaRevocationUrl" }, /* 449 */
+ { 0x08, 451, 0, 8, "nsCaPolicyUrl" }, /* 450 */
+ { 0x0d, 0, 0, 8, "nsComment" }, /* 451 */
+ { 0x03, 455, 1, 7, "directory" }, /* 452 */
+ { 0x01, 0, 1, 8, "" }, /* 453 */
+ { 0x03, 0, 0, 9, "employeeNumber" }, /* 454 */
+ { 0x04, 0, 1, 7, "policy" }, /* 455 */
+ { 0x01, 0, 0, 8, "nsSGC" }, /* 456 */
+ { 0x45, 0, 1, 6, "verisign" }, /* 457 */
+ { 0x01, 0, 1, 7, "pki" }, /* 458 */
+ { 0x09, 0, 1, 8, "attributes" }, /* 459 */
+ { 0x02, 461, 0, 9, "messageType" }, /* 460 */
+ { 0x03, 462, 0, 9, "pkiStatus" }, /* 461 */
+ { 0x04, 463, 0, 9, "failInfo" }, /* 462 */
+ { 0x05, 464, 0, 9, "senderNonce" }, /* 463 */
+ { 0x06, 465, 0, 9, "recipientNonce" }, /* 464 */
+ { 0x07, 466, 0, 9, "transID" }, /* 465 */
+ { 0x08, 0, 0, 9, "extensionReq" }, /* 466 */
+ {0x67, 0, 1, 0, "" }, /* 467 */
+ { 0x81, 0, 1, 1, "" }, /* 468 */
+ { 0x05, 0, 1, 2, "" }, /* 469 */
+ { 0x02, 0, 1, 3, "tcg-attribute" }, /* 470 */
+ { 0x01, 472, 0, 4, "tcg-at-tpmManufacturer" }, /* 471 */
+ { 0x02, 473, 0, 4, "tcg-at-tpmModel" }, /* 472 */
+ { 0x03, 474, 0, 4, "tcg-at-tpmVersion" }, /* 473 */
+ { 0x0F, 0, 0, 4, "tcg-at-tpmIdLabel" } /* 474 */
};
diff --git a/src/libstrongswan/asn1/oid.h b/src/libstrongswan/asn1/oid.h
index 0933f236a..0f7c5d644 100644
--- a/src/libstrongswan/asn1/oid.h
+++ b/src/libstrongswan/asn1/oid.h
@@ -141,99 +141,112 @@ extern const oid_t oid_names[];
#define OID_MS_SMARTCARD_LOGON 202
#define OID_USER_PRINCIPAL_NAME 203
#define OID_STRONGSWAN 209
-#define OID_TCGID 216
-#define OID_AUTHORITY_INFO_ACCESS 260
-#define OID_IP_ADDR_BLOCKS 262
-#define OID_POLICY_QUALIFIER_CPS 264
-#define OID_POLICY_QUALIFIER_UNOTICE 265
-#define OID_SERVER_AUTH 267
-#define OID_CLIENT_AUTH 268
-#define OID_OCSP_SIGNING 275
-#define OID_XMPP_ADDR 281
-#define OID_AUTHENTICATION_INFO 285
-#define OID_ACCESS_IDENTITY 286
-#define OID_CHARGING_IDENTITY 287
-#define OID_GROUP 288
-#define OID_OCSP 291
-#define OID_BASIC 292
-#define OID_NONCE 293
-#define OID_CRL 294
-#define OID_RESPONSE 295
-#define OID_NO_CHECK 296
-#define OID_ARCHIVE_CUTOFF 297
-#define OID_SERVICE_LOCATOR 298
-#define OID_CA_ISSUERS 299
-#define OID_IKE_INTERMEDIATE 304
-#define OID_DES_CBC 308
-#define OID_SHA1 309
-#define OID_SHA1_WITH_RSA_OIW 310
-#define OID_ECGDSA_PUBKEY 329
-#define OID_ECGDSA_SIG_WITH_RIPEMD160 332
-#define OID_ECGDSA_SIG_WITH_SHA1 333
-#define OID_ECGDSA_SIG_WITH_SHA224 334
-#define OID_ECGDSA_SIG_WITH_SHA256 335
-#define OID_ECGDSA_SIG_WITH_SHA384 336
-#define OID_ECGDSA_SIG_WITH_SHA512 337
-#define OID_SECT163K1 360
-#define OID_SECT163R1 361
-#define OID_SECT239K1 362
-#define OID_SECT113R1 363
-#define OID_SECT113R2 364
-#define OID_SECT112R1 365
-#define OID_SECT112R2 366
-#define OID_SECT160R1 367
-#define OID_SECT160K1 368
-#define OID_SECT256K1 369
-#define OID_SECT163R2 370
-#define OID_SECT283K1 371
-#define OID_SECT283R1 372
-#define OID_SECT131R1 373
-#define OID_SECT131R2 374
-#define OID_SECT193R1 375
-#define OID_SECT193R2 376
-#define OID_SECT233K1 377
-#define OID_SECT233R1 378
-#define OID_SECT128R1 379
-#define OID_SECT128R2 380
-#define OID_SECT160R2 381
-#define OID_SECT192K1 382
-#define OID_SECT224K1 383
-#define OID_SECT224R1 384
-#define OID_SECT384R1 385
-#define OID_SECT521R1 386
-#define OID_SECT409K1 387
-#define OID_SECT409R1 388
-#define OID_SECT571K1 389
-#define OID_SECT571R1 390
-#define OID_AES128_CBC 399
-#define OID_AES128_GCM 400
-#define OID_AES128_CCM 401
-#define OID_AES192_CBC 402
-#define OID_AES192_GCM 403
-#define OID_AES192_CCM 404
-#define OID_AES256_CBC 405
-#define OID_AES256_GCM 406
-#define OID_AES256_CCM 407
-#define OID_SHA256 409
-#define OID_SHA384 410
-#define OID_SHA512 411
-#define OID_SHA224 412
-#define OID_NS_REVOCATION_URL 426
-#define OID_NS_CA_REVOCATION_URL 427
-#define OID_NS_CA_POLICY_URL 428
-#define OID_NS_COMMENT 429
-#define OID_EMPLOYEE_NUMBER 432
-#define OID_PKI_MESSAGE_TYPE 438
-#define OID_PKI_STATUS 439
-#define OID_PKI_FAIL_INFO 440
-#define OID_PKI_SENDER_NONCE 441
-#define OID_PKI_RECIPIENT_NONCE 442
-#define OID_PKI_TRANS_ID 443
-#define OID_TPM_MANUFACTURER 449
-#define OID_TPM_MODEL 450
-#define OID_TPM_VERSION 451
-#define OID_TPM_ID_LABEL 452
+#define OID_BLISS_PUBLICKEY 214
+#define OID_BLISS_I 216
+#define OID_BLISS_II 217
+#define OID_BLISS_III 218
+#define OID_BLISS_IV 219
+#define OID_BLISS_B_I 220
+#define OID_BLISS_B_II 221
+#define OID_BLISS_B_III 222
+#define OID_BLISS_B_IV 223
+#define OID_BLISS_WITH_SHA512 225
+#define OID_BLISS_WITH_SHA384 226
+#define OID_BLISS_WITH_SHA256 227
+#define OID_TCGID 234
+#define OID_BLOWFISH_CBC 238
+#define OID_AUTHORITY_INFO_ACCESS 282
+#define OID_IP_ADDR_BLOCKS 284
+#define OID_POLICY_QUALIFIER_CPS 286
+#define OID_POLICY_QUALIFIER_UNOTICE 287
+#define OID_SERVER_AUTH 289
+#define OID_CLIENT_AUTH 290
+#define OID_OCSP_SIGNING 297
+#define OID_XMPP_ADDR 303
+#define OID_AUTHENTICATION_INFO 307
+#define OID_ACCESS_IDENTITY 308
+#define OID_CHARGING_IDENTITY 309
+#define OID_GROUP 310
+#define OID_OCSP 313
+#define OID_BASIC 314
+#define OID_NONCE 315
+#define OID_CRL 316
+#define OID_RESPONSE 317
+#define OID_NO_CHECK 318
+#define OID_ARCHIVE_CUTOFF 319
+#define OID_SERVICE_LOCATOR 320
+#define OID_CA_ISSUERS 321
+#define OID_IKE_INTERMEDIATE 326
+#define OID_DES_CBC 330
+#define OID_SHA1 331
+#define OID_SHA1_WITH_RSA_OIW 332
+#define OID_ECGDSA_PUBKEY 351
+#define OID_ECGDSA_SIG_WITH_RIPEMD160 354
+#define OID_ECGDSA_SIG_WITH_SHA1 355
+#define OID_ECGDSA_SIG_WITH_SHA224 356
+#define OID_ECGDSA_SIG_WITH_SHA256 357
+#define OID_ECGDSA_SIG_WITH_SHA384 358
+#define OID_ECGDSA_SIG_WITH_SHA512 359
+#define OID_SECT163K1 382
+#define OID_SECT163R1 383
+#define OID_SECT239K1 384
+#define OID_SECT113R1 385
+#define OID_SECT113R2 386
+#define OID_SECT112R1 387
+#define OID_SECT112R2 388
+#define OID_SECT160R1 389
+#define OID_SECT160K1 390
+#define OID_SECT256K1 391
+#define OID_SECT163R2 392
+#define OID_SECT283K1 393
+#define OID_SECT283R1 394
+#define OID_SECT131R1 395
+#define OID_SECT131R2 396
+#define OID_SECT193R1 397
+#define OID_SECT193R2 398
+#define OID_SECT233K1 399
+#define OID_SECT233R1 400
+#define OID_SECT128R1 401
+#define OID_SECT128R2 402
+#define OID_SECT160R2 403
+#define OID_SECT192K1 404
+#define OID_SECT224K1 405
+#define OID_SECT224R1 406
+#define OID_SECT384R1 407
+#define OID_SECT521R1 408
+#define OID_SECT409K1 409
+#define OID_SECT409R1 410
+#define OID_SECT571K1 411
+#define OID_SECT571R1 412
+#define OID_AES128_CBC 421
+#define OID_AES128_GCM 422
+#define OID_AES128_CCM 423
+#define OID_AES192_CBC 424
+#define OID_AES192_GCM 425
+#define OID_AES192_CCM 426
+#define OID_AES256_CBC 427
+#define OID_AES256_GCM 428
+#define OID_AES256_CCM 429
+#define OID_SHA256 431
+#define OID_SHA384 432
+#define OID_SHA512 433
+#define OID_SHA224 434
+#define OID_NS_REVOCATION_URL 448
+#define OID_NS_CA_REVOCATION_URL 449
+#define OID_NS_CA_POLICY_URL 450
+#define OID_NS_COMMENT 451
+#define OID_EMPLOYEE_NUMBER 454
+#define OID_PKI_MESSAGE_TYPE 460
+#define OID_PKI_STATUS 461
+#define OID_PKI_FAIL_INFO 462
+#define OID_PKI_SENDER_NONCE 463
+#define OID_PKI_RECIPIENT_NONCE 464
+#define OID_PKI_TRANS_ID 465
+#define OID_TPM_MANUFACTURER 471
+#define OID_TPM_MODEL 472
+#define OID_TPM_VERSION 473
+#define OID_TPM_ID_LABEL 474
-#define OID_MAX 453
+#define OID_MAX 475
#endif /* OID_H_ */
diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt
index e545188d4..919d24c43 100644
--- a/src/libstrongswan/asn1/oid.txt
+++ b/src/libstrongswan/asn1/oid.txt
@@ -208,6 +208,24 @@
0xA0 ""
0x2A "ITA"
0x01 "strongSwan" OID_STRONGSWAN
+ 0x02 "cps"
+ 0x03 "e-voting"
+ 0x05 "BLISS"
+ 0x01 "keyType"
+ 0x01 "blissPublicKey" OID_BLISS_PUBLICKEY
+ 0x02 "parameters"
+ 0x01 "BLISS-I" OID_BLISS_I
+ 0x02 "BLISS-II" OID_BLISS_II
+ 0x03 "BLISS-III" OID_BLISS_III
+ 0x04 "BLISS-IV" OID_BLISS_IV
+ 0x05 "BLISS-B-I" OID_BLISS_B_I
+ 0x06 "BLISS-B-II" OID_BLISS_B_II
+ 0x07 "BLISS-B-III" OID_BLISS_B_III
+ 0x08 "BLISS-B-IV" OID_BLISS_B_IV
+ 0x03 "blissSigType"
+ 0x01 "BLISS-with-SHA512" OID_BLISS_WITH_SHA512
+ 0x02 "BLISS-with-SHA384" OID_BLISS_WITH_SHA384
+ 0x03 "BLISS-with-SHA256" OID_BLISS_WITH_SHA256
0x89 ""
0x31 ""
0x01 ""
@@ -215,6 +233,10 @@
0x02 ""
0x02 ""
0x4B "TCGID" OID_TCGID
+ 0x97 ""
+ 0x55 ""
+ 0x01 ""
+ 0x02 "blowfish-cbc" OID_BLOWFISH_CBC
0xC1 ""
0x16 "ntruCryptosystems"
0x01 "eess"
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c
index db08c6b96..0ca45a15b 100644
--- a/src/libstrongswan/credentials/auth_cfg.c
+++ b/src/libstrongswan/credentials/auth_cfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2012 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
* Copyright (C) 2007-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -49,6 +49,7 @@ ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_AC_CERT,
"RULE_GROUP",
"RULE_RSA_STRENGTH",
"RULE_ECDSA_STRENGTH",
+ "RULE_BLISS_STRENGTH",
"RULE_SIGNATURE_SCHEME",
"RULE_CERT_POLICY",
"HELPER_IM_CERT",
@@ -71,6 +72,7 @@ static inline bool is_multi_value_rule(auth_rule_t type)
case AUTH_RULE_EAP_VENDOR:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_IDENTITY:
case AUTH_RULE_IDENTITY_LOOSE:
case AUTH_RULE_EAP_IDENTITY:
@@ -207,6 +209,7 @@ static void init_entry(entry_t *this, auth_rule_t type, va_list args)
case AUTH_RULE_OCSP_VALIDATION:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
/* integer type */
this->value = (void*)(uintptr_t)va_arg(args, u_int);
@@ -255,6 +258,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2)
case AUTH_RULE_OCSP_VALIDATION:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
{
return e1->value == e2->value;
@@ -345,6 +349,7 @@ static void destroy_entry_value(entry_t *entry)
case AUTH_RULE_OCSP_VALIDATION:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
case AUTH_RULE_MAX:
break;
@@ -376,6 +381,7 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator,
case AUTH_RULE_OCSP_VALIDATION:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
/* integer type */
entry->value = (void*)(uintptr_t)va_arg(args, u_int);
@@ -450,6 +456,7 @@ METHOD(auth_cfg_t, get, void*,
case AUTH_RULE_EAP_VENDOR:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
return (void*)0;
case AUTH_RULE_SIGNATURE_SCHEME:
return (void*)HASH_UNKNOWN;
@@ -513,6 +520,7 @@ METHOD(auth_cfg_t, complies, bool,
signature_scheme_t scheme = SIGN_UNKNOWN;
u_int strength = 0;
auth_rule_t t1, t2;
+ char *key_type;
void *value;
e1 = constraints->create_enumerator(constraints);
@@ -703,6 +711,7 @@ METHOD(auth_cfg_t, complies, bool,
}
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
{
strength = (uintptr_t)value;
break;
@@ -797,30 +806,39 @@ METHOD(auth_cfg_t, complies, bool,
e2 = create_enumerator(this);
while (e2->enumerate(e2, &t2, &strength))
{
- if (t2 == AUTH_RULE_RSA_STRENGTH ||
- t2 == AUTH_RULE_ECDSA_STRENGTH)
+ switch (t2)
{
- success = FALSE;
- e1 = constraints->create_enumerator(constraints);
- while (e1->enumerate(e1, &t1, &value))
+ default:
+ continue;
+ case AUTH_RULE_RSA_STRENGTH:
+ key_type = "RSA";
+ break;
+ case AUTH_RULE_ECDSA_STRENGTH:
+ key_type = "ECDSA";
+ break;
+ case AUTH_RULE_BLISS_STRENGTH:
+ key_type = "BLISS";
+ break;
+ }
+ success = FALSE;
+ e1 = constraints->create_enumerator(constraints);
+ while (e1->enumerate(e1, &t1, &value))
+ {
+ if (t1 == t2 && (uintptr_t)value <= strength)
{
- if (t1 == t2 && (uintptr_t)value <= strength)
- {
- success = TRUE;
- break;
- }
+ success = TRUE;
+ break;
}
- e1->destroy(e1);
- if (!success)
+ }
+ e1->destroy(e1);
+ if (!success)
+ {
+ if (log_error)
{
- if (log_error)
- {
- DBG1(DBG_CFG, "%s-%d signatures not acceptable",
- t2 == AUTH_RULE_RSA_STRENGTH ? "RSA" : "ECDSA",
- strength);
- }
- break;
+ DBG1(DBG_CFG, "%s-%d signatures not acceptable",
+ key_type, strength);
}
+ break;
}
}
e2->destroy(e2);
@@ -891,6 +909,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
case AUTH_RULE_EAP_VENDOR:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
{
add(this, type, (uintptr_t)value);
@@ -1060,6 +1079,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*,
case AUTH_RULE_OCSP_VALIDATION:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_BLISS_STRENGTH:
case AUTH_RULE_SIGNATURE_SCHEME:
clone->add(clone, type, (uintptr_t)value);
break;
diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h
index 95b36d706..53f1b3805 100644
--- a/src/libstrongswan/credentials/auth_cfg.h
+++ b/src/libstrongswan/credentials/auth_cfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2012 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
* Copyright (C) 2007-2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -102,6 +102,8 @@ enum auth_rule_t {
AUTH_RULE_RSA_STRENGTH,
/** required ECDSA public key strength, u_int in bits */
AUTH_RULE_ECDSA_STRENGTH,
+ /** required BLISS public key strength, u_int in bits */
+ AUTH_RULE_BLISS_STRENGTH,
/** required signature scheme, signature_scheme_t */
AUTH_RULE_SIGNATURE_SCHEME,
/** certificatePolicy constraint, numerical OID as char* */
diff --git a/src/libstrongswan/credentials/cred_encoding.h b/src/libstrongswan/credentials/cred_encoding.h
index a6c9c30af..b4d1f4c3c 100644
--- a/src/libstrongswan/credentials/cred_encoding.h
+++ b/src/libstrongswan/credentials/cred_encoding.h
@@ -144,6 +144,10 @@ enum cred_encoding_part_t {
CRED_PART_PKCS10_ASN1_DER,
/** a PGP encoded certificate */
CRED_PART_PGP_CERT,
+ /** a DER encoded BLISS public key */
+ CRED_PART_BLISS_PUB_ASN1_DER,
+ /** a DER encoded BLISS private key */
+ CRED_PART_BLISS_PRIV_ASN1_DER,
CRED_PART_END,
};
diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c
index b0c8e48ba..371e6404d 100644
--- a/src/libstrongswan/credentials/credential_manager.c
+++ b/src/libstrongswan/credentials/credential_manager.c
@@ -698,6 +698,9 @@ static void get_key_strength(certificate_t *cert, auth_cfg_t *auth)
case KEY_ECDSA:
auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength);
break;
+ case KEY_BLISS:
+ auth->add(auth, AUTH_RULE_BLISS_STRENGTH, strength);
+ break;
default:
break;
}
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c
index 37bba77d1..bd5915e60 100644
--- a/src/libstrongswan/credentials/keys/public_key.c
+++ b/src/libstrongswan/credentials/keys/public_key.c
@@ -1,6 +1,8 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
* Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -17,14 +19,15 @@
#include "public_key.h"
-ENUM(key_type_names, KEY_ANY, KEY_DSA,
+ENUM(key_type_names, KEY_ANY, KEY_BLISS,
"ANY",
"RSA",
"ECDSA",
- "DSA"
+ "DSA",
+ "BLISS"
);
-ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521,
+ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_BLISS_WITH_SHA512,
"UNKNOWN",
"RSA_EMSA_PKCS1_NULL",
"RSA_EMSA_PKCS1_MD5",
@@ -41,6 +44,9 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521,
"ECDSA-256",
"ECDSA-384",
"ECDSA-521",
+ "BLISS_WITH_SHA256",
+ "BLISS_WITH_SHA384",
+ "BLISS_WITH_SHA512",
);
ENUM(encryption_scheme_names, ENCRYPT_UNKNOWN, ENCRYPT_RSA_OAEP_SHA512,
@@ -130,8 +136,158 @@ signature_scheme_t signature_scheme_from_oid(int oid)
return SIGN_ECDSA_WITH_SHA384_DER;
case OID_ECDSA_WITH_SHA512:
return SIGN_ECDSA_WITH_SHA512_DER;
- default:
- return SIGN_UNKNOWN;
+ case OID_BLISS_PUBLICKEY:
+ case OID_BLISS_WITH_SHA512:
+ return SIGN_BLISS_WITH_SHA512;
+ case OID_BLISS_WITH_SHA256:
+ return SIGN_BLISS_WITH_SHA256;
+ case OID_BLISS_WITH_SHA384:
+ return SIGN_BLISS_WITH_SHA384;
}
+ return SIGN_UNKNOWN;
}
+/*
+ * Defined in header.
+ */
+int signature_scheme_to_oid(signature_scheme_t scheme)
+{
+ switch (scheme)
+ {
+ case SIGN_UNKNOWN:
+ case SIGN_RSA_EMSA_PKCS1_NULL:
+ case SIGN_ECDSA_WITH_NULL:
+ case SIGN_ECDSA_256:
+ case SIGN_ECDSA_384:
+ case SIGN_ECDSA_521:
+ break;
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return OID_MD5_WITH_RSA;
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ return OID_SHA1_WITH_RSA;
+ case SIGN_RSA_EMSA_PKCS1_SHA224:
+ return OID_SHA224_WITH_RSA;
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ return OID_SHA256_WITH_RSA;
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ return OID_SHA384_WITH_RSA;
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return OID_SHA512_WITH_RSA;
+ case SIGN_ECDSA_WITH_SHA1_DER:
+ return OID_ECDSA_WITH_SHA1;
+ case SIGN_ECDSA_WITH_SHA256_DER:
+ return OID_ECDSA_WITH_SHA256;
+ case SIGN_ECDSA_WITH_SHA384_DER:
+ return OID_ECDSA_WITH_SHA384;
+ case SIGN_ECDSA_WITH_SHA512_DER:
+ return OID_ECDSA_WITH_SHA512;
+ case SIGN_BLISS_WITH_SHA256:
+ return OID_BLISS_WITH_SHA256;
+ case SIGN_BLISS_WITH_SHA384:
+ return OID_BLISS_WITH_SHA384;
+ case SIGN_BLISS_WITH_SHA512:
+ return OID_BLISS_WITH_SHA512;
+ }
+ return OID_UNKNOWN;
+}
+
+/**
+ * Map for signature schemes to the key type and maximum key size allowed.
+ * We only cover schemes with hash algorithms supported by IKEv2 signature
+ * authentication.
+ */
+static struct {
+ signature_scheme_t scheme;
+ key_type_t type;
+ int max_keysize;
+} scheme_map[] = {
+ { SIGN_RSA_EMSA_PKCS1_SHA256, KEY_RSA, 3072 },
+ { SIGN_RSA_EMSA_PKCS1_SHA384, KEY_RSA, 7680 },
+ { SIGN_RSA_EMSA_PKCS1_SHA512, KEY_RSA, 0 },
+ { SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, 256 },
+ { SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, 384 },
+ { SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, 0 },
+ { SIGN_BLISS_WITH_SHA256, KEY_BLISS, 128 },
+ { SIGN_BLISS_WITH_SHA384, KEY_BLISS, 192 },
+ { SIGN_BLISS_WITH_SHA512, KEY_BLISS, 0 },
+};
+
+/**
+ * Private data for signature scheme enumerator
+ */
+typedef struct {
+ enumerator_t public;
+ int index;
+ key_type_t type;
+ int size;
+} private_enumerator_t;
+
+METHOD(enumerator_t, signature_schemes_enumerate, bool,
+ private_enumerator_t *this, signature_scheme_t *scheme)
+{
+ while (++this->index < countof(scheme_map))
+ {
+ if (this->type == scheme_map[this->index].type &&
+ (this->size <= scheme_map[this->index].max_keysize ||
+ !scheme_map[this->index].max_keysize))
+ {
+ *scheme = scheme_map[this->index].scheme;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Defined in header.
+ */
+enumerator_t *signature_schemes_for_key(key_type_t type, int size)
+{
+ private_enumerator_t *this;
+
+ INIT(this,
+ .public = {
+ .enumerate = (void*)_signature_schemes_enumerate,
+ .destroy = (void*)free,
+ },
+ .index = -1,
+ .type = type,
+ .size = size,
+ );
+
+ return &this->public;
+}
+
+/*
+ * Defined in header.
+ */
+key_type_t key_type_from_signature_scheme(signature_scheme_t scheme)
+{
+ switch (scheme)
+ {
+ case SIGN_UNKNOWN:
+ break;
+ case SIGN_RSA_EMSA_PKCS1_NULL:
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ case SIGN_RSA_EMSA_PKCS1_SHA224:
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ return KEY_RSA;
+ case SIGN_ECDSA_WITH_SHA1_DER:
+ case SIGN_ECDSA_WITH_SHA256_DER:
+ case SIGN_ECDSA_WITH_SHA384_DER:
+ case SIGN_ECDSA_WITH_SHA512_DER:
+ case SIGN_ECDSA_WITH_NULL:
+ case SIGN_ECDSA_256:
+ case SIGN_ECDSA_384:
+ case SIGN_ECDSA_521:
+ return KEY_ECDSA;
+ case SIGN_BLISS_WITH_SHA256:
+ case SIGN_BLISS_WITH_SHA384:
+ case SIGN_BLISS_WITH_SHA512:
+ return KEY_BLISS;
+ }
+ return KEY_ANY;
+}
diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h
index 2afcf8325..66e98b294 100644
--- a/src/libstrongswan/credentials/keys/public_key.h
+++ b/src/libstrongswan/credentials/keys/public_key.h
@@ -1,6 +1,8 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
* Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -42,6 +44,8 @@ enum key_type_t {
KEY_ECDSA = 2,
/** DSA */
KEY_DSA = 3,
+ /** BLISS */
+ KEY_BLISS = 4,
/** ElGamal, ... */
};
@@ -90,6 +94,12 @@ enum signature_scheme_t {
SIGN_ECDSA_384,
/** ECDSA on the P-521 curve with SHA-512 as in RFC 4754 */
SIGN_ECDSA_521,
+ /** BLISS with SHA-256 */
+ SIGN_BLISS_WITH_SHA256,
+ /** BLISS with SHA-384 */
+ SIGN_BLISS_WITH_SHA384,
+ /** BLISS with SHA-512 */
+ SIGN_BLISS_WITH_SHA512,
};
/**
@@ -234,8 +244,35 @@ bool public_key_has_fingerprint(public_key_t *public, chunk_t fingerprint);
* Conversion of ASN.1 signature or hash OID to signature scheme.
*
* @param oid ASN.1 OID
- * @return signature_scheme, SIGN_UNKNOWN if OID is unsupported
+ * @return signature scheme, SIGN_UNKNOWN if OID is unsupported
*/
signature_scheme_t signature_scheme_from_oid(int oid);
+/**
+ * Conversion of signature scheme to ASN.1 signature OID.
+ *
+ * @param scheme signature scheme
+ * @return ASN.1 OID, OID_UNKNOWN if not supported
+ */
+int signature_scheme_to_oid(signature_scheme_t scheme);
+
+/**
+ * Enumerate signature schemes that are appropriate for a key of the given type
+ * and size|strength.
+ *
+ * @param type type of the key
+ * @param size size or strength of the key
+ * @return enumerator over signature_scheme_t (increasing strength)
+ */
+enumerator_t *signature_schemes_for_key(key_type_t type, int size);
+
+/**
+ * Determine the type of key associated with a given signature scheme.
+ *
+ * @param scheme signature scheme
+ * @return key type (could be KEY_ANY)
+ */
+key_type_t key_type_from_signature_scheme(signature_scheme_t scheme);
+
+
#endif /** PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c
index 563f4bdd5..60720dc57 100644
--- a/src/libstrongswan/credentials/sets/cert_cache.c
+++ b/src/libstrongswan/credentials/sets/cert_cache.c
@@ -143,6 +143,7 @@ METHOD(cert_cache_t, issued_by, bool,
private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer,
signature_scheme_t *schemep)
{
+ certificate_t *cached_issuer = NULL;
relation_t *found = NULL, *current;
signature_scheme_t scheme;
int i;
@@ -154,39 +155,41 @@ METHOD(cert_cache_t, issued_by, bool,
current->lock->read_lock(current->lock);
if (current->subject)
{
- /* check for equal issuer */
if (issuer->equals(issuer, current->issuer))
{
- /* reuse issuer instance in cache() */
- issuer = current->issuer;
if (subject->equals(subject, current->subject))
{
- /* write hit counter is not locked, but not critical */
current->hits++;
- found = current;;
+ found = current;
if (schemep)
{
*schemep = current->scheme;
}
}
+ else if (!cached_issuer)
+ {
+ cached_issuer = current->issuer->get_ref(current->issuer);
+ }
}
}
current->lock->unlock(current->lock);
if (found)
{
+ DESTROY_IF(cached_issuer);
return TRUE;
}
}
- /* no cache hit, check and cache signature */
if (subject->issued_by(subject, issuer, &scheme))
{
- cache(this, subject, issuer, scheme);
+ cache(this, subject, cached_issuer ?: issuer, scheme);
if (schemep)
{
*schemep = scheme;
}
+ DESTROY_IF(cached_issuer);
return TRUE;
}
+ DESTROY_IF(cached_issuer);
return FALSE;
}
diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c
index d8f568d36..7ad011b5e 100644
--- a/src/libstrongswan/credentials/sets/mem_cred.c
+++ b/src/libstrongswan/credentials/sets/mem_cred.c
@@ -192,6 +192,24 @@ METHOD(mem_cred_t, add_cert_ref, certificate_t*,
return add_cert_internal(this, trusted, cert);
}
+METHOD(mem_cred_t, get_cert_ref, certificate_t*,
+ private_mem_cred_t *this, certificate_t *cert)
+{
+ certificate_t *cached;
+
+ this->lock->write_lock(this->lock);
+ if (this->untrusted->find_first(this->untrusted,
+ (linked_list_match_t)certificate_equals,
+ (void**)&cached, cert) == SUCCESS)
+ {
+ cert->destroy(cert);
+ cert = cached->get_ref(cached);
+ }
+ this->lock->unlock(this->lock);
+
+ return cert;
+}
+
METHOD(mem_cred_t, add_crl, bool,
private_mem_cred_t *this, crl_t *crl)
{
@@ -736,6 +754,7 @@ mem_cred_t *mem_cred_create()
},
.add_cert = _add_cert,
.add_cert_ref = _add_cert_ref,
+ .get_cert_ref = _get_cert_ref,
.add_crl = _add_crl,
.add_key = _add_key,
.add_shared = _add_shared,
diff --git a/src/libstrongswan/credentials/sets/mem_cred.h b/src/libstrongswan/credentials/sets/mem_cred.h
index d0dd51da1..3ce815abc 100644
--- a/src/libstrongswan/credentials/sets/mem_cred.h
+++ b/src/libstrongswan/credentials/sets/mem_cred.h
@@ -59,6 +59,18 @@ struct mem_cred_t {
certificate_t *cert);
/**
+ * Get an existing reference to the same certificate.
+ *
+ * Searches for the same certficate in the set, and returns a reference
+ * to it, destroying the passed certificate. If the passed certificate
+ * is not found, it is just returned.
+ *
+ * @param cert certificate to look up
+ * @return the same certificate, potentially different instance
+ */
+ certificate_t* (*get_cert_ref)(mem_cred_t *this, certificate_t *cert);
+
+ /**
* Add an X.509 CRL to the credential set.
*
* @param crl CRL, gets owned by set
diff --git a/src/libstrongswan/crypto/crypters/crypter.c b/src/libstrongswan/crypto/crypters/crypter.c
index 8123adde5..1e73baa4e 100644
--- a/src/libstrongswan/crypto/crypters/crypter.c
+++ b/src/libstrongswan/crypto/crypters/crypter.c
@@ -96,6 +96,10 @@ encryption_algorithm_t encryption_algorithm_from_oid(int oid, size_t *key_size)
alg = ENCR_CAMELLIA_CBC;
alg_key_size = 256;
break;
+ case OID_BLOWFISH_CBC:
+ alg = ENCR_BLOWFISH;
+ alg_key_size = 0;
+ break;
default:
alg = ENCR_UNDEFINED;
alg_key_size = 0;
@@ -154,6 +158,9 @@ int encryption_algorithm_to_oid(encryption_algorithm_t alg, size_t key_size)
oid = OID_UNKNOWN;
}
break;
+ case ENCR_BLOWFISH:
+ oid = OID_BLOWFISH_CBC;
+ break;
default:
oid = OID_UNKNOWN;
}
diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c
index d09844bfa..15ed17381 100644
--- a/src/libstrongswan/crypto/crypto_tester.c
+++ b/src/libstrongswan/crypto/crypto_tester.c
@@ -580,13 +580,22 @@ METHOD(crypto_tester_t, test_signer, bool,
break;
}
+ data = chunk_create(vector->data, vector->len);
key = chunk_create(vector->key, signer->get_key_size(signer));
if (!signer->set_key(signer, key))
{
goto failure;
}
+ /* do partial append mode and check if key gets set correctly */
+ if (!signer->get_signature(signer, data, NULL))
+ {
+ goto failure;
+ }
+ if (!signer->set_key(signer, key))
+ {
+ goto failure;
+ }
/* allocated signature */
- data = chunk_create(vector->data, vector->len);
if (!signer->allocate_signature(signer, data, &mac))
{
goto failure;
@@ -905,13 +914,25 @@ METHOD(crypto_tester_t, test_prf, bool,
break;
}
+ seed = chunk_create(vector->seed, vector->len);
key = chunk_create(vector->key, vector->key_size);
if (!prf->set_key(prf, key))
{
goto failure;
}
+ if (alg != PRF_FIPS_SHA1_160)
+ {
+ /* do partial append mode and check if key gets set correctly */
+ if (!prf->get_bytes(prf, seed, NULL))
+ {
+ goto failure;
+ }
+ if (!prf->set_key(prf, key))
+ {
+ goto failure;
+ }
+ }
/* allocated bytes */
- seed = chunk_create(vector->seed, vector->len);
if (!prf->allocate_bytes(prf, seed, &out))
{
goto failure;
@@ -942,7 +963,7 @@ METHOD(crypto_tester_t, test_prf, bool,
goto failure;
}
/* bytes to existing buffer, using append mode */
- if (seed.len > 2)
+ if (alg != PRF_FIPS_SHA1_160 && seed.len > 2)
{
memset(out.ptr, 0, out.len);
if (vector->stateful)
diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/diffie_hellman.c
index 87c9b21f8..0d4cd9109 100644
--- a/src/libstrongswan/crypto/diffie_hellman.c
+++ b/src/libstrongswan/crypto/diffie_hellman.c
@@ -42,15 +42,16 @@ ENUM_NEXT(diffie_hellman_group_names, MODP_1024_160, ECP_512_BP, ECP_521_BIT,
"ECP_256_BP",
"ECP_384_BP",
"ECP_512_BP");
-ENUM_NEXT(diffie_hellman_group_names, MODP_NULL, MODP_CUSTOM, ECP_512_BP,
- "MODP_NULL",
- "MODP_CUSTOM");
-ENUM_NEXT(diffie_hellman_group_names, NTRU_112_BIT, NTRU_256_BIT, MODP_CUSTOM,
+ENUM_NEXT(diffie_hellman_group_names, MODP_NULL, MODP_NULL, ECP_512_BP,
+ "MODP_NULL");
+ENUM_NEXT(diffie_hellman_group_names, NTRU_112_BIT, NTRU_256_BIT, MODP_NULL,
"NTRU_112",
"NTRU_128",
"NTRU_192",
"NTRU_256");
-ENUM_END(diffie_hellman_group_names, NTRU_256_BIT);
+ENUM_NEXT(diffie_hellman_group_names, MODP_CUSTOM, MODP_CUSTOM, NTRU_256_BIT,
+ "MODP_CUSTOM");
+ENUM_END(diffie_hellman_group_names, MODP_CUSTOM);
/**
@@ -439,7 +440,7 @@ void diffie_hellman_init()
{
int i;
- if (lib->settings->get_int(lib->settings,
+ if (lib->settings->get_bool(lib->settings,
"%s.dh_exponent_ansi_x9_42", TRUE, lib->ns))
{
for (i = 0; i < countof(dh_params); i++)
@@ -463,7 +464,7 @@ diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group)
if (!dh_params[i].public.exp_len)
{
if (!dh_params[i].public.subgroup.len &&
- lib->settings->get_int(lib->settings,
+ lib->settings->get_bool(lib->settings,
"%s.dh_exponent_ansi_x9_42", TRUE, lib->ns))
{
dh_params[i].public.exp_len = dh_params[i].public.prime.len;
@@ -500,3 +501,75 @@ bool diffie_hellman_group_is_ec(diffie_hellman_group_t group)
return FALSE;
}
}
+
+/**
+ * See header.
+ */
+bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value)
+{
+ diffie_hellman_params_t *params;
+ bool valid = FALSE;
+
+ switch (group)
+ {
+ case MODP_768_BIT:
+ case MODP_1024_BIT:
+ case MODP_1536_BIT:
+ case MODP_2048_BIT:
+ case MODP_3072_BIT:
+ case MODP_4096_BIT:
+ case MODP_6144_BIT:
+ case MODP_8192_BIT:
+ case MODP_1024_160:
+ case MODP_2048_224:
+ case MODP_2048_256:
+ params = diffie_hellman_get_params(group);
+ if (params)
+ {
+ valid = value.len == params->prime.len;
+ }
+ break;
+ case ECP_192_BIT:
+ valid = value.len == 48;
+ break;
+ case ECP_224_BIT:
+ case ECP_224_BP:
+ valid = value.len == 56;
+ break;
+ case ECP_256_BIT:
+ case ECP_256_BP:
+ valid = value.len == 64;
+ break;
+ case ECP_384_BIT:
+ case ECP_384_BP:
+ valid = value.len == 96;
+ break;
+ case ECP_512_BP:
+ valid = value.len == 128;
+ break;
+ case ECP_521_BIT:
+ valid = value.len == 132;
+ break;
+ case NTRU_112_BIT:
+ case NTRU_128_BIT:
+ case NTRU_192_BIT:
+ case NTRU_256_BIT:
+ /* verification currently not supported, do in plugin */
+ valid = FALSE;
+ break;
+ case MODP_NULL:
+ case MODP_CUSTOM:
+ valid = TRUE;
+ break;
+ case MODP_NONE:
+ /* fail */
+ break;
+ /* compile-warn unhandled groups, fail verification */
+ }
+ if (!valid)
+ {
+ DBG1(DBG_ENC, "invalid DH public value size (%zu bytes) for %N",
+ value.len, diffie_hellman_group_names, group);
+ }
+ return valid;
+}
diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/diffie_hellman.h
index 105db22f1..4704cd0da 100644
--- a/src/libstrongswan/crypto/diffie_hellman.h
+++ b/src/libstrongswan/crypto/diffie_hellman.h
@@ -63,12 +63,14 @@ enum diffie_hellman_group_t {
/** insecure NULL diffie hellman group for testing, in PRIVATE USE */
MODP_NULL = 1024,
/** MODP group with custom generator/prime */
- MODP_CUSTOM = 1025,
/** Parameters defined by IEEE 1363.1, in PRIVATE USE */
NTRU_112_BIT = 1030,
NTRU_128_BIT = 1031,
NTRU_192_BIT = 1032,
- NTRU_256_BIT = 1033
+ NTRU_256_BIT = 1033,
+ /** internally used DH group with additional parameters g and p, outside
+ * of PRIVATE USE (i.e. IKEv2 DH group range) so it can't be negotiated */
+ MODP_CUSTOM = 65536,
};
/**
@@ -87,9 +89,10 @@ struct diffie_hellman_t {
* Space for returned secret is allocated and must be freed by the caller.
*
* @param secret shared secret will be written into this chunk
- * @return SUCCESS, FAILED if not both DH values are set
+ * @return TRUE if shared secret computed successfully
*/
- status_t (*get_shared_secret) (diffie_hellman_t *this, chunk_t *secret);
+ bool (*get_shared_secret)(diffie_hellman_t *this, chunk_t *secret)
+ __attribute__((warn_unused_result));
/**
* Sets the public value of partner.
@@ -97,8 +100,10 @@ struct diffie_hellman_t {
* Chunk gets cloned and can be destroyed afterwards.
*
* @param value public value of partner
+ * @return TRUE if other public value verified and set
*/
- void (*set_other_public_value) (diffie_hellman_t *this, chunk_t value);
+ bool (*set_other_public_value)(diffie_hellman_t *this, chunk_t value)
+ __attribute__((warn_unused_result));
/**
* Gets the own public value to transmit.
@@ -106,8 +111,10 @@ struct diffie_hellman_t {
* Space for returned chunk is allocated and must be freed by the caller.
*
* @param value public value of caller is stored at this location
+ * @return TRUE if public value retrieved
*/
- void (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value);
+ bool (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value)
+ __attribute__((warn_unused_result));
/**
* Get the DH group used.
@@ -168,8 +175,17 @@ diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group)
* Check if a given DH group is an ECDH group
*
* @param group group to check
- * @return TUE if group is an ECP group
+ * @return TRUE if group is an ECP group
*/
bool diffie_hellman_group_is_ec(diffie_hellman_group_t group);
+/**
+ * Check if a diffie hellman public value is valid for given group.
+ *
+ * @param group group the value is used in
+ * @param value public DH value to check
+ * @return TRUE if value looks valid for group
+ */
+bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value);
+
#endif /** DIFFIE_HELLMAN_H_ @}*/
diff --git a/src/libstrongswan/crypto/hashers/hash_algorithm_set.c b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c
new file mode 100644
index 000000000..93b67cb13
--- /dev/null
+++ b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2015 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 "hash_algorithm_set.h"
+
+#include <collections/array.h>
+
+typedef struct private_hash_algorithm_set_t private_hash_algorithm_set_t;
+
+struct private_hash_algorithm_set_t {
+
+ /**
+ * Public interface
+ */
+ hash_algorithm_set_t public;
+
+ /**
+ * Algorithms contained in the set
+ */
+ array_t *algorithms;
+};
+
+/**
+ * Sort hash algorithms
+ */
+static int hash_sort(const void *a, const void *b, void *user)
+{
+ const hash_algorithm_t *ha = a, *hb = b;
+ return *ha - *hb;
+}
+
+/**
+ * Find a hash algorithm
+ */
+static int hash_find(const void *a, const void *b)
+{
+ return hash_sort(a, b, NULL);
+}
+
+METHOD(hash_algorithm_set_t, contains, bool,
+ private_hash_algorithm_set_t *this, hash_algorithm_t hash)
+{
+ return array_bsearch(this->algorithms, &hash, hash_find, NULL) != -1;
+}
+
+METHOD(hash_algorithm_set_t, add, void,
+ private_hash_algorithm_set_t *this, hash_algorithm_t hash)
+{
+ if (!contains(this, hash))
+ {
+ array_insert(this->algorithms, ARRAY_TAIL, &hash);
+ array_sort(this->algorithms, hash_sort, NULL);
+ }
+}
+
+METHOD(hash_algorithm_set_t, count, int,
+ private_hash_algorithm_set_t *this)
+{
+ return array_count(this->algorithms);
+}
+
+static bool hash_filter(void *data, void **in, hash_algorithm_t *out)
+{
+ *out = **(hash_algorithm_t**)in;
+ return TRUE;
+}
+
+METHOD(hash_algorithm_set_t, create_enumerator, enumerator_t*,
+ private_hash_algorithm_set_t *this)
+{
+ return enumerator_create_filter(array_create_enumerator(this->algorithms),
+ (void*)hash_filter, NULL, NULL);
+}
+
+METHOD(hash_algorithm_set_t, destroy, void,
+ private_hash_algorithm_set_t *this)
+{
+ array_destroy(this->algorithms);
+ free(this);
+}
+
+/**
+ * Described in header
+ */
+hash_algorithm_set_t *hash_algorithm_set_create()
+{
+ private_hash_algorithm_set_t *this;
+
+ INIT(this,
+ .public = {
+ .add = _add,
+ .contains = _contains,
+ .count = _count,
+ .create_enumerator = _create_enumerator,
+ .destroy = _destroy,
+ },
+ .algorithms = array_create(sizeof(hash_algorithm_t), 0),
+ );
+
+ return &this->public;
+} \ No newline at end of file
diff --git a/src/libstrongswan/crypto/hashers/hash_algorithm_set.h b/src/libstrongswan/crypto/hashers/hash_algorithm_set.h
new file mode 100644
index 000000000..00e90cc2e
--- /dev/null
+++ b/src/libstrongswan/crypto/hashers/hash_algorithm_set.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 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 hash_algorithm_set hash_algorithm_set
+ * @{ @ingroup crypto
+ */
+
+#ifndef HASH_ALGORITHM_SET_H_
+#define HASH_ALGORITHM_SET_H_
+
+typedef struct hash_algorithm_set_t hash_algorithm_set_t;
+
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
+/**
+ * A set of hash algorithms
+ */
+struct hash_algorithm_set_t {
+
+ /**
+ * Add the given algorithm to the set.
+ *
+ * @param alg hash algorithm
+ */
+ void (*add)(hash_algorithm_set_t *this, hash_algorithm_t alg);
+
+ /**
+ * Check if the given algorithm is contained in the set.
+ *
+ * @param alg hash algorithm
+ * @return TRUE if contained in set
+ */
+ bool (*contains)(hash_algorithm_set_t *this, hash_algorithm_t alg);
+
+ /**
+ * Number of hash algorithms contained in the set.
+ *
+ * @return number of algorithms
+ */
+ int (*count)(hash_algorithm_set_t *this);
+
+ /**
+ * Enumerate the algorithms contained in the set.
+ *
+ * @return enumerator over hash_algorithm_t (sorted by identifier)
+ */
+ enumerator_t *(*create_enumerator)(hash_algorithm_set_t *this);
+
+ /**
+ * Destroy a hash_algorithm_set_t instance
+ */
+ void (*destroy)(hash_algorithm_set_t *this);
+};
+
+/**
+ * Create a set of hash algorithms.
+ *
+ * @return hash_algorithm_set_t instance
+ */
+hash_algorithm_set_t *hash_algorithm_set_create();
+
+#endif /** HASH_ALGORITHM_SET_H_ @}*/
diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c
index 13cbb5a59..38eebea9c 100644
--- a/src/libstrongswan/crypto/hashers/hasher.c
+++ b/src/libstrongswan/crypto/hashers/hasher.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2015 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -19,29 +19,31 @@
#include <asn1/oid.h>
-ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512,
+ENUM_BEGIN(hash_algorithm_names, HASH_SHA1, HASH_SHA512,
+ "HASH_SHA1",
+ "HASH_SHA256",
+ "HASH_SHA384",
+ "HASH_SHA512");
+ENUM_NEXT(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA224, HASH_SHA512,
"HASH_UNKNOWN",
"HASH_MD2",
"HASH_MD4",
"HASH_MD5",
- "HASH_SHA1",
- "HASH_SHA224",
- "HASH_SHA256",
- "HASH_SHA384",
- "HASH_SHA512"
-);
+ "HASH_SHA224");
+ENUM_END(hash_algorithm_names, HASH_SHA224);
-ENUM(hash_algorithm_short_names, HASH_UNKNOWN, HASH_SHA512,
+ENUM_BEGIN(hash_algorithm_short_names, HASH_SHA1, HASH_SHA512,
+ "sha1",
+ "sha256",
+ "sha384",
+ "sha512");
+ENUM_NEXT(hash_algorithm_short_names, HASH_UNKNOWN, HASH_SHA224, HASH_SHA512,
"unknown",
"md2",
"md4",
"md5",
- "sha1",
- "sha224",
- "sha256",
- "sha384",
- "sha512"
-);
+ "sha224");
+ENUM_END(hash_algorithm_short_names, HASH_SHA224);
/*
* Described in header.
@@ -249,6 +251,28 @@ integrity_algorithm_t hasher_algorithm_to_integrity(hash_algorithm_t alg,
/*
* Described in header.
*/
+bool hasher_algorithm_for_ikev2(hash_algorithm_t alg)
+{
+ switch (alg)
+ {
+ case HASH_SHA1:
+ case HASH_SHA256:
+ case HASH_SHA384:
+ case HASH_SHA512:
+ return TRUE;
+ case HASH_UNKNOWN:
+ case HASH_MD2:
+ case HASH_MD4:
+ case HASH_MD5:
+ case HASH_SHA224:
+ break;
+ }
+ return FALSE;
+}
+
+/*
+ * Described in header.
+ */
int hasher_algorithm_to_oid(hash_algorithm_t alg)
{
int oid;
@@ -323,8 +347,56 @@ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg, key_type_t key)
default:
return OID_UNKNOWN;
}
+ case KEY_BLISS:
+ switch (alg)
+ {
+ case HASH_SHA256:
+ return OID_BLISS_WITH_SHA256;
+ case HASH_SHA384:
+ return OID_BLISS_WITH_SHA384;
+ case HASH_SHA512:
+ return OID_BLISS_WITH_SHA512;
+ default:
+ return OID_UNKNOWN;
+ }
default:
return OID_UNKNOWN;
}
}
+/*
+ * Defined in header.
+ */
+hash_algorithm_t hasher_from_signature_scheme(signature_scheme_t scheme)
+{
+ switch (scheme)
+ {
+ case SIGN_UNKNOWN:
+ case SIGN_RSA_EMSA_PKCS1_NULL:
+ case SIGN_ECDSA_WITH_NULL:
+ break;
+ case SIGN_RSA_EMSA_PKCS1_MD5:
+ return HASH_MD5;
+ case SIGN_RSA_EMSA_PKCS1_SHA1:
+ case SIGN_ECDSA_WITH_SHA1_DER:
+ return HASH_SHA1;
+ case SIGN_RSA_EMSA_PKCS1_SHA224:
+ return HASH_SHA224;
+ case SIGN_RSA_EMSA_PKCS1_SHA256:
+ case SIGN_ECDSA_WITH_SHA256_DER:
+ case SIGN_ECDSA_256:
+ case SIGN_BLISS_WITH_SHA256:
+ return HASH_SHA256;
+ case SIGN_RSA_EMSA_PKCS1_SHA384:
+ case SIGN_ECDSA_WITH_SHA384_DER:
+ case SIGN_ECDSA_384:
+ case SIGN_BLISS_WITH_SHA384:
+ return HASH_SHA384;
+ case SIGN_RSA_EMSA_PKCS1_SHA512:
+ case SIGN_ECDSA_WITH_SHA512_DER:
+ case SIGN_ECDSA_521:
+ case SIGN_BLISS_WITH_SHA512:
+ return HASH_SHA512;
+ }
+ return HASH_UNKNOWN;
+}
diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h
index 37ef0b6ab..772586308 100644
--- a/src/libstrongswan/crypto/hashers/hasher.h
+++ b/src/libstrongswan/crypto/hashers/hasher.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2015 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -32,19 +32,19 @@ typedef struct hasher_t hasher_t;
#include <credentials/keys/public_key.h>
/**
- * Algorithms to use for hashing.
+ * Hash algorithms as defined for IKEv2 by RFC 7427
*/
enum hash_algorithm_t {
- /** not specified hash function */
- HASH_UNKNOWN = 0,
- HASH_MD2 = 1,
- HASH_MD4 = 2,
- HASH_MD5 = 3,
- HASH_SHA1 = 4,
- HASH_SHA224 = 5,
- HASH_SHA256 = 6,
- HASH_SHA384 = 7,
- HASH_SHA512 = 8
+ HASH_SHA1 = 1,
+ HASH_SHA256 = 2,
+ HASH_SHA384 = 3,
+ HASH_SHA512 = 4,
+ /* use private use range for algorithms not defined/permitted by RFC 7427 */
+ HASH_UNKNOWN = 1024,
+ HASH_MD2 = 1025,
+ HASH_MD4 = 1026,
+ HASH_MD5 = 1027,
+ HASH_SHA224 = 1028,
};
#define HASH_SIZE_MD2 16
@@ -163,6 +163,14 @@ integrity_algorithm_t hasher_algorithm_to_integrity(hash_algorithm_t alg,
size_t length);
/**
+ * Check if the given algorithm may be used for IKEv2 signature authentication.
+ *
+ * @param alg hash algorithm
+ * @return TRUE if algorithm may be used, FALSE otherwise
+ */
+bool hasher_algorithm_for_ikev2(hash_algorithm_t alg);
+
+/**
* Conversion of hash algorithm into ASN.1 OID.
*
* @param alg hash algorithm
@@ -179,4 +187,12 @@ int hasher_algorithm_to_oid(hash_algorithm_t alg);
*/
int hasher_signature_algorithm_to_oid(hash_algorithm_t alg, key_type_t key);
+/**
+ * Determine the hash algorithm associated with a given signature scheme.
+ *
+ * @param scheme signature scheme
+ * @return hash algorithm (could be HASH_UNKNOWN)
+ */
+hash_algorithm_t hasher_from_signature_scheme(signature_scheme_t scheme);
+
#endif /** HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/ntru/ntru_mgf1.c b/src/libstrongswan/crypto/mgf1/mgf1.c
index 2338db208..4bbcd6e99 100644
--- a/src/libstrongswan/plugins/ntru/ntru_mgf1.c
+++ b/src/libstrongswan/crypto/mgf1/mgf1.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -13,23 +13,23 @@
* for more details.
*/
-#include "ntru_mgf1.h"
+#include "mgf1.h"
-#include <crypto/hashers/hasher.h>
-#include <utils/debug.h>
-#include <utils/test.h>
+#include "crypto/hashers/hasher.h"
+#include "utils/debug.h"
+#include "utils/test.h"
-typedef struct private_ntru_mgf1_t private_ntru_mgf1_t;
+typedef struct private_mgf1_t private_mgf1_t;
/**
- * Private data of an ntru_mgf1_t object.
+ * Private data of an mgf1_t object.
*/
-struct private_ntru_mgf1_t {
+struct private_mgf1_t {
/**
- * Public ntru_mgf1_t interface.
+ * Public mgf1_t interface.
*/
- ntru_mgf1_t public;
+ mgf1_t public;
/**
* Hasher the MGF1 Mask Generation Function is based on
@@ -58,14 +58,14 @@ struct private_ntru_mgf1_t {
};
-METHOD(ntru_mgf1_t, get_hash_size, size_t,
- private_ntru_mgf1_t *this)
+METHOD(mgf1_t, get_hash_size, size_t,
+ private_mgf1_t *this)
{
return this->hasher->get_hash_size(this->hasher);
}
-METHOD(ntru_mgf1_t, get_mask, bool,
- private_ntru_mgf1_t *this, size_t mask_len, u_char *mask)
+METHOD(mgf1_t, get_mask, bool,
+ private_mgf1_t *this, size_t mask_len, u_char *mask)
{
u_char buf[HASH_SIZE_SHA512];
size_t hash_len;
@@ -102,8 +102,8 @@ METHOD(ntru_mgf1_t, get_mask, bool,
return TRUE;
}
-METHOD(ntru_mgf1_t, allocate_mask, bool,
- private_ntru_mgf1_t *this, size_t mask_len, chunk_t *mask)
+METHOD(mgf1_t, allocate_mask, bool,
+ private_mgf1_t *this, size_t mask_len, chunk_t *mask)
{
if (mask_len == 0)
{
@@ -115,8 +115,8 @@ METHOD(ntru_mgf1_t, allocate_mask, bool,
return get_mask(this, mask_len, mask->ptr);
}
-METHOD(ntru_mgf1_t, destroy, void,
- private_ntru_mgf1_t *this)
+METHOD(mgf1_t, destroy, void,
+ private_mgf1_t *this)
{
this->hasher->destroy(this->hasher);
chunk_clear(&this->state);
@@ -126,10 +126,10 @@ METHOD(ntru_mgf1_t, destroy, void,
/*
* Described in header.
*/
-ntru_mgf1_t *ntru_mgf1_create(hash_algorithm_t alg, chunk_t seed,
+mgf1_t *mgf1_create(hash_algorithm_t alg, chunk_t seed,
bool hash_seed)
{
- private_ntru_mgf1_t *this;
+ private_mgf1_t *this;
hasher_t *hasher;
size_t state_len;
@@ -178,5 +178,3 @@ ntru_mgf1_t *ntru_mgf1_create(hash_algorithm_t alg, chunk_t seed,
return &this->public;
}
-
-EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_mgf1_create);
diff --git a/src/libstrongswan/plugins/ntru/ntru_mgf1.h b/src/libstrongswan/crypto/mgf1/mgf1.h
index 53e90412a..592d31596 100644
--- a/src/libstrongswan/plugins/ntru/ntru_mgf1.h
+++ b/src/libstrongswan/crypto/mgf1/mgf1.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -14,29 +14,29 @@
*/
/**
- * @defgroup ntru_mgf1 ntru_mgf1
- * @{ @ingroup ntru_p
+ * @defgroup mgf1 mgf1
+ * @{ @ingroup crypto
*/
-#ifndef NTRU_MGF1_H_
-#define NTRU_MGF1_H_
+#ifndef MGF1_H_
+#define MGF1_H_
-typedef struct ntru_mgf1_t ntru_mgf1_t;
+typedef struct mgf1_t mgf1_t;
#include <library.h>
/**
* Implements the PKCS#1 MGF1 Mask Generation Function based on a hash function
- * defined in section 10.2.1 of RFC 2437
+ * defined in section 10.2.1 of RFC 2437
*/
-struct ntru_mgf1_t {
+struct mgf1_t {
/**
* Get the hash size of the underlying hash function
*
* @return hash size in bytes
*/
- size_t (*get_hash_size)(ntru_mgf1_t *this);
+ size_t (*get_hash_size)(mgf1_t *this);
/**
* Generate a mask pattern and copy it to an output buffer
@@ -46,7 +46,7 @@ struct ntru_mgf1_t {
* @param mask output buffer of minimum size mask_len
* @return TRUE if successful
*/
- bool (*get_mask)(ntru_mgf1_t *this, size_t mask_len, u_char *mask);
+ bool (*get_mask)(mgf1_t *this, size_t mask_len, u_char *mask);
/**
* Generate a mask pattern and return it in an allocated chunk
@@ -55,12 +55,12 @@ struct ntru_mgf1_t {
* @param mask chunk containing generated mask
* @return TRUE if successful
*/
- bool (*allocate_mask)(ntru_mgf1_t *this, size_t mask_len, chunk_t *mask);
+ bool (*allocate_mask)(mgf1_t *this, size_t mask_len, chunk_t *mask);
/**
* Destroy the MGF1 object
*/
- void (*destroy)(ntru_mgf1_t *this);
+ void (*destroy)(mgf1_t *this);
};
/**
@@ -68,10 +68,10 @@ struct ntru_mgf1_t {
*
* @param alg hash algorithm to be used by MGF1
* @param seed seed used by MGF1 to generate mask from
- * @param hash_seed hash seed before using it as a seed from MGF1
+ * @param hash_seed hash seed before using it as a seed for MGF1
*/
-ntru_mgf1_t *ntru_mgf1_create(hash_algorithm_t alg, chunk_t seed,
+mgf1_t *mgf1_create(hash_algorithm_t alg, chunk_t seed,
bool hash_seed);
-#endif /** NTRU_MGF1_H_ @}*/
+#endif /** MGF1_H_ @}*/
diff --git a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c
new file mode 100644
index 000000000..ef0a2bd01
--- /dev/null
+++ b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "mgf1_bitspender.h"
+
+#include <crypto/mgf1/mgf1.h>
+
+typedef struct private_mgf1_bitspender_t private_mgf1_bitspender_t;
+
+/**
+ * Private data structure for mgf1_bitspender_t object
+ */
+struct private_mgf1_bitspender_t {
+ /**
+ * Public interface.
+ */
+ mgf1_bitspender_t public;
+
+ /**
+ * MGF1 bit mask generator
+ */
+ mgf1_t *mgf1;
+
+ /**
+ * Octet storage (accommodates up to 64 octets)
+ */
+ uint8_t octets[HASH_SIZE_SHA512];
+
+ /**
+ * Length of the returned hash value in octets
+ */
+ int hash_len;
+
+ /**
+ * Number of generated octets
+ */
+ int octets_count;
+
+ /**
+ * Number of available octets
+ */
+ int octets_left;
+
+ /**
+ * Bit storage (accommodates up to 32 bits)
+ */
+ uint32_t bits;
+
+ /**
+ * Number of available bits
+ */
+ int bits_left;
+
+ /**
+ * Byte storage (accommodates up to 4 bytes)
+ */
+ uint8_t bytes[4];
+
+ /**
+ * Number of available bytes
+ */
+ int bytes_left;
+
+};
+
+METHOD(mgf1_bitspender_t, get_bits, bool,
+ private_mgf1_bitspender_t *this, int bits_needed, uint32_t *bits)
+{
+ int bits_now;
+
+ *bits = 0x00000000;
+
+ if (bits_needed == 0)
+ {
+ /* trivial */
+ return TRUE;
+ }
+ if (bits_needed > 32)
+ {
+ /* too many bits requested */
+ return FALSE;
+ }
+
+ while (bits_needed)
+ {
+ if (this->bits_left == 0)
+ {
+ if (this->octets_left == 0)
+ {
+ /* get another block from MGF1 */
+ if (!this->mgf1->get_mask(this->mgf1, this->hash_len,
+ this->octets))
+ {
+ /* no block available */
+ return FALSE;
+ }
+ this->octets_left = this->hash_len;
+ this->octets_count += this->hash_len;
+ }
+ this->bits = untoh32(this->octets + this->hash_len -
+ this->octets_left);
+ this->bits_left = 32;
+ this->octets_left -= 4;
+ }
+ if (bits_needed > this->bits_left)
+ {
+ bits_now = this->bits_left;
+ this->bits_left = 0;
+ bits_needed -= bits_now;
+ }
+ else
+ {
+ bits_now = bits_needed;
+ this->bits_left -= bits_needed;
+ bits_needed = 0;
+ }
+ if (bits_now == 32)
+ {
+ *bits = this->bits;
+ }
+ else
+ {
+ *bits <<= bits_now;
+ *bits |= this->bits >> this->bits_left;
+ if (this->bits_left)
+ {
+ this->bits &= 0xffffffff >> (32 - this->bits_left);
+ }
+ }
+ }
+ return TRUE;
+}
+
+METHOD(mgf1_bitspender_t, get_byte, bool,
+ private_mgf1_bitspender_t *this, uint8_t *byte)
+{
+ if (this->bytes_left == 0)
+ {
+ if (this->octets_left == 0)
+ {
+ /* get another block from MGF1 */
+ if (!this->mgf1->get_mask(this->mgf1, this->hash_len, this->octets))
+ {
+ /* no block available */
+ return FALSE;
+ }
+ this->octets_left = this->hash_len;
+ this->octets_count += this->hash_len;
+ }
+ memcpy(this->bytes, this->octets + this->hash_len - this->octets_left, 4);
+ this->bytes_left = 4;
+ this->octets_left -= 4;
+ }
+ *byte = this->bytes[4 - this->bytes_left--];
+
+ return TRUE;
+}
+
+METHOD(mgf1_bitspender_t, destroy, void,
+ private_mgf1_bitspender_t *this)
+{
+ DBG2(DBG_LIB, "mgf1 generated %u octets", this->octets_count);
+ memwipe(this->octets, sizeof(this->octets));
+ this->mgf1->destroy(this->mgf1);
+ free(this);
+}
+
+/**
+ * See header.
+ */
+mgf1_bitspender_t *mgf1_bitspender_create(hash_algorithm_t alg, chunk_t seed,
+ bool hash_seed)
+{
+ private_mgf1_bitspender_t *this;
+ mgf1_t *mgf1;
+
+ mgf1 = mgf1_create(alg, seed, hash_seed);
+ if (!mgf1)
+ {
+ return NULL;
+ }
+ DBG2(DBG_LIB, "mgf1 based on %N is seeded with %u octets",
+ hash_algorithm_short_names, alg, seed.len);
+
+ INIT(this,
+ .public = {
+ .get_bits = _get_bits,
+ .get_byte = _get_byte,
+ .destroy = _destroy,
+ },
+ .mgf1 = mgf1,
+ .hash_len = mgf1->get_hash_size(mgf1),
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h
new file mode 100644
index 000000000..f7df8e834
--- /dev/null
+++ b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup mgf1_bitspender mgf1_bitspender
+ * @{ @ingroup mgf1
+ */
+
+#ifndef MGF1_BITSPENDER_H_
+#define MGF1_BITSPENDER_H_
+
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
+typedef struct mgf1_bitspender_t mgf1_bitspender_t;
+
+/**
+ * Generates a given number of pseudo-random bits at a time using MGF1
+ */
+struct mgf1_bitspender_t {
+
+ /**
+ * Get pseudo-random bits
+ *
+ * @param bits_needed Number of needed bits (1..32)
+ * @param bits Pseudo-random bits
+ * @result FALSE if internal MGF1 error occurred
+ */
+ bool (*get_bits)(mgf1_bitspender_t *this, int bits_needed, uint32_t *bits);
+
+ /**
+ * Get a pseudo-random byte
+ *
+ * @param byte Pseudo-random byte
+ * @result FALSE if internal MGF1 error occurred
+ */
+ bool (*get_byte)(mgf1_bitspender_t *this, uint8_t *byte);
+
+ /**
+ * Destroy mgf1_bitspender_t object
+ */
+ void (*destroy)(mgf1_bitspender_t *this);
+};
+
+/**
+ * Create a mgf1_bitspender_t object
+ *
+ * @param alg Hash algorithm to be used with MGF1
+ * @param seed Seed used to initialize MGF1
+ * @param hash_seed Hash seed before using it as a seed for MFG1
+ */
+mgf1_bitspender_t *mgf1_bitspender_create(hash_algorithm_t alg, chunk_t seed,
+ bool hash_seed);
+
+#endif /** MGF1_BITSPENDER_H_ @}*/
diff --git a/src/libstrongswan/crypto/pkcs5.c b/src/libstrongswan/crypto/pkcs5.c
index 3b4df0e8a..478926f2f 100644
--- a/src/libstrongswan/crypto/pkcs5.c
+++ b/src/libstrongswan/crypto/pkcs5.c
@@ -108,13 +108,13 @@ struct private_pkcs5_t {
* Verify padding of decrypted blob.
* Length of blob is adjusted accordingly.
*/
-static bool verify_padding(chunk_t *blob)
+static bool verify_padding(crypter_t *crypter, chunk_t *blob)
{
u_int8_t padding, count;
padding = count = blob->ptr[blob->len - 1];
- if (padding > 8)
+ if (padding > crypter->get_block_size(crypter))
{
return FALSE;
}
@@ -153,7 +153,7 @@ static bool decrypt_generic(private_pkcs5_t *this, chunk_t password,
return FALSE;
}
memwipe(keymat.ptr, keymat.len);
- if (verify_padding(decrypted))
+ if (verify_padding(this->crypter, decrypted))
{
return TRUE;
}
@@ -504,6 +504,7 @@ static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0)
{
asn1_parser_t *parser;
chunk_t object, params;
+ size_t keylen;
int objectID;
bool success = FALSE;
@@ -533,20 +534,35 @@ static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0)
{
int oid = asn1_parse_algorithmIdentifier(object,
parser->get_level(parser) + 1, &params);
- if (oid != OID_3DES_EDE_CBC)
+ this->encr = encryption_algorithm_from_oid(oid, &keylen);
+ if (this->encr == ENCR_UNDEFINED)
{ /* unsupported encryption scheme */
goto end;
}
- if (this->keylen <= 0)
- { /* default key length for DES-EDE3-CBC-Pad */
- this->keylen = 24;
+ /* prefer encoded key length */
+ this->keylen = this->keylen ?: keylen / 8;
+ if (!this->keylen)
+ { /* set default key length for known algorithms */
+ switch (this->encr)
+ {
+ case ENCR_DES:
+ this->keylen = 8;
+ break;
+ case ENCR_3DES:
+ this->keylen = 24;
+ break;
+ case ENCR_BLOWFISH:
+ this->keylen = 16;
+ break;
+ default:
+ goto end;
+ }
}
if (!asn1_parse_simple_object(&params, ASN1_OCTET_STRING,
parser->get_level(parser) + 1, "IV"))
{
goto end;
}
- this->encr = ENCR_3DES;
this->data.pbes2.iv = chunk_clone(params);
break;
}
diff --git a/src/libstrongswan/ipsec/ipsec_types.c b/src/libstrongswan/ipsec/ipsec_types.c
index 4bbd918a0..f2ee11ee8 100644
--- a/src/libstrongswan/ipsec/ipsec_types.c
+++ b/src/libstrongswan/ipsec/ipsec_types.c
@@ -48,7 +48,15 @@ bool mark_from_string(const char *value, mark_t *mark)
{
return FALSE;
}
- mark->value = strtoul(value, &endptr, 0);
+ if (strcasepfx(value, "%unique"))
+ {
+ mark->value = MARK_UNIQUE;
+ endptr = (char*)value + strlen("%unique");
+ }
+ else
+ {
+ mark->value = strtoul(value, &endptr, 0);
+ }
if (*endptr)
{
if (*endptr != '/')
diff --git a/src/libstrongswan/ipsec/ipsec_types.h b/src/libstrongswan/ipsec/ipsec_types.h
index c1465e097..fa122af30 100644
--- a/src/libstrongswan/ipsec/ipsec_types.h
+++ b/src/libstrongswan/ipsec/ipsec_types.h
@@ -169,9 +169,9 @@ struct mark_t {
};
/**
- * Special mark value that uses the reqid of the CHILD_SA as mark
+ * Special mark value that uses a unique mark for each CHILD_SA
*/
-#define MARK_REQID (0xFFFFFFFF)
+#define MARK_UNIQUE (0xFFFFFFFF)
/**
* Try to parse a mark_t from the given string of the form mark[/mask].
diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h
index 2bd5e3523..3a6dd1ba4 100644
--- a/src/libstrongswan/library.h
+++ b/src/libstrongswan/library.h
@@ -79,6 +79,9 @@
*
* @defgroup utils utils
* @ingroup libstrongswan
+ *
+ * @defgroup compat compat
+ * @ingroup utils
*/
/**
diff --git a/src/libstrongswan/networking/host.c b/src/libstrongswan/networking/host.c
index 8d04a4ec9..07da3ef3b 100644
--- a/src/libstrongswan/networking/host.c
+++ b/src/libstrongswan/networking/host.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2012 Tobias Brunner
+ * Copyright (C) 2006-2014 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -528,6 +528,42 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port)
/*
* Described in header.
*/
+bool host_create_from_range(char *string, host_t **from, host_t **to)
+{
+ char *sep, *pos;
+
+ sep = strchr(string, '-');
+ if (!sep)
+ {
+ return FALSE;
+ }
+ for (pos = sep+1; *pos && *pos == ' '; pos++)
+ {
+ /* trim spaces before to address*/
+ }
+ *to = host_create_from_string(pos, 0);
+ if (!*to)
+ {
+ return FALSE;
+ }
+ for (pos = sep-1; pos > string && *pos == ' '; pos--)
+ {
+ /* trim spaces behind from address */
+ }
+ pos = strndup(string, pos - string + 1);
+ *from = host_create_from_string_and_family(pos, (*to)->get_family(*to), 0);
+ free(pos);
+ if (!*from)
+ {
+ (*to)->destroy(*to);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Described in header.
+ */
host_t *host_create_from_subnet(char *string, int *bits)
{
char *pos, buf[64];
diff --git a/src/libstrongswan/networking/host.h b/src/libstrongswan/networking/host.h
index 9c9b5035f..db6f4dd49 100644
--- a/src/libstrongswan/networking/host.h
+++ b/src/libstrongswan/networking/host.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2009 Tobias Brunner
+ * Copyright (C) 2006-2014 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -24,6 +24,9 @@
#ifndef HOST_H_
#define HOST_H_
+#include <utils/utils.h>
+#include <utils/chunk.h>
+
typedef enum host_diff_t host_diff_t;
typedef struct host_t host_t;
@@ -31,9 +34,6 @@ typedef struct host_t host_t;
#include <stdio.h>
#include <sys/types.h>
-#include <utils/utils.h>
-#include <utils/chunk.h>
-
/**
* Representates a Host
*
@@ -181,6 +181,19 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port);
host_t *host_create_from_sockaddr(sockaddr_t *sockaddr);
/**
+ * Parse a range definition (1.2.3.0-1.2.3.5), return the two hosts.
+ *
+ * The two hosts are not ordered, from is simply the first, to is the second,
+ * from is not necessarily smaller.
+ *
+ * @param string string to parse
+ * @param from returns the first address (out)
+ * @param to returns the second address (out)
+ * @return TRUE if parsed successfully, FALSE otherwise
+ */
+bool host_create_from_range(char *string, host_t **from, host_t **to);
+
+/**
* Create a host from a CIDR subnet definition (1.2.3.0/24), return bits.
*
* @param string string to parse
diff --git a/src/libstrongswan/networking/host_resolver.c b/src/libstrongswan/networking/host_resolver.c
index a7524ac23..bad87e434 100644
--- a/src/libstrongswan/networking/host_resolver.c
+++ b/src/libstrongswan/networking/host_resolver.c
@@ -163,20 +163,25 @@ static void *resolve_hosts(private_host_resolver_t *this)
int error;
bool old, timed_out;
+ /* default resolver threads to non-cancellable */
+ thread_cancelability(FALSE);
+
while (TRUE)
{
this->mutex->lock(this->mutex);
- thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
while (this->queue->remove_first(this->queue,
(void**)&query) != SUCCESS)
{
- old = thread_cancelability(TRUE);
+ if (this->disabled)
+ {
+ this->mutex->unlock(this->mutex);
+ return NULL;
+ }
timed_out = this->new_query->timed_wait(this->new_query,
this->mutex, NEW_QUERY_WAIT_TIMEOUT * 1000);
- thread_cancelability(old);
if (this->disabled)
{
- thread_cleanup_pop(TRUE);
+ this->mutex->unlock(this->mutex);
return NULL;
}
else if (timed_out && (this->threads > this->min_threads))
@@ -185,13 +190,13 @@ static void *resolve_hosts(private_host_resolver_t *this)
this->threads--;
this->pool->remove(this->pool, thread, NULL);
- thread_cleanup_pop(TRUE);
+ this->mutex->unlock(this->mutex);
thread->detach(thread);
return NULL;
}
}
this->busy_threads++;
- thread_cleanup_pop(TRUE);
+ this->mutex->unlock(this->mutex);
memset(&hints, 0, sizeof(hints));
hints.ai_family = query->family;
diff --git a/src/libstrongswan/networking/tun_device.c b/src/libstrongswan/networking/tun_device.c
index ff2c4a337..81d215677 100644
--- a/src/libstrongswan/networking/tun_device.c
+++ b/src/libstrongswan/networking/tun_device.c
@@ -346,40 +346,27 @@ METHOD(tun_device_t, write_packet, bool,
METHOD(tun_device_t, read_packet, bool,
private_tun_device_t *this, chunk_t *packet)
{
+ chunk_t data;
ssize_t len;
- fd_set set;
bool old;
- FD_ZERO(&set);
- FD_SET(this->tunfd, &set);
+ data = chunk_alloca(get_mtu(this));
old = thread_cancelability(TRUE);
- len = select(this->tunfd + 1, &set, NULL, NULL, NULL);
+ len = read(this->tunfd, data.ptr, data.len);
thread_cancelability(old);
-
- if (len < 0)
- {
- DBG1(DBG_LIB, "select on TUN device %s failed: %s", this->if_name,
- strerror(errno));
- return FALSE;
- }
- /* FIXME: this is quite expensive for lots of small packets, copy from
- * local buffer instead? */
- *packet = chunk_alloc(get_mtu(this));
- len = read(this->tunfd, packet->ptr, packet->len);
if (len < 0)
{
DBG1(DBG_LIB, "reading from TUN device %s failed: %s", this->if_name,
strerror(errno));
- chunk_free(packet);
return FALSE;
}
- packet->len = len;
+ data.len = len;
#ifdef __APPLE__
/* UTUN's prepend packets with a 32-bit protocol number */
- packet->len -= sizeof(u_int32_t);
- memmove(packet->ptr, packet->ptr + sizeof(u_int32_t), packet->len);
+ data = chunk_skip(data, sizeof(u_int32_t));
#endif
+ *packet = chunk_clone(data);
return TRUE;
}
diff --git a/src/libstrongswan/networking/tun_device.h b/src/libstrongswan/networking/tun_device.h
index 543125beb..880369ba7 100644
--- a/src/libstrongswan/networking/tun_device.h
+++ b/src/libstrongswan/networking/tun_device.h
@@ -31,8 +31,6 @@ typedef struct tun_device_t tun_device_t;
* Class to create TUN devices
*
* Creating such a device requires the CAP_NET_ADMIN capability.
- *
- * @note The implementation is currently very Linux specific
*/
struct tun_device_t {
@@ -42,7 +40,7 @@ struct tun_device_t {
* @note This call blocks until a packet is available. It is a thread
* cancellation point.
*
- * @param packet the packet read from the device
+ * @param packet the packet read from the device, allocated
* @return TRUE if successful
*/
bool (*read_packet)(tun_device_t *this, chunk_t *packet);
diff --git a/src/libstrongswan/plugins/acert/Makefile.in b/src/libstrongswan/plugins/acert/Makefile.in
index 425e8f1a9..65542ea5d 100644
--- a/src/libstrongswan/plugins/acert/Makefile.in
+++ b/src/libstrongswan/plugins/acert/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/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in
index 11dcf2907..9d79c81ee 100644
--- a/src/libstrongswan/plugins/aes/Makefile.in
+++ b/src/libstrongswan/plugins/aes/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/libstrongswan/plugins/af_alg/Makefile.in b/src/libstrongswan/plugins/af_alg/Makefile.in
index 279000d88..4a86f9640 100644
--- a/src/libstrongswan/plugins/af_alg/Makefile.in
+++ b/src/libstrongswan/plugins/af_alg/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/libstrongswan/plugins/af_alg/af_alg_prf.c b/src/libstrongswan/plugins/af_alg/af_alg_prf.c
index 720738a84..2b7d51376 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_prf.c
+++ b/src/libstrongswan/plugins/af_alg/af_alg_prf.c
@@ -139,6 +139,7 @@ METHOD(prf_t, set_key, bool,
{
char buf[this->block_size];
+ this->ops->reset(this->ops);
if (this->xcbc)
{
/* The kernel currently does not support variable length XCBC keys,
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_signer.c b/src/libstrongswan/plugins/af_alg/af_alg_signer.c
index 6ee380633..9ad01103a 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_signer.c
+++ b/src/libstrongswan/plugins/af_alg/af_alg_signer.c
@@ -156,6 +156,7 @@ METHOD(signer_t, get_block_size, size_t,
METHOD(signer_t, set_key, bool,
private_af_alg_signer_t *this, chunk_t key)
{
+ this->ops->reset(this->ops);
return this->ops->set_key(this->ops, key);
}
diff --git a/src/libstrongswan/plugins/agent/Makefile.in b/src/libstrongswan/plugins/agent/Makefile.in
index c8e8112c5..292c2fd90 100644
--- a/src/libstrongswan/plugins/agent/Makefile.in
+++ b/src/libstrongswan/plugins/agent/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/libstrongswan/plugins/bliss/Makefile.am b/src/libstrongswan/plugins/bliss/Makefile.am
new file mode 100644
index 000000000..e2aaaf55c
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/Makefile.am
@@ -0,0 +1,54 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = \
+ $(PLUGIN_CFLAGS) \
+ @COVERAGE_CFLAGS@
+
+# these file are also used by bliss_huffman
+noinst_LTLIBRARIES = libbliss-params.la
+libbliss_params_la_SOURCES = \
+ bliss_param_set.h bliss_param_set.c \
+ bliss_fft_params.h bliss_fft_params.c
+
+# these files are also used by the tests, we can't directly refer to them
+# because of the subdirectory, which would cause distclean to fail
+noinst_LTLIBRARIES += libbliss.la
+libbliss_la_SOURCES = \
+ bliss_private_key.h bliss_private_key.c \
+ bliss_public_key.h bliss_public_key.c \
+ bliss_signature.h bliss_signature.c \
+ bliss_utils.h bliss_utils.c \
+ bliss_bitpacker.h bliss_bitpacker.c \
+ bliss_fft.h bliss_fft.c \
+ bliss_huffman_code.h bliss_huffman_code.c \
+ bliss_huffman_code_1.c bliss_huffman_code_3.c bliss_huffman_code_4.c \
+ bliss_huffman_coder.h bliss_huffman_coder.c \
+ bliss_sampler.h bliss_sampler.c
+libbliss_la_LIBADD = libbliss-params.la
+
+if MONOLITHIC
+noinst_LTLIBRARIES += libstrongswan-bliss.la
+else
+plugin_LTLIBRARIES = libstrongswan-bliss.la
+endif
+
+libstrongswan_bliss_la_SOURCES = \
+ bliss_plugin.h bliss_plugin.c
+
+libstrongswan_bliss_la_LDFLAGS = -module -avoid-version
+
+libstrongswan_bliss_la_LIBADD = libbliss.la
+
+noinst_PROGRAMS = bliss_huffman
+
+bliss_huffman_SOURCES = bliss_huffman.c
+bliss_huffman_LDADD = -lm libbliss-params.la
+
+recreate-bliss-huffman : bliss_huffman bliss_huffman_code.h
+ $(AM_V_GEN) \
+ ./bliss_huffman 1 8 > $(srcdir)/bliss_huffman_code_1.c 2>/dev/null
+ $(AM_V_GEN) \
+ ./bliss_huffman 3 16 > $(srcdir)/bliss_huffman_code_3.c 2>/dev/null
+ $(AM_V_GEN) \
+ ./bliss_huffman 4 32 > $(srcdir)/bliss_huffman_code_4.c 2>/dev/null
diff --git a/src/libstrongswan/plugins/bliss/Makefile.in b/src/libstrongswan/plugins/bliss/Makefile.in
new file mode 100644
index 000000000..1361dd340
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/Makefile.in
@@ -0,0 +1,862 @@
+# 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@
+@MONOLITHIC_TRUE@am__append_1 = libstrongswan-bliss.la
+noinst_PROGRAMS = bliss_huffman$(EXEEXT)
+subdir = src/libstrongswan/plugins/bliss
+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)
+libbliss_params_la_LIBADD =
+am_libbliss_params_la_OBJECTS = bliss_param_set.lo bliss_fft_params.lo
+libbliss_params_la_OBJECTS = $(am_libbliss_params_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 =
+libbliss_la_DEPENDENCIES = libbliss-params.la
+am_libbliss_la_OBJECTS = bliss_private_key.lo bliss_public_key.lo \
+ bliss_signature.lo bliss_utils.lo bliss_bitpacker.lo \
+ bliss_fft.lo bliss_huffman_code.lo bliss_huffman_code_1.lo \
+ bliss_huffman_code_3.lo bliss_huffman_code_4.lo \
+ bliss_huffman_coder.lo bliss_sampler.lo
+libbliss_la_OBJECTS = $(am_libbliss_la_OBJECTS)
+libstrongswan_bliss_la_DEPENDENCIES = libbliss.la
+am_libstrongswan_bliss_la_OBJECTS = bliss_plugin.lo
+libstrongswan_bliss_la_OBJECTS = $(am_libstrongswan_bliss_la_OBJECTS)
+libstrongswan_bliss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_bliss_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_bliss_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_bliss_la_rpath =
+PROGRAMS = $(noinst_PROGRAMS)
+am_bliss_huffman_OBJECTS = bliss_huffman.$(OBJEXT)
+bliss_huffman_OBJECTS = $(am_bliss_huffman_OBJECTS)
+bliss_huffman_DEPENDENCIES = libbliss-params.la
+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 = $(libbliss_params_la_SOURCES) $(libbliss_la_SOURCES) \
+ $(libstrongswan_bliss_la_SOURCES) $(bliss_huffman_SOURCES)
+DIST_SOURCES = $(libbliss_params_la_SOURCES) $(libbliss_la_SOURCES) \
+ $(libstrongswan_bliss_la_SOURCES) $(bliss_huffman_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
+
+AM_CFLAGS = \
+ $(PLUGIN_CFLAGS) \
+ @COVERAGE_CFLAGS@
+
+
+# these file are also used by bliss_huffman
+
+# these files are also used by the tests, we can't directly refer to them
+# because of the subdirectory, which would cause distclean to fail
+noinst_LTLIBRARIES = libbliss-params.la libbliss.la $(am__append_1)
+libbliss_params_la_SOURCES = \
+ bliss_param_set.h bliss_param_set.c \
+ bliss_fft_params.h bliss_fft_params.c
+
+libbliss_la_SOURCES = \
+ bliss_private_key.h bliss_private_key.c \
+ bliss_public_key.h bliss_public_key.c \
+ bliss_signature.h bliss_signature.c \
+ bliss_utils.h bliss_utils.c \
+ bliss_bitpacker.h bliss_bitpacker.c \
+ bliss_fft.h bliss_fft.c \
+ bliss_huffman_code.h bliss_huffman_code.c \
+ bliss_huffman_code_1.c bliss_huffman_code_3.c bliss_huffman_code_4.c \
+ bliss_huffman_coder.h bliss_huffman_coder.c \
+ bliss_sampler.h bliss_sampler.c
+
+libbliss_la_LIBADD = libbliss-params.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-bliss.la
+libstrongswan_bliss_la_SOURCES = \
+ bliss_plugin.h bliss_plugin.c
+
+libstrongswan_bliss_la_LDFLAGS = -module -avoid-version
+libstrongswan_bliss_la_LIBADD = libbliss.la
+bliss_huffman_SOURCES = bliss_huffman.c
+bliss_huffman_LDADD = -lm libbliss-params.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/libstrongswan/plugins/bliss/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/bliss/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}; \
+ }
+
+libbliss-params.la: $(libbliss_params_la_OBJECTS) $(libbliss_params_la_DEPENDENCIES) $(EXTRA_libbliss_params_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libbliss_params_la_OBJECTS) $(libbliss_params_la_LIBADD) $(LIBS)
+
+libbliss.la: $(libbliss_la_OBJECTS) $(libbliss_la_DEPENDENCIES) $(EXTRA_libbliss_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libbliss_la_OBJECTS) $(libbliss_la_LIBADD) $(LIBS)
+
+libstrongswan-bliss.la: $(libstrongswan_bliss_la_OBJECTS) $(libstrongswan_bliss_la_DEPENDENCIES) $(EXTRA_libstrongswan_bliss_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libstrongswan_bliss_la_LINK) $(am_libstrongswan_bliss_la_rpath) $(libstrongswan_bliss_la_OBJECTS) $(libstrongswan_bliss_la_LIBADD) $(LIBS)
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_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
+
+bliss_huffman$(EXEEXT): $(bliss_huffman_OBJECTS) $(bliss_huffman_DEPENDENCIES) $(EXTRA_bliss_huffman_DEPENDENCIES)
+ @rm -f bliss_huffman$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(bliss_huffman_OBJECTS) $(bliss_huffman_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_bitpacker.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_fft.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_fft_params.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman_code.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman_code_1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman_code_3.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman_code_4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman_coder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_param_set.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_private_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_public_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_sampler.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_signature.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_utils.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) $(PROGRAMS)
+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-noinstPROGRAMS 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-noinstPROGRAMS \
+ 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
+
+
+recreate-bliss-huffman : bliss_huffman bliss_huffman_code.h
+ $(AM_V_GEN) \
+ ./bliss_huffman 1 8 > $(srcdir)/bliss_huffman_code_1.c 2>/dev/null
+ $(AM_V_GEN) \
+ ./bliss_huffman 3 16 > $(srcdir)/bliss_huffman_code_3.c 2>/dev/null
+ $(AM_V_GEN) \
+ ./bliss_huffman 4 32 > $(srcdir)/bliss_huffman_code_4.c 2>/dev/null
+
+# 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/libstrongswan/plugins/bliss/bliss_bitpacker.c b/src/libstrongswan/plugins/bliss/bliss_bitpacker.c
new file mode 100644
index 000000000..4d8446119
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_bitpacker.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY;https://www.hsr.ch/HSR-intern-Anmeldung.4409.0.html?&no_cache=1 without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_bitpacker.h"
+
+typedef struct private_bliss_bitpacker_t private_bliss_bitpacker_t;
+
+/**
+ * Private data structure for bliss_bitpacker_t object
+ */
+struct private_bliss_bitpacker_t {
+ /**
+ * Public interface.
+ */
+ bliss_bitpacker_t public;
+
+ /**
+ * Current number of bits written to buffer
+ */
+ size_t bits;
+
+ /**
+ * Bit buffer for up to 32 bits
+ */
+ uint32_t bits_buf;
+
+ /**
+ * Bits left in the bit buffer
+ */
+ size_t bits_left;
+
+ /**
+ * Buffer
+ */
+ chunk_t buf;
+
+ /**
+ * Read/Write pointer into buffer
+ */
+ chunk_t pos;
+
+};
+
+METHOD(bliss_bitpacker_t, get_bits, size_t,
+ private_bliss_bitpacker_t *this)
+{
+ return this->bits;
+}
+
+METHOD(bliss_bitpacker_t, write_bits, bool,
+ private_bliss_bitpacker_t *this, uint32_t value, size_t bits)
+{
+ if (bits == 0)
+ {
+ return TRUE;
+ }
+ if (bits > 32)
+ {
+ return FALSE;
+ }
+ if (bits < 32)
+ {
+ value &= (1 << bits) - 1;
+ }
+ this->bits += bits;
+
+ while (TRUE)
+ {
+ if (bits <= this->bits_left)
+ {
+ this->bits_buf |= value << (this->bits_left - bits);
+ this->bits_left -= bits;
+ return TRUE;
+ }
+
+ this->bits_buf |= value >> (bits - this->bits_left);
+ value &= (1 << (bits - this->bits_left)) - 1;
+ bits -= this->bits_left;
+
+ if (this->pos.len < 8)
+ {
+ return FALSE;
+ }
+ htoun32(this->pos.ptr, this->bits_buf);
+ this->pos = chunk_skip(this->pos, 4);
+ this->bits_buf = 0;
+ this->bits_left = 32;
+ }
+}
+
+METHOD(bliss_bitpacker_t, read_bits, bool,
+ private_bliss_bitpacker_t *this, uint32_t *value, size_t bits)
+{
+ if (bits > 32)
+ {
+ return FALSE;
+ }
+ *value = 0;
+
+ while (TRUE)
+ {
+ if (this->bits_left == 0)
+ {
+ if (this->pos.len < 4)
+ {
+ return FALSE;
+ }
+ this->bits_buf = untoh32(this->pos.ptr);
+ this->pos = chunk_skip(this->pos, 4);
+ this->bits_left = 32;
+ }
+ if (bits <= this->bits_left)
+ {
+ *value |= this->bits_buf >> (this->bits_left - bits);
+ this->bits_buf &= (1 << (this->bits_left - bits)) - 1;
+ this->bits_left -= bits;
+
+ return TRUE;
+ }
+ *value |= this->bits_buf << (bits - this->bits_left);
+ bits -= this->bits_left;
+ this->bits_left = 0;
+ }
+}
+
+METHOD(bliss_bitpacker_t, extract_buf, chunk_t,
+ private_bliss_bitpacker_t *this)
+{
+ chunk_t buf;
+
+ htoun32(this->pos.ptr, this->bits_buf);
+ this->pos.len -= 4;
+ buf = this->buf;
+ buf.len = this->buf.len - this->pos.len - this->bits_left/8;
+ this->buf = this->pos = chunk_empty;
+
+ return buf;
+}
+
+METHOD(bliss_bitpacker_t, destroy, void,
+ private_bliss_bitpacker_t *this)
+{
+ free(this->buf.ptr);
+ free(this);
+}
+
+/**
+ * See header.
+ */
+bliss_bitpacker_t *bliss_bitpacker_create(uint16_t max_bits)
+{
+ private_bliss_bitpacker_t *this;
+
+ INIT(this,
+ .public = {
+ .get_bits = _get_bits,
+ .write_bits = _write_bits,
+ .read_bits = _read_bits,
+ .extract_buf = _extract_buf,
+ .destroy = _destroy,
+ },
+ .bits_left = 32,
+ .buf = chunk_alloc(round_up(max_bits, 32)/8),
+ );
+
+ this->pos = this->buf;
+
+ return &this->public;
+}
+
+/**
+ * See header.
+ */
+bliss_bitpacker_t *bliss_bitpacker_create_from_data(chunk_t data)
+{
+ private_bliss_bitpacker_t *this;
+
+ INIT(this,
+ .public = {
+ .get_bits = _get_bits,
+ .write_bits = _write_bits,
+ .read_bits = _read_bits,
+ .extract_buf = _extract_buf,
+ .destroy = _destroy,
+ },
+ .bits = 8 * data.len,
+ .buf = chunk_alloc(round_up(data.len, 4)),
+ );
+
+ memset(this->buf.ptr + this->buf.len - 4, 0x00, 4);
+ memcpy(this->buf.ptr, data.ptr, data.len);
+ this->pos = this->buf;
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_bitpacker.h b/src/libstrongswan/plugins/bliss/bliss_bitpacker.h
new file mode 100644
index 000000000..2fe6cba1c
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_bitpacker.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_bitpacker bliss_bitpacker
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_BITPACKER_H_
+#define BLISS_BITPACKER_H_
+
+#include <library.h>
+
+typedef struct bliss_bitpacker_t bliss_bitpacker_t;
+
+/**
+ * Reads and writes a variable number of bits in packed format
+ * from and to an octet buffer
+ */
+struct bliss_bitpacker_t {
+
+ /**
+ * Get the number of bits written into buffer
+ *
+ * @result Number of bits written
+ */
+ size_t (*get_bits)(bliss_bitpacker_t *this);
+
+ /**
+ * Get the prime modulus of the Number Theoretic Transform
+ *
+ * @param value Value to be written
+ * @param bits Number of bits to be written
+ * @result TRUE if value could be written into buffer
+ */
+ bool (*write_bits)(bliss_bitpacker_t *this, uint32_t value, size_t bits);
+
+
+ /**
+ * Get the prime modulus of the Number Theoretic Transform
+ *
+ * @param value Value returned
+ * @param bits Number of bits to be read
+ * @result TRUE if value could be read from buffer
+ */
+ bool (*read_bits)(bliss_bitpacker_t *this, uint32_t *value, size_t bits);
+
+ /**
+ * Detach the internal octet buffer and return it
+ */
+ chunk_t (*extract_buf)(bliss_bitpacker_t *this);
+
+ /**
+ * Destroy bliss_bitpacker_t object
+ */
+ void (*destroy)(bliss_bitpacker_t *this);
+};
+
+/**
+ * Create a bliss_bitpacker_t object for writing
+ *
+ * @param max_bits Total number of bits to be stored
+ */
+bliss_bitpacker_t* bliss_bitpacker_create(uint16_t max_bits);
+
+/**
+ * Create a bliss_bitpacker_t object for reading
+ *
+ * @param data Packed array of bits
+ */
+bliss_bitpacker_t* bliss_bitpacker_create_from_data(chunk_t data);
+
+#endif /** BLISS_BITPACKER_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_fft.c b/src/libstrongswan/plugins/bliss/bliss_fft.c
new file mode 100644
index 000000000..033c2144e
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_fft.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_fft.h"
+
+typedef struct private_bliss_fft_t private_bliss_fft_t;
+
+/**
+ * Private data structure for bliss_fft_t object
+ */
+struct private_bliss_fft_t {
+ /**
+ * Public interface.
+ */
+ bliss_fft_t public;
+
+ /**
+ * FFT parameter set used as constants
+ */
+ bliss_fft_params_t *p;
+
+};
+
+METHOD(bliss_fft_t, get_size, uint16_t,
+ private_bliss_fft_t *this)
+{
+ return this->p->n;
+}
+
+METHOD(bliss_fft_t, get_modulus, uint16_t,
+ private_bliss_fft_t *this)
+{
+ return this->p->q;
+}
+
+/**
+ * Do an FFT butterfly operation
+ *
+ * x[i1] ---|+|------- x[i1]
+ * \/
+ * /\ w[iw]
+ * x[i2] ---|-|--|*|-- x[i2]
+ *
+ */
+static void butterfly(private_bliss_fft_t *this, uint32_t *x, int i1,int i2,
+ int iw)
+{
+ uint32_t xp, xm;
+
+ xp = x[i1] + x[i2];
+ xm = x[i1] + (this->p->q - x[i2]);
+ if (xp >= this->p->q)
+ {
+ xp -= this->p->q;
+ }
+ x[i1] = xp;
+ x[i2] = (xm * this->p->w[iw]) % this->p->q;
+}
+
+/**
+ * Trivial butterfly operation of last FFT stage
+ */
+static void butterfly_last(private_bliss_fft_t *this, uint32_t *x, int i1)
+{
+ uint32_t xp, xm;
+ int i2 = i1 + 1;
+
+ xp = x[i1] + x[i2];
+ xm = x[i1] + (this->p->q - x[i2]);
+ if (xp >= this->p->q)
+ {
+ xp -= this->p->q;
+ }
+ if (xm >= this->p->q)
+ {
+ xm -= this->p->q;
+ }
+ x[i1] = xp;
+ x[i2] = xm;
+}
+
+METHOD(bliss_fft_t, transform, void,
+ private_bliss_fft_t *this, uint32_t *a, uint32_t *b, bool inverse)
+{
+ int stage, i, j, k, m, n, t, iw, i_rev;
+ uint16_t q;
+ uint32_t tmp;
+
+ /* we are going to use the transform size n and the modulus q a lot */
+ n = this->p->n;
+ q = this->p->q;
+
+ if (!inverse)
+ {
+ /* apply linear phase needed for negative wrapped convolution */
+ for (i = 0; i < n; i++)
+ {
+ b[i] = (a[i] * this->p->w[i]) % q;
+ }
+ }
+ else if (a != b)
+ {
+ /* copy if input and output array are not the same */
+ for (i = 0; i < n; i++)
+ {
+ b[i] = a[i];
+ }
+ }
+
+ m = n;
+ k = 1;
+
+ for (stage = this->p->stages; stage > 0; stage--)
+ {
+ m >>= 1;
+ t = 0;
+
+ for (j = 0; j < k; j++)
+ {
+ if (stage == 1)
+ {
+ butterfly_last(this, b, t);
+ }
+ else
+ {
+ for (i = 0; i < m; i++)
+ {
+ iw = 2 * (inverse ? (n - i * k) : (i * k));
+ butterfly(this, b, t + i, t + i + m, iw);
+ }
+ }
+ t += 2*m;
+ }
+ k <<= 1;
+ }
+
+ /* Sort output in bit-reverse order */
+ for (i = 0; i < n; i++)
+ {
+ i_rev = this->p->rev[i];
+
+ if (i_rev > i)
+ {
+ tmp = b[i];
+ b[i] = b[i_rev];
+ b[i_rev] = tmp;
+ }
+ }
+
+ /**
+ * Compensate the linear phase needed for negative wrapped convolution
+ * and normalize the output array with 1/n mod q after the inverse FFT.
+ */
+ if (inverse)
+ {
+ for (i = 0; i < n; i++)
+ {
+ b[i] = (((b[i] * this->p->w[2*n - i]) % q) * this->p->n_inv) % q;
+ }
+ }
+}
+
+METHOD(bliss_fft_t, destroy, void,
+ private_bliss_fft_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header.
+ */
+bliss_fft_t *bliss_fft_create(bliss_fft_params_t *params)
+{
+ private_bliss_fft_t *this;
+
+ INIT(this,
+ .public = {
+ .get_size = _get_size,
+ .get_modulus = _get_modulus,
+ .transform = _transform,
+ .destroy = _destroy,
+ },
+ .p = params,
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_fft.h b/src/libstrongswan/plugins/bliss/bliss_fft.h
new file mode 100644
index 000000000..a79edd2be
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_fft.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_fft bliss_fft
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_FFT_H_
+#define BLISS_FFT_H_
+
+#include "bliss_fft_params.h"
+
+#include <library.h>
+
+typedef struct bliss_fft_t bliss_fft_t;
+
+/**
+ * Implements a Number Theoretic Transform (NTT) via the FFT algorithm
+ */
+struct bliss_fft_t {
+
+ /**
+ * Get the size of the Number Theoretic Transform
+ *
+ * @result Transform size
+ */
+ uint16_t (*get_size)(bliss_fft_t *this);
+
+ /**
+ * Get the prime modulus of the Number Theoretic Transform
+ *
+ * @result Prime modulus
+ */
+ uint16_t (*get_modulus)(bliss_fft_t *this);
+
+ /**
+ * Compute the [inverse] NTT of a polynomial
+ *
+ * @param a Coefficient of input polynomial
+ * @param b Coefficient of output polynomial
+ * @param inverse TRUE if the inverse NTT has to be computed
+ */
+ void (*transform)(bliss_fft_t *this, uint32_t *a, uint32_t *b, bool inverse);
+
+ /**
+ * Destroy bliss_fft_t object
+ */
+ void (*destroy)(bliss_fft_t *this);
+};
+
+/**
+ * Create a bliss_fft_t object for a given FFT parameter set
+ *
+ * @param params FFT parameters
+ */
+bliss_fft_t *bliss_fft_create(bliss_fft_params_t *params);
+
+#endif /** BLISS_FFT_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_fft_params.c b/src/libstrongswan/plugins/bliss/bliss_fft_params.c
new file mode 100644
index 000000000..c892c06e6
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_fft_params.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_fft_params.h"
+
+/**
+ * FFT parameters for q = 12289 and 2n = 1024
+ */
+static uint16_t w_12289_1024[] = {
+ 1, 49, 2401, 7048, 1260, 295, 2166, 7822, 2319, 3030,
+ 1002, 12231, 9447, 8210, 9042, 654, 7468, 9551, 1017, 677,
+ 8595, 3329, 3364, 5079, 3091, 3991, 11224, 9260, 11336, 2459,
+ 9890, 5339, 3542, 1512, 354, 5057, 2013, 325, 3636, 6118,
+ 4846, 3963, 9852, 3477, 10616, 4046, 1630, 6136, 5728, 10314,
+ 1537, 1579, 3637, 6167, 7247, 11011, 11112, 3772, 493, 11868,
+ 3949, 9166, 6730, 10256, 10984, 9789, 390, 6821, 2426, 8273,
+ 12129, 4449, 9088, 2908, 7313, 1956, 9821, 1958, 9919, 6760,
+ 11726, 9280, 27, 1323, 3382, 5961, 9442, 7965, 9326, 2281,
+ 1168, 8076, 2476, 10723, 9289, 468, 10643, 5369, 5012, 12097,
+
+ 2881, 5990, 10863, 3860, 4805, 1954, 9723, 9445, 8112, 4240,
+ 11136, 4948, 8961, 8974, 9611, 3957, 9558, 1360, 5195, 8775,
+ 12149, 5429, 7952, 8689, 7935, 7856, 3985, 10930, 7143, 5915,
+ 7188, 8120, 4632, 5766, 12176, 6752, 11334, 2361, 5088, 3532,
+ 1022, 922, 8311, 1702, 9664, 6554, 1632, 6234, 10530, 12121,
+ 4057, 2169, 7969, 9522, 11885, 4782, 827, 3656, 7098, 3710,
+ 9744, 10474, 9377, 4780, 729, 11143, 5291, 1190, 9154, 6142,
+ 6022, 142, 6958, 9139, 5407, 6874, 5023, 347, 4714, 9784,
+ 145, 7105, 4053, 1973, 10654, 5908, 6845, 3602, 4452, 9235,
+ 10111, 3879, 5736, 10706, 8456, 8807, 1428, 8527, 12286, 12142,
+
+ 5086, 3434, 8509, 11404, 5791, 1112, 5332, 3199, 9283, 174,
+ 8526, 12237, 9741, 10327, 2174, 8214, 9238, 10258, 11082, 2302,
+ 2197, 9341, 3016, 316, 3195, 9087, 2859, 4912, 7197, 8561,
+ 1663, 7753, 11227, 9407, 6250, 11314, 1381, 6224, 10040, 400,
+ 7311, 1858, 5019, 151, 7399, 6170, 7394, 5925, 7678, 7552,
+ 1378, 6077, 2837, 3834, 3531, 973, 10810, 1263, 442, 9369,
+ 4388, 6099, 3915, 7500, 11119, 4115, 5011, 12048, 480, 11231,
+ 9603, 3565, 2639, 6421, 7404, 6415, 7110, 4298, 1689, 9027,
+ 12208, 8320, 2143, 6695, 8541, 683, 8889, 5446, 8785, 350,
+ 4861, 4698, 9000, 10885, 4938, 8471, 9542, 576, 3646, 6608,
+
+ 4278, 709, 10163, 6427, 7698, 8532, 242, 11858, 3459, 9734,
+ 9984, 9945, 8034, 418, 8193, 8209, 8993, 10542, 420, 8291,
+ 722, 10800, 773, 1010, 334, 4077, 3149, 6833, 3014, 218,
+ 10682, 7280, 339, 4322, 2865, 5206, 9314, 1693, 9223, 9523,
+ 11934, 7183, 7875, 4916, 7393, 5876, 5277, 504, 118, 5782,
+ 671, 8301, 1212, 10232, 9808, 1321, 3284, 1159, 7635, 5445,
+ 8736, 10238, 10102, 3438, 8705, 8719, 9405, 6152, 6512, 11863,
+ 3704, 9450, 8357, 3956, 9509, 11248, 10436, 7515, 11854, 3263,
+ 130, 6370, 4905, 6854, 4043, 1483, 11222, 9162, 6534, 652,
+ 7370, 4749, 11499, 10446, 8005, 11286, 9, 441, 9320, 1987,
+
+ 11340, 2655, 7205, 8953, 8582, 2692, 9018, 11767, 11289, 156,
+ 7644, 5886, 5767, 12225, 9153, 6093, 3621, 5383, 5698, 8844,
+ 3241, 11341, 2704, 9606, 3712, 9842, 2987, 11184, 7300, 1319,
+ 3186, 8646, 5828, 2925, 8146, 5906, 6747, 11089, 2645, 6715,
+ 9521, 11836, 2381, 6068, 2396, 6803, 1544, 1922, 8155, 6347,
+ 3778, 787, 1696, 9370, 4437, 8500, 10963, 8760, 11414, 6281,
+ 544, 2078, 3510, 12233, 9545, 723, 10849, 3174, 8058, 1594,
+ 4372, 5315, 2366, 5333, 3248, 11684, 7222, 9786, 243, 11907,
+ 5860, 4493, 11244, 10240, 10200, 8240, 10512, 11239, 9995, 10484,
+ 9867, 4212, 9764, 11454, 8241, 10561, 1351, 4754, 11744, 10162,
+
+ 6378, 5297, 1484, 11271, 11563, 1293, 1912, 7665, 6915, 7032,
+ 476, 11035, 12288, 12240, 9888, 5241, 11029, 11994, 10123, 4467,
+ 9970, 9259, 11287, 58, 2842, 4079, 3247, 11635, 4821, 2738,
+ 11272, 11612, 3694, 8960, 8925, 7210, 9198, 8298, 1065, 3029,
+ 953, 9830, 2399, 6950, 8747, 10777, 11935, 7232, 10276, 11964,
+ 8653, 6171, 7443, 8326, 2437, 8812, 1673, 8243, 10659, 6153,
+ 6561, 1975, 10752, 10710, 8652, 6122, 5042, 1278, 1177, 8517,
+ 11796, 421, 8340, 3123, 5559, 2033, 1305, 2500, 11899, 5468,
+ 9863, 4016, 160, 7840, 3201, 9381, 4976, 10333, 2468, 10331,
+ 2370, 5529, 563, 3009, 12262, 10966, 8907, 6328, 2847, 4324,
+
+ 2963, 10008, 11121, 4213, 9813, 1566, 3000, 11821, 1646, 6920,
+ 7277, 192, 9408, 6299, 1426, 8429, 7484, 10335, 2566, 2844,
+ 4177, 8049, 1153, 7341, 3328, 3315, 2678, 8332, 2731, 10929,
+ 7094, 3514, 140, 6860, 4337, 3600, 4354, 4433, 8304, 1359,
+ 5146, 6374, 5101, 4169, 7657, 6523, 113, 5537, 955, 9928,
+ 7201, 8757, 11267, 11367, 3978, 10587, 2625, 5735, 10657, 6055,
+ 1759, 168, 8232, 10120, 4320, 2767, 404, 7507, 11462, 8633,
+ 5191, 8579, 2545, 1815, 2912, 7509, 11560, 1146, 6998, 11099,
+ 3135, 6147, 6267, 12147, 5331, 3150, 6882, 5415, 7266, 11942,
+ 7575, 2505, 12144, 5184, 8236, 10316, 1635, 6381, 5444, 8687,
+
+ 7837, 3054, 2178, 8410, 6553, 1583, 3833, 3482, 10861, 3762,
+ 3, 147, 7203, 8855, 3780, 885, 6498, 11177, 6957, 9090,
+ 3006, 12115, 3763, 52, 2548, 1962, 10115, 4075, 3051, 2031,
+ 1207, 9987, 10092, 2948, 9273, 11973, 9094, 3202, 9430, 7377,
+ 5092, 3728, 10626, 4536, 1062, 2882, 6039, 975, 10908, 6065,
+ 2249, 11889, 4978, 10431, 7270, 12138, 4890, 6119, 4895, 6364,
+ 4611, 4737, 10911, 6212, 9452, 8455, 8758, 11316, 1479, 11026,
+ 11847, 2920, 7901, 6190, 8374, 4789, 1170, 8174, 7278, 241,
+ 11809, 1058, 2686, 8724, 9650, 5868, 4885, 5874, 5179, 7991,
+ 10600, 3262, 81, 3969, 10146, 5594, 3748, 11606, 3400, 6843,
+
+ 3504, 11939, 7428, 7591, 3289, 1404, 7351, 3818, 2747, 11713,
+ 8643, 5681, 8011, 11580, 2126, 5862, 4591, 3757, 12047, 431,
+ 8830, 2555, 2305, 2344, 4255, 11871, 4096, 4080, 3296, 1747,
+ 11869, 3998, 11567, 1489, 11516, 11279, 11955, 8212, 9140, 5456,
+ 9275, 12071, 1607, 5009, 11950, 7967, 9424, 7083, 2975, 10596,
+ 3066, 2766, 355, 5106, 4414, 7373, 4896, 6413, 7012, 11785,
+ 12171, 6507, 11618, 3988, 11077, 2057, 2481, 10968, 9005, 11130,
+ 4654, 6844, 3553, 2051, 2187, 8851, 3584, 3570, 2884, 6137,
+ 5777, 426, 8585, 2839, 3932, 8333, 2780, 1041, 1853, 4774,
+ 435, 9026, 12159, 5919, 7384, 5435, 8246, 10806, 1067, 3127,
+
+ 5755, 11637, 4919, 7540, 790, 1843, 4284, 1003, 12280, 11848,
+ 2969, 10302, 949, 9634, 5084, 3336, 3707, 9597, 3271, 522,
+ 1000, 12133, 4645, 6403, 6522, 64, 3136, 6196, 8668, 6906,
+ 6591, 3445, 9048, 948, 9585, 2683, 8577, 2447, 9302, 1105,
+ 4989, 10970, 9103, 3643, 6461, 9364, 4143, 6383, 5542, 1200,
+ 9644, 5574, 2768, 453, 9908, 6221, 9893, 5486, 10745, 10367,
+ 4134, 5942, 8511, 11502, 10593, 2919, 7852, 3789, 1326, 3529,
+ 875, 6008, 11745, 10211, 8779, 56, 2744, 11566, 1440, 9115,
+ 4231, 10695, 7917, 6974, 9923, 6956, 9041, 605, 5067, 2503,
+ 12046, 382, 6429, 7796, 1045, 2049, 2089, 4049, 1777, 1050,
+
+ 2294, 1805, 2422, 8077, 2525, 835, 4048, 1728, 10938, 7535,
+ 545, 2127, 5911, 6992, 10805, 1018, 726, 10996, 10377, 4624,
+ 5374, 5257, 11813, 1254, 1
+};
+
+/**
+ * Bit-reversed indices for n = 512
+ */
+static uint16_t rev_512[] = {
+ 0, 256, 128, 384, 64, 320, 192, 448, 32, 288,
+ 160, 416, 96, 352, 224, 480, 16, 272, 144, 400,
+ 80, 336, 208, 464, 48, 304, 176, 432, 112, 368,
+ 240, 496, 8, 264, 136, 392, 72, 328, 200, 456,
+ 40, 296, 168, 424, 104, 360, 232, 488, 24, 280,
+ 152, 408, 88, 344, 216, 472, 56, 312, 184, 440,
+ 120, 376, 248, 504, 4, 260, 132, 388, 68, 324,
+ 196, 452, 36, 292, 164, 420, 100, 356, 228, 484,
+ 20, 276, 148, 404, 84, 340, 212, 468, 52, 308,
+ 180, 436, 116, 372, 244, 500, 12, 268, 140, 396,
+
+ 76, 332, 204, 460, 44, 300, 172, 428, 108, 364,
+ 236, 492, 28, 284, 156, 412, 92, 348, 220, 476,
+ 60, 316, 188, 444, 124, 380, 252, 508, 2, 258,
+ 130, 386, 66, 322, 194, 450, 34, 290, 162, 418,
+ 98, 354, 226, 482, 18, 274, 146, 402, 82, 338,
+ 210, 466, 50, 306, 178, 434, 114, 370, 242, 498,
+ 10, 266, 138, 394, 74, 330, 202, 458, 42, 298,
+ 170, 426, 106, 362, 234, 490, 26, 282, 154, 410,
+ 90, 346, 218, 474, 58, 314, 186, 442, 122, 378,
+ 250, 506, 6, 262, 134, 390, 70, 326, 198, 454,
+
+ 38, 294, 166, 422, 102, 358, 230, 486, 22, 278,
+ 150, 406, 86, 342, 214, 470, 54, 310, 182, 438,
+ 118, 374, 246, 502, 14, 270, 142, 398, 78, 334,
+ 206, 462, 46, 302, 174, 430, 110, 366, 238, 494,
+ 30, 286, 158, 414, 94, 350, 222, 478, 62, 318,
+ 190, 446, 126, 382, 254, 510, 1, 257, 129, 385,
+ 65, 321, 193, 449, 33, 289, 161, 417, 97, 353,
+ 225, 481, 17, 273, 145, 401, 81, 337, 209, 465,
+ 49, 305, 177, 433, 113, 369, 241, 497, 9, 265,
+ 137, 393, 73, 329, 201, 457, 41, 297, 169, 425,
+
+ 105, 361, 233, 489, 25, 281, 153, 409, 89, 345,
+ 217, 473, 57, 313, 185, 441, 121, 377, 249, 505,
+ 5, 261, 133, 389, 69, 325, 197, 453, 37, 293,
+ 165, 421, 101, 357, 229, 485, 21, 277, 149, 405,
+ 85, 341, 213, 469, 53, 309, 181, 437, 117, 373,
+ 245, 501, 13, 269, 141, 397, 77, 333, 205, 461,
+ 45, 301, 173, 429, 109, 365, 237, 493, 29, 285,
+ 157, 413, 93, 349, 221, 477, 61, 317, 189, 445,
+ 125, 381, 253, 509, 3, 259, 131, 387, 67, 323,
+ 195, 451, 35, 291, 163, 419, 99, 355, 227, 483,
+
+ 19, 275, 147, 403, 83, 339, 211, 467, 51, 307,
+ 179, 435, 115, 371, 243, 499, 11, 267, 139, 395,
+ 75, 331, 203, 459, 43, 299, 171, 427, 107, 363,
+ 235, 491, 27, 283, 155, 411, 91, 347, 219, 475,
+ 59, 315, 187, 443, 123, 379, 251, 507, 7, 263,
+ 135, 391, 71, 327, 199, 455, 39, 295, 167, 423,
+ 103, 359, 231, 487, 23, 279, 151, 407, 87, 343,
+ 215, 471, 55, 311, 183, 439, 119, 375, 247, 503,
+ 15, 271, 143, 399, 79, 335, 207, 463, 47, 303,
+ 175, 431, 111, 367, 239, 495, 31, 287, 159, 415,
+
+ 95, 351, 223, 479, 63, 319, 191, 447, 127, 383,
+ 255, 511
+};
+
+bliss_fft_params_t bliss_fft_12289_512 = {
+ 12289, 512, 12265, 9, w_12289_1024, rev_512
+};
+
+/**
+ * FFT parameters for q = 17 and n = 16
+ */
+static uint16_t w_17_16[] = {
+ 1, 3, 9, 10, 13, 5, 15, 11, 16, 14, 8, 7, 4, 12, 2, 6, 1 };
+
+/**
+ * Bit-reversed indices for n = 8
+ */
+static uint16_t rev_8[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+bliss_fft_params_t bliss_fft_17_8 = { 17, 8, 15, 3, w_17_16, rev_8 };
diff --git a/src/libstrongswan/plugins/bliss/bliss_fft_params.h b/src/libstrongswan/plugins/bliss/bliss_fft_params.h
new file mode 100644
index 000000000..31b151b67
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_fft_params.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_fft_params bliss_fft_params
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_FFT_PARAMS_H_
+#define BLISS_FFT_PARAMS_H_
+
+#include <library.h>
+
+typedef struct bliss_fft_params_t bliss_fft_params_t;
+
+/**
+ * Defines the parameters for an NTT computed via the FFT algorithm
+ */
+struct bliss_fft_params_t {
+
+ /**
+ * Prime modulus
+ */
+ uint16_t q;
+
+ /**
+ * Size of the FFT with the condition k * n = q-1
+ */
+ uint16_t n;
+
+ /**
+ * Inverse of n mod q used for normalization of the FFT
+ */
+ uint16_t n_inv;
+
+ /**
+ * Number of FFT stages stages = log2(n)
+ */
+ uint16_t stages;
+
+ /**
+ * FFT twiddle factors (n-th roots of unity)
+ */
+ uint16_t *w;
+
+ /**
+ * FFT bit reversal
+ */
+ uint16_t *rev;
+
+};
+
+/**
+ * FFT parameters for q = 12289 and n = 512
+ */
+extern bliss_fft_params_t bliss_fft_12289_512;
+
+/**
+ * FFT parameters for q = 17 and n = 8
+ */
+extern bliss_fft_params_t bliss_fft_17_8;
+
+#endif /** BLISS_FFT_PARAMS_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman.c b/src/libstrongswan/plugins/bliss/bliss_huffman.c
new file mode 100644
index 000000000..647234fd8
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2014 Tobias Brunner
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_param_set.h"
+
+#include <library.h>
+
+#include <stdio.h>
+#include <math.h>
+
+typedef struct tuple_t tuple_t;
+
+struct tuple_t {
+ int8_t z1;
+ int8_t z2;
+ uint16_t index;
+ uint16_t bits;
+ uint32_t code;
+};
+
+typedef struct node_t node_t;
+
+struct node_t {
+ node_t *next;
+ node_t *l;
+ node_t *r;
+ tuple_t *tuple;
+ double p;
+ uint16_t depth;
+ uint16_t index;
+};
+
+static void print_node(node_t *node)
+{
+ if (node->tuple)
+ {
+ fprintf(stderr, "(%1d,%2d)", node->tuple->z1, node->tuple->z2);
+ }
+ else
+ {
+ fprintf(stderr, " ");
+ }
+ fprintf(stderr, " %18.16f\n", node->p);
+}
+
+static double code_node(node_t *node, int *index, uint8_t bits, uint32_t code)
+{
+ double code_length = 0;
+
+ node->index = (*index)++;
+
+ if (node->tuple)
+ {
+ node->tuple->code = code;
+ node->tuple->bits = bits;
+ code_length += node->p * bits;
+ }
+ if (node->l)
+ {
+ code_length += code_node(node->l, index, bits + 1, (code << 1));
+ }
+ if (node->r)
+ {
+ code_length += code_node(node->r, index, bits + 1, (code << 1) + 1);
+ }
+
+ return code_length;
+
+}
+
+static void write_node(node_t *node)
+{
+ int16_t node_0, node_1, tuple;
+
+ node_0 = node->l ? node->l->index : BLISS_HUFFMAN_CODE_NO_NODE;
+ node_1 = node->r ? node->r->index : BLISS_HUFFMAN_CODE_NO_NODE;
+ tuple = node->tuple ? node->tuple->index : BLISS_HUFFMAN_CODE_NO_TUPLE;
+
+ printf("\t{ %3d, %3d, %3d }, /* %3d: ", node_0, node_1, tuple, node->index);
+
+ if (node->tuple)
+ {
+ printf("(%d,%2d) %2u bit%s ", node->tuple->z1, node->tuple->z2,
+ node->tuple->bits, (node->tuple->bits == 1) ? " " : "s");
+ }
+ printf("*/\n");
+
+ if (node->l)
+ {
+ write_node(node->l);
+ }
+ if (node->r)
+ {
+ write_node(node->r);
+ }
+}
+
+static void write_header(void)
+{
+ printf("/*\n");
+ printf(" * Copyright (C) 2014 Andreas Steffen\n");
+ printf(" * HSR Hochschule fuer Technik Rapperswil\n");
+ printf(" *\n");
+ printf(" * Optimum Huffman code for BLISS-X signatures\n");
+ printf(" *\n");
+ printf(" * This file has been automatically generated by the"
+ " bliss_huffman utility\n");
+ printf(" * Do not edit manually!\n");
+ printf(" */\n\n");
+};
+
+static void write_code_tables(int bliss_type, int n_z1, int n_z2, node_t *nodes,
+ tuple_t **tuples)
+{
+ int index, i, k;
+ uint32_t bit;
+ double code_length;
+
+ printf("#include \"bliss_huffman_code.h\"\n\n");
+
+ printf("static bliss_huffman_code_node_t nodes[] = {\n");
+ index = 0;
+ code_length = code_node(nodes, &index, 0, 0);
+ write_node(nodes);
+ printf("};\n\n");
+
+ printf("static bliss_huffman_code_tuple_t tuples[] = {\n");
+ index = 0;
+ for (i = 0; i < n_z1; i++)
+ {
+ if (i > 0)
+ {
+ printf("\n");
+ }
+ for (k = 1 - n_z2; k < n_z2; k++)
+ {
+ printf("\t{ %5u, %2u }, /* %3d: (%1d,%2d) ",
+ tuples[index]->code, tuples[index]->bits, index, i, k);
+ bit = 1 << (tuples[index]->bits - 1);
+ while (bit)
+ {
+ printf("%s", (tuples[index]->code & bit) ? "1" : "0");
+ bit >>= 1;
+ }
+ printf(" */\n");
+ index++;
+ }
+ }
+ printf("};\n\n");
+ printf("/* code_length = %6.4f bits/tuple (%d bits) */\n\n",
+ code_length, (int)(512 * code_length + 1));
+
+ printf("bliss_huffman_code_t bliss_huffman_code_%d = {\n", bliss_type);
+ printf("\t.n_z1 = %d,\n", n_z1);
+ printf("\t.n_z2 = %d,\n", n_z2);
+ printf("\t.tuples = tuples,\n");
+ printf("\t.nodes = nodes\n");
+ printf("};\n");
+}
+
+static void destroy_node(node_t *node)
+{
+ if (node->l)
+ {
+ destroy_node(node->l);
+ }
+ if (node->r)
+ {
+ destroy_node(node->r);
+ }
+ free(node->tuple);
+ free(node);
+}
+
+static void remove_node(node_t *list, node_t **last, node_t *node)
+{
+ node_t *current, *prev;
+
+ for (current = list->next, prev = list; current;
+ prev = current, current = current->next)
+ {
+ if (current == node)
+ {
+ prev->next = current->next;
+ if (*last == current)
+ {
+ *last = prev->next ?: prev;
+ }
+ break;
+ }
+ }
+}
+
+/**
+ * Generate a Huffman code for the optimum encoding of BLISS signatures
+ */
+int main(int argc, char *argv[])
+{
+ bliss_param_set_t *set;
+ int dx, bliss_type, depth = 1, groups, groups_left, pairs = 1;
+ int i_max = 9, k_max = 8, index_max = (2*k_max - 1) * i_max;
+ int i, i_top, k, k_top;
+ uint16_t index;
+ double p, p_z1[i_max], p_z2[k_max], x_z1[i_max], x_z2[k_max];
+ double t, x, x0, p_sum, entropy = 0, erf_i, erf_k, erf_0 = 0;
+ tuple_t *tuple, *tuples[index_max];
+ node_t *node, *node_l, *node_r, *nodes = NULL;
+ node_t *node_list, *node_last;
+
+ if (argc < 2)
+ {
+ fprintf(stderr, "usage: bliss_huffman <bliss type> [<pairs>]\n");
+ exit(1);
+ }
+ if (argc > 2)
+ {
+ pairs = atoi(argv[2]);
+ }
+ fprintf(stderr, "%d code pairs with constant length\n\n", pairs);
+ groups_left = groups = pairs >> 1;
+
+ bliss_type = atoi(argv[1]);
+ set = bliss_param_set_get_by_id(bliss_type);
+ if (!set)
+ {
+ fprintf(stderr, "bliss type %d unsupported\n", bliss_type);
+ exit(1);
+ }
+ write_header();
+ printf("/*\n");
+ printf(" * Design: sigma = %u\n", set->sigma);
+ printf(" *\n");
+
+ t = 1/(sqrt(2) * set->sigma);
+
+ /* Probability distribution for z1 */
+ i_top = (set->B_inf + 255) / 256;
+ p_sum = 0;
+ x = 0;
+
+ for (i = 0; i < i_top; i++)
+ {
+ x = min(x + 256, set->B_inf);
+ erf_i = erf(t*x);
+ p_z1[i] = erf_i - erf_0;
+ p_sum += p_z1[i];
+ erf_0 = erf_i;
+ x_z1[i] = x;
+ }
+
+ /* Normalize and print the probability distribution for z1 */
+ printf(" * i p_z1[i]\n");
+ x0 = 0;
+
+ for (i = 0; i < i_top; i++)
+ {
+ p_z1[i] /= p_sum;
+ printf(" * %2d %18.16f %4.0f .. %4.0f\n", i, p_z1[i], x0, x_z1[i]);
+ x0 = x_z1[i];
+ }
+ printf(" *\n");
+
+ /* Probability distribution for z2 */
+ dx = 1 << set->d;
+ k_top = 1 + set->B_inf / dx;
+ x = (dx >> 1) - 0.5;
+ p_sum = 0;
+
+ for (k = 0; k < k_top; k++)
+ {
+
+ erf_k = erf(t*x) / 2;
+ p_z2[k] = (k == 0) ? 2*erf_k : erf_k - erf_0;
+ p_sum += (k == 0) ? p_z2[k] : 2*p_z2[k];
+ erf_0 = erf_k;
+ x_z2[k] = x;
+ x += dx;
+ }
+
+ /* Normalize the probability distribution for z2 */
+ for (k = 0; k < k_top; k++)
+ {
+ p_z2[k] /= p_sum;
+ }
+
+ /* Print the probability distribution for z2 */
+ printf(" * k p_z2[k] dx = %d\n", dx);
+
+ for (k = 1 - k_top; k < k_top; k++)
+ {
+
+ printf(" * %2d %18.16f ",k, p_z2[abs(k)]);
+ if (k < 0)
+ {
+ printf(" %7.1f ..%7.1f\n", -x_z2[-k], -x_z2[-k-1]);
+ }
+ else if (k == 0)
+ {
+ printf(" %7.1f ..%7.1f\n", -x_z2[k], x_z2[k]);
+ }
+ else
+ {
+ printf(" %7.1f ..%7.1f\n", x_z2[k-1], x_z2[k]);
+ }
+ }
+ printf(" *\n");
+
+ /* Compute probabilities of tuples (z1, z2) */
+ INIT(node_list);
+ node_last = node_list;
+ printf(" * (i, k) p\n");
+ p_sum =0;
+ index = 0;
+
+ for (i = 0; i < i_top; i++)
+ {
+ for (k = 1 - k_top; k < k_top; k++)
+ {
+ p = p_z1[i] * p_z2[abs(k)];
+ printf(" * (%1d,%2d) %18.16f\n", i, k, p);
+ p_sum += p;
+ entropy += -log(p) * p;
+
+ INIT(tuple,
+ .z1 = i,
+ .z2 = k,
+ .index = index,
+ );
+ tuples[index++] = tuple;
+
+ INIT(node,
+ .p = p,
+ .tuple = tuple,
+ );
+ node_last->next = node;
+ node_last = node;
+ }
+ printf(" *\n");
+ }
+ entropy /= log(2);
+ printf(" * p_sum %18.16f\n", p_sum);
+ printf(" *\n");
+ printf(" * entropy = %6.4f bits/tuple (%d bits)\n",
+ entropy, (int)(512 * entropy));
+ printf(" */\n\n");
+
+ /* Build Huffman tree */
+ while (node_list->next != node_last)
+ {
+ node_r = node_l = NULL;
+
+ for (node = node_list->next; node; node = node->next)
+ {
+ if (pairs > 0)
+ {
+ if (!node->tuple)
+ {
+ continue;
+ }
+ }
+ else if (groups_left > 0)
+ {
+ if (node->tuple || node->depth != depth)
+ {
+ continue;
+ }
+ }
+ if (node_r == NULL || node->p < node_r->p)
+ {
+ node_l = node_r;
+ node_r = node;
+ }
+ else if (node_l == NULL || node->p < node_l->p)
+ {
+ node_l = node;
+ }
+ }
+
+ INIT(node,
+ .l = node_l,
+ .r = node_r,
+ .p = node_l->p + node_r->p,
+ .depth = 1 + max(node_l->depth, node_r->depth),
+ .tuple = NULL,
+ );
+ print_node(node_r);
+ print_node(node_l);
+ fprintf(stderr, " %18.16f", node->p);
+
+ remove_node(node_list, &node_last, node_l);
+ remove_node(node_list, &node_last, node_r);
+ node_last->next = node;
+ node_last = node;
+
+ if (pairs > 0)
+ {
+ pairs--;
+ }
+ else if (groups > 0)
+ {
+ if (--groups_left == 0)
+ {
+ groups >>= 1;
+ groups_left = groups;
+ depth++;
+ }
+ }
+ fprintf(stderr, "\n\n");
+ }
+
+
+ nodes = node_list->next;
+
+ write_code_tables(bliss_type, i_top, k_top, nodes, tuples);
+
+ destroy_node(nodes);
+ destroy_node(node_list);
+ exit(0);
+}
+
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code.c
new file mode 100644
index 000000000..e31cd9d3c
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_huffman_code.h"
+
+extern bliss_huffman_code_t bliss_huffman_code_1;
+extern bliss_huffman_code_t bliss_huffman_code_3;
+extern bliss_huffman_code_t bliss_huffman_code_4;
+
+/**
+ * See header.
+ */
+bliss_huffman_code_t* bliss_huffman_code_get_by_id(bliss_param_set_id_t id)
+{
+ switch (id)
+ {
+ case BLISS_I:
+ case BLISS_B_I:
+ return &bliss_huffman_code_1;
+ case BLISS_III:
+ case BLISS_B_III:
+ return &bliss_huffman_code_3;
+ case BLISS_IV:
+ case BLISS_B_IV:
+ return &bliss_huffman_code_4;
+ default:
+ return NULL;
+ }
+}
+
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code.h b/src/libstrongswan/plugins/bliss/bliss_huffman_code.h
new file mode 100644
index 000000000..df8511b2e
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_huffman_code bliss_huffman_code
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_HUFFMAN_CODE_H_
+#define BLISS_HUFFMAN_CODE_H_
+
+#include "bliss_param_set.h"
+
+#include <library.h>
+
+typedef struct bliss_huffman_code_t bliss_huffman_code_t;
+typedef struct bliss_huffman_code_tuple_t bliss_huffman_code_tuple_t;
+typedef struct bliss_huffman_code_node_t bliss_huffman_code_node_t;
+
+struct bliss_huffman_code_tuple_t {
+ uint32_t code;
+ uint16_t bits;
+};
+
+#define BLISS_HUFFMAN_CODE_NO_TUPLE -1
+#define BLISS_HUFFMAN_CODE_NO_NODE -1
+
+struct bliss_huffman_code_node_t {
+ int16_t node_0;
+ int16_t node_1;
+ int16_t tuple;
+};
+
+/**
+ * Defines the Huffman code for the optimum encoding of a BLISS signature
+ */
+struct bliss_huffman_code_t {
+
+ /**
+ * Range of z1: 0..n_z1-1
+ */
+ uint16_t n_z1;
+
+ /**
+ * Range of z2: -n_z2..n_z2
+ */
+ uint16_t n_z2;
+
+ /**
+ * Table of tuple codewords
+ */
+ bliss_huffman_code_tuple_t *tuples;
+
+ /**
+ * Table of binary decision nodes
+ */
+ bliss_huffman_code_node_t *nodes;
+};
+
+/**
+ * Get Optimum Huffman code for BLISS signature given by BLISS parameter set ID
+ *
+ * @param id BLISS parameter set ID
+ * @return Optimum Huffman code for BLISS signature
+*/
+bliss_huffman_code_t* bliss_huffman_code_get_by_id(bliss_param_set_id_t id);
+
+#endif /** BLISS_HUFFMAN_CODE_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code_1.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code_1.c
new file mode 100644
index 000000000..1bf433fd1
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code_1.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Optimum Huffman code for BLISS-X signatures
+ *
+ * This file has been automatically generated by the bliss_huffman utility
+ * Do not edit manually!
+ */
+
+/*
+ * Design: sigma = 215
+ *
+ * i p_z1[i]
+ * 0 0.7662277087816564 0 .. 256
+ * 1 0.2165251006508514 256 .. 512
+ * 2 0.0168930510015114 512 .. 768
+ * 3 0.0003522302274478 768 .. 1024
+ * 4 0.0000019067136680 1024 .. 1280
+ * 5 0.0000000026239598 1280 .. 1536
+ * 6 0.0000000000009052 1536 .. 1792
+ * 7 0.0000000000000001 1792 .. 2047
+ *
+ * k p_z2[k] dx = 1024
+ * -1 0.0086781953089156 -1535.5 .. -511.5
+ * 0 0.9826436093821688 -511.5 .. 511.5
+ * 1 0.0086781953089156 511.5 .. 1535.5
+ *
+ * (i, k) p
+ * (0,-1) 0.0066494737079101
+ * (0, 0) 0.7529287613658361
+ * (0, 1) 0.0066494737079101
+ *
+ * (1,-1) 0.0018790471127307
+ * (1, 0) 0.2127670064253900
+ * (1, 1) 0.0018790471127307
+ *
+ * (2,-1) 0.0001466011959546
+ * (2, 0) 0.0165998486096022
+ * (2, 1) 0.0001466011959546
+ *
+ * (3,-1) 0.0000030567227075
+ * (3, 0) 0.0003461167820328
+ * (3, 1) 0.0000030567227075
+ *
+ * (4,-1) 0.0000000165468336
+ * (4, 0) 0.0000018736200007
+ * (4, 1) 0.0000000165468336
+ *
+ * (5,-1) 0.0000000000227712
+ * (5, 0) 0.0000000025784174
+ * (5, 1) 0.0000000000227712
+ *
+ * (6,-1) 0.0000000000000079
+ * (6, 0) 0.0000000000008895
+ * (6, 1) 0.0000000000000079
+ *
+ * (7,-1) 0.0000000000000000
+ * (7, 0) 0.0000000000000001
+ * (7, 1) 0.0000000000000000
+ *
+ * p_sum 0.9999999999999998
+ *
+ * entropy = 1.0195 bits/tuple (521 bits)
+ */
+
+#include "bliss_huffman_code.h"
+
+static bliss_huffman_code_node_t nodes[] = {
+ { 1, 2, -1 }, /* 0: */
+ { -1, -1, 1 }, /* 1: (0, 0) 1 bit */
+ { 3, 4, -1 }, /* 2: */
+ { -1, -1, 4 }, /* 3: (1, 0) 2 bits */
+ { 5, 46, -1 }, /* 4: */
+ { 6, 45, -1 }, /* 5: */
+ { 7, 8, -1 }, /* 6: */
+ { -1, -1, 0 }, /* 7: (0,-1) 5 bits */
+ { 9, 44, -1 }, /* 8: */
+ { 10, 11, -1 }, /* 9: */
+ { -1, -1, 3 }, /* 10: (1,-1) 7 bits */
+ { 12, 13, -1 }, /* 11: */
+ { -1, -1, 10 }, /* 12: (3, 0) 8 bits */
+ { 14, 29, -1 }, /* 13: */
+ { 15, 22, -1 }, /* 14: */
+ { 16, 19, -1 }, /* 15: */
+ { 17, 18, -1 }, /* 16: */
+ { -1, -1, 8 }, /* 17: (2, 1) 12 bits */
+ { -1, -1, 6 }, /* 18: (2,-1) 12 bits */
+ { 20, 21, -1 }, /* 19: */
+ { -1, -1, 11 }, /* 20: (3, 1) 12 bits */
+ { -1, -1, 9 }, /* 21: (3,-1) 12 bits */
+ { 23, 26, -1 }, /* 22: */
+ { 24, 25, -1 }, /* 23: */
+ { -1, -1, 13 }, /* 24: (4, 0) 12 bits */
+ { -1, -1, 14 }, /* 25: (4, 1) 12 bits */
+ { 27, 28, -1 }, /* 26: */
+ { -1, -1, 12 }, /* 27: (4,-1) 12 bits */
+ { -1, -1, 16 }, /* 28: (5, 0) 12 bits */
+ { 30, 37, -1 }, /* 29: */
+ { 31, 34, -1 }, /* 30: */
+ { 32, 33, -1 }, /* 31: */
+ { -1, -1, 17 }, /* 32: (5, 1) 12 bits */
+ { -1, -1, 15 }, /* 33: (5,-1) 12 bits */
+ { 35, 36, -1 }, /* 34: */
+ { -1, -1, 19 }, /* 35: (6, 0) 12 bits */
+ { -1, -1, 20 }, /* 36: (6, 1) 12 bits */
+ { 38, 41, -1 }, /* 37: */
+ { 39, 40, -1 }, /* 38: */
+ { -1, -1, 18 }, /* 39: (6,-1) 12 bits */
+ { -1, -1, 22 }, /* 40: (7, 0) 12 bits */
+ { 42, 43, -1 }, /* 41: */
+ { -1, -1, 23 }, /* 42: (7, 1) 12 bits */
+ { -1, -1, 21 }, /* 43: (7,-1) 12 bits */
+ { -1, -1, 5 }, /* 44: (1, 1) 6 bits */
+ { -1, -1, 2 }, /* 45: (0, 1) 4 bits */
+ { -1, -1, 7 }, /* 46: (2, 0) 3 bits */
+};
+
+static bliss_huffman_code_tuple_t tuples[] = {
+ { 24, 5 }, /* 0: (0,-1) 11000 */
+ { 0, 1 }, /* 1: (0, 0) 0 */
+ { 13, 4 }, /* 2: (0, 1) 1101 */
+
+ { 100, 7 }, /* 3: (1,-1) 1100100 */
+ { 2, 2 }, /* 4: (1, 0) 10 */
+ { 51, 6 }, /* 5: (1, 1) 110011 */
+
+ { 3249, 12 }, /* 6: (2,-1) 110010110001 */
+ { 7, 3 }, /* 7: (2, 0) 111 */
+ { 3248, 12 }, /* 8: (2, 1) 110010110000 */
+
+ { 3251, 12 }, /* 9: (3,-1) 110010110011 */
+ { 202, 8 }, /* 10: (3, 0) 11001010 */
+ { 3250, 12 }, /* 11: (3, 1) 110010110010 */
+
+ { 3254, 12 }, /* 12: (4,-1) 110010110110 */
+ { 3252, 12 }, /* 13: (4, 0) 110010110100 */
+ { 3253, 12 }, /* 14: (4, 1) 110010110101 */
+
+ { 3257, 12 }, /* 15: (5,-1) 110010111001 */
+ { 3255, 12 }, /* 16: (5, 0) 110010110111 */
+ { 3256, 12 }, /* 17: (5, 1) 110010111000 */
+
+ { 3260, 12 }, /* 18: (6,-1) 110010111100 */
+ { 3258, 12 }, /* 19: (6, 0) 110010111010 */
+ { 3259, 12 }, /* 20: (6, 1) 110010111011 */
+
+ { 3263, 12 }, /* 21: (7,-1) 110010111111 */
+ { 3261, 12 }, /* 22: (7, 0) 110010111101 */
+ { 3262, 12 }, /* 23: (7, 1) 110010111110 */
+};
+
+/* code_length = 1.3189 bits/tuple (676 bits) */
+
+bliss_huffman_code_t bliss_huffman_code_1 = {
+ .n_z1 = 8,
+ .n_z2 = 2,
+ .tuples = tuples,
+ .nodes = nodes
+};
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code_3.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code_3.c
new file mode 100644
index 000000000..37a8084d4
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code_3.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Optimum Huffman code for BLISS-X signatures
+ *
+ * This file has been automatically generated by the bliss_huffman utility
+ * Do not edit manually!
+ */
+
+/*
+ * Design: sigma = 250
+ *
+ * i p_z1[i]
+ * 0 0.6941647250930416 0 .. 256
+ * 1 0.2652752755116807 256 .. 512
+ * 2 0.0384337021454129 512 .. 768
+ * 3 0.0020842622589255 768 .. 1024
+ * 4 0.0000417294572050 1024 .. 1280
+ * 5 0.0000003047309681 1280 .. 1536
+ * 6 0.0000000008027661 1536 .. 1760
+ *
+ * k p_z2[k] dx = 512
+ * -3 0.0000001543959154 -1791.5 ..-1279.5
+ * -2 0.0010701394583782 -1279.5 .. -767.5
+ * -1 0.1523201563502276 -767.5 .. -255.5
+ * 0 0.6932190995909575 -255.5 .. 255.5
+ * 1 0.1523201563502276 255.5 .. 767.5
+ * 2 0.0010701394583782 767.5 .. 1279.5
+ * 3 0.0000001543959154 1279.5 .. 1791.5
+ *
+ * (i, k) p
+ * (0,-3) 0.0000001071761982
+ * (0,-2) 0.0007428530629363
+ * (0,-1) 0.1057352794589848
+ * (0, 0) 0.4812082456968029
+ * (0, 1) 0.1057352794589848
+ * (0, 2) 0.0007428530629363
+ * (0, 3) 0.0000001071761982
+ *
+ * (1,-3) 0.0000000409574190
+ * (1,-2) 0.0002838815396572
+ * (1,-1) 0.0404067714417889
+ * (1, 0) 0.1838938876339505
+ * (1, 1) 0.0404067714417889
+ * (1, 2) 0.0002838815396572
+ * (1, 3) 0.0000000409574190
+ *
+ * (2,-3) 0.0000000059340066
+ * (2,-2) 0.0000411294211974
+ * (2,-1) 0.0058542275199074
+ * (2, 0) 0.0266429763951902
+ * (2, 1) 0.0058542275199074
+ * (2, 2) 0.0000411294211974
+ * (2, 3) 0.0000000059340066
+ *
+ * (3,-3) 0.0000000003218016
+ * (3,-2) 0.0000022304512849
+ * (3,-1) 0.0003174751531544
+ * (3, 0) 0.0014448504064437
+ * (3, 1) 0.0003174751531544
+ * (3, 2) 0.0000022304512849
+ * (3, 3) 0.0000000003218016
+ *
+ * (4,-3) 0.0000000000064429
+ * (4,-2) 0.0000000446563387
+ * (4,-1) 0.0000063562374459
+ * (4, 0) 0.0000289276567501
+ * (4, 1) 0.0000063562374459
+ * (4, 2) 0.0000000446563387
+ * (4, 3) 0.0000000000064429
+ *
+ * (5,-3) 0.0000000000000470
+ * (5,-2) 0.0000000003261046
+ * (5,-1) 0.0000000464166687
+ * (5, 0) 0.0000002112453273
+ * (5, 1) 0.0000000464166687
+ * (5, 2) 0.0000000003261046
+ * (5, 3) 0.0000000000000470
+ *
+ * (6,-3) 0.0000000000000001
+ * (6,-2) 0.0000000000008591
+ * (6,-1) 0.0000000001222775
+ * (6, 0) 0.0000000005564928
+ * (6, 1) 0.0000000001222775
+ * (6, 2) 0.0000000000008591
+ * (6, 3) 0.0000000000000001
+ *
+ * p_sum 0.9999999999999999
+ *
+ * entropy = 2.2879 bits/tuple (1171 bits)
+ */
+
+#include "bliss_huffman_code.h"
+
+static bliss_huffman_code_node_t nodes[] = {
+ { 1, 96, -1 }, /* 0: */
+ { 2, 93, -1 }, /* 1: */
+ { 3, 4, -1 }, /* 2: */
+ { -1, -1, 10 }, /* 3: (1, 0) 3 bits */
+ { 5, 8, -1 }, /* 4: */
+ { 6, 7, -1 }, /* 5: */
+ { -1, -1, 11 }, /* 6: (1, 1) 5 bits */
+ { -1, -1, 9 }, /* 7: (1,-1) 5 bits */
+ { 9, 10, -1 }, /* 8: */
+ { -1, -1, 17 }, /* 9: (2, 0) 5 bits */
+ { 11, 92, -1 }, /* 10: */
+ { 12, 13, -1 }, /* 11: */
+ { -1, -1, 16 }, /* 12: (2,-1) 7 bits */
+ { 14, 89, -1 }, /* 13: */
+ { 15, 16, -1 }, /* 14: */
+ { -1, -1, 24 }, /* 15: (3, 0) 9 bits */
+ { 17, 86, -1 }, /* 16: */
+ { 18, 85, -1 }, /* 17: */
+ { 19, 20, -1 }, /* 18: */
+ { -1, -1, 8 }, /* 19: (1,-2) 12 bits */
+ { 21, 84, -1 }, /* 20: */
+ { 22, 53, -1 }, /* 21: */
+ { 23, 38, -1 }, /* 22: */
+ { 24, 31, -1 }, /* 23: */
+ { 25, 28, -1 }, /* 24: */
+ { 26, 27, -1 }, /* 25: */
+ { -1, -1, 15 }, /* 26: (2,-2) 18 bits */
+ { -1, -1, 31 }, /* 27: (4, 0) 18 bits */
+ { 29, 30, -1 }, /* 28: */
+ { -1, -1, 32 }, /* 29: (4, 1) 18 bits */
+ { -1, -1, 30 }, /* 30: (4,-1) 18 bits */
+ { 32, 35, -1 }, /* 31: */
+ { 33, 34, -1 }, /* 32: */
+ { -1, -1, 26 }, /* 33: (3, 2) 18 bits */
+ { -1, -1, 22 }, /* 34: (3,-2) 18 bits */
+ { 36, 37, -1 }, /* 35: */
+ { -1, -1, 38 }, /* 36: (5, 0) 18 bits */
+ { -1, -1, 6 }, /* 37: (0, 3) 18 bits */
+ { 39, 46, -1 }, /* 38: */
+ { 40, 43, -1 }, /* 39: */
+ { 41, 42, -1 }, /* 40: */
+ { -1, -1, 0 }, /* 41: (0,-3) 18 bits */
+ { -1, -1, 39 }, /* 42: (5, 1) 18 bits */
+ { 44, 45, -1 }, /* 43: */
+ { -1, -1, 37 }, /* 44: (5,-1) 18 bits */
+ { -1, -1, 33 }, /* 45: (4, 2) 18 bits */
+ { 47, 50, -1 }, /* 46: */
+ { 48, 49, -1 }, /* 47: */
+ { -1, -1, 29 }, /* 48: (4,-2) 18 bits */
+ { -1, -1, 13 }, /* 49: (1, 3) 18 bits */
+ { 51, 52, -1 }, /* 50: */
+ { -1, -1, 7 }, /* 51: (1,-3) 18 bits */
+ { -1, -1, 20 }, /* 52: (2, 3) 18 bits */
+ { 54, 69, -1 }, /* 53: */
+ { 55, 62, -1 }, /* 54: */
+ { 56, 59, -1 }, /* 55: */
+ { 57, 58, -1 }, /* 56: */
+ { -1, -1, 14 }, /* 57: (2,-3) 18 bits */
+ { -1, -1, 45 }, /* 58: (6, 0) 18 bits */
+ { 60, 61, -1 }, /* 59: */
+ { -1, -1, 40 }, /* 60: (5, 2) 18 bits */
+ { -1, -1, 36 }, /* 61: (5,-2) 18 bits */
+ { 63, 66, -1 }, /* 62: */
+ { 64, 65, -1 }, /* 63: */
+ { -1, -1, 27 }, /* 64: (3, 3) 18 bits */
+ { -1, -1, 21 }, /* 65: (3,-3) 18 bits */
+ { 67, 68, -1 }, /* 66: */
+ { -1, -1, 46 }, /* 67: (6, 1) 18 bits */
+ { -1, -1, 44 }, /* 68: (6,-1) 18 bits */
+ { 70, 77, -1 }, /* 69: */
+ { 71, 74, -1 }, /* 70: */
+ { 72, 73, -1 }, /* 71: */
+ { -1, -1, 34 }, /* 72: (4, 3) 18 bits */
+ { -1, -1, 28 }, /* 73: (4,-3) 18 bits */
+ { 75, 76, -1 }, /* 74: */
+ { -1, -1, 47 }, /* 75: (6, 2) 18 bits */
+ { -1, -1, 43 }, /* 76: (6,-2) 18 bits */
+ { 78, 81, -1 }, /* 77: */
+ { 79, 80, -1 }, /* 78: */
+ { -1, -1, 41 }, /* 79: (5, 3) 18 bits */
+ { -1, -1, 35 }, /* 80: (5,-3) 18 bits */
+ { 82, 83, -1 }, /* 81: */
+ { -1, -1, 48 }, /* 82: (6, 3) 18 bits */
+ { -1, -1, 42 }, /* 83: (6,-3) 18 bits */
+ { -1, -1, 19 }, /* 84: (2, 2) 13 bits */
+ { -1, -1, 25 }, /* 85: (3, 1) 11 bits */
+ { 87, 88, -1 }, /* 86: */
+ { -1, -1, 23 }, /* 87: (3,-1) 11 bits */
+ { -1, -1, 12 }, /* 88: (1, 2) 11 bits */
+ { 90, 91, -1 }, /* 89: */
+ { -1, -1, 5 }, /* 90: (0, 2) 9 bits */
+ { -1, -1, 1 }, /* 91: (0,-2) 9 bits */
+ { -1, -1, 18 }, /* 92: (2, 1) 6 bits */
+ { 94, 95, -1 }, /* 93: */
+ { -1, -1, 4 }, /* 94: (0, 1) 3 bits */
+ { -1, -1, 2 }, /* 95: (0,-1) 3 bits */
+ { -1, -1, 3 }, /* 96: (0, 0) 1 bit */
+};
+
+static bliss_huffman_code_tuple_t tuples[] = {
+ { 59976, 18 }, /* 0: (0,-3) 001110101001001000 */
+ { 119, 9 }, /* 1: (0,-2) 001110111 */
+ { 3, 3 }, /* 2: (0,-1) 011 */
+ { 1, 1 }, /* 3: (0, 0) 1 */
+ { 2, 3 }, /* 4: (0, 1) 010 */
+ { 118, 9 }, /* 5: (0, 2) 001110110 */
+ { 59975, 18 }, /* 6: (0, 3) 001110101001000111 */
+
+ { 59982, 18 }, /* 7: (1,-3) 001110101001001110 */
+ { 936, 12 }, /* 8: (1,-2) 001110101000 */
+ { 5, 5 }, /* 9: (1,-1) 00101 */
+ { 0, 3 }, /* 10: (1, 0) 000 */
+ { 4, 5 }, /* 11: (1, 1) 00100 */
+ { 471, 11 }, /* 12: (1, 2) 00111010111 */
+ { 59981, 18 }, /* 13: (1, 3) 001110101001001101 */
+
+ { 59984, 18 }, /* 14: (2,-3) 001110101001010000 */
+ { 59968, 18 }, /* 15: (2,-2) 001110101001000000 */
+ { 28, 7 }, /* 16: (2,-1) 0011100 */
+ { 6, 5 }, /* 17: (2, 0) 00110 */
+ { 15, 6 }, /* 18: (2, 1) 001111 */
+ { 1875, 13 }, /* 19: (2, 2) 0011101010011 */
+ { 59983, 18 }, /* 20: (2, 3) 001110101001001111 */
+
+ { 59989, 18 }, /* 21: (3,-3) 001110101001010101 */
+ { 59973, 18 }, /* 22: (3,-2) 001110101001000101 */
+ { 470, 11 }, /* 23: (3,-1) 00111010110 */
+ { 116, 9 }, /* 24: (3, 0) 001110100 */
+ { 469, 11 }, /* 25: (3, 1) 00111010101 */
+ { 59972, 18 }, /* 26: (3, 2) 001110101001000100 */
+ { 59988, 18 }, /* 27: (3, 3) 001110101001010100 */
+
+ { 59993, 18 }, /* 28: (4,-3) 001110101001011001 */
+ { 59980, 18 }, /* 29: (4,-2) 001110101001001100 */
+ { 59971, 18 }, /* 30: (4,-1) 001110101001000011 */
+ { 59969, 18 }, /* 31: (4, 0) 001110101001000001 */
+ { 59970, 18 }, /* 32: (4, 1) 001110101001000010 */
+ { 59979, 18 }, /* 33: (4, 2) 001110101001001011 */
+ { 59992, 18 }, /* 34: (4, 3) 001110101001011000 */
+
+ { 59997, 18 }, /* 35: (5,-3) 001110101001011101 */
+ { 59987, 18 }, /* 36: (5,-2) 001110101001010011 */
+ { 59978, 18 }, /* 37: (5,-1) 001110101001001010 */
+ { 59974, 18 }, /* 38: (5, 0) 001110101001000110 */
+ { 59977, 18 }, /* 39: (5, 1) 001110101001001001 */
+ { 59986, 18 }, /* 40: (5, 2) 001110101001010010 */
+ { 59996, 18 }, /* 41: (5, 3) 001110101001011100 */
+
+ { 59999, 18 }, /* 42: (6,-3) 001110101001011111 */
+ { 59995, 18 }, /* 43: (6,-2) 001110101001011011 */
+ { 59991, 18 }, /* 44: (6,-1) 001110101001010111 */
+ { 59985, 18 }, /* 45: (6, 0) 001110101001010001 */
+ { 59990, 18 }, /* 46: (6, 1) 001110101001010110 */
+ { 59994, 18 }, /* 47: (6, 2) 001110101001011010 */
+ { 59998, 18 }, /* 48: (6, 3) 001110101001011110 */
+};
+
+/* code_length = 2.3227 bits/tuple (1190 bits) */
+
+bliss_huffman_code_t bliss_huffman_code_3 = {
+ .n_z1 = 7,
+ .n_z2 = 4,
+ .tuples = tuples,
+ .nodes = nodes
+};
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code_4.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code_4.c
new file mode 100644
index 000000000..c4f709c93
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code_4.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * Optimum Huffman code for BLISS-X signatures
+ *
+ * This file has been automatically generated by the bliss_huffman utility
+ * Do not edit manually!
+ */
+
+/*
+ * Design: sigma = 271
+ *
+ * i p_z1[i]
+ * 0 0.6551621276225426 0 .. 256
+ * 1 0.2859860850630749 256 .. 512
+ * 2 0.0542541135599810 512 .. 768
+ * 3 0.0044399624814222 768 .. 1024
+ * 4 0.0001553928373912 1024 .. 1280
+ * 5 0.0000023066278552 1280 .. 1536
+ * 6 0.0000000118077330 1536 .. 1613
+ *
+ * k p_z2[k] dx = 256
+ * -6 0.0000001026458579 -1663.5 ..-1407.5
+ * -5 0.0000106295703648 -1407.5 ..-1151.5
+ * -4 0.0004651193817805 -1151.5 .. -895.5
+ * -3 0.0086670703658387 -895.5 .. -639.5
+ * -2 0.0693723939195647 -639.5 .. -383.5
+ * -1 0.2404908493690626 -383.5 .. -127.5
+ * 0 0.3619876694950614 -127.5 .. 127.5
+ * 1 0.2404908493690626 127.5 .. 383.5
+ * 2 0.0693723939195647 383.5 .. 639.5
+ * 3 0.0086670703658387 639.5 .. 895.5
+ * 4 0.0004651193817805 895.5 .. 1151.5
+ * 5 0.0000106295703648 1151.5 .. 1407.5
+ * 6 0.0000001026458579 1407.5 .. 1663.5
+ *
+ * (i, k) p
+ * (0,-6) 0.0000000672496787
+ * (0,-5) 0.0000069640919359
+ * (0,-4) 0.0003047286037658
+ * (0,-3) 0.0056783362611372
+ * (0,-2) 0.0454501651986111
+ * (0,-1) 0.1575604965463875
+ * (0, 0) 0.2371606117195102
+ * (0, 1) 0.1575604965463875
+ * (0, 2) 0.0454501651986111
+ * (0, 3) 0.0056783362611372
+ * (0, 4) 0.0003047286037658
+ * (0, 5) 0.0000069640919359
+ * (0, 6) 0.0000000672496787
+ *
+ * (1,-6) 0.0000000293552870
+ * (1,-5) 0.0000030399092145
+ * (1,-4) 0.0001330176710824
+ * (1,-3) 0.0024786615228924
+ * (1,-2) 0.0198395393485098
+ * (1,-1) 0.0687770365045519
+ * (1, 0) 0.1035234364399989
+ * (1, 1) 0.0687770365045519
+ * (1, 2) 0.0198395393485098
+ * (1, 3) 0.0024786615228924
+ * (1, 4) 0.0001330176710824
+ * (1, 5) 0.0000030399092145
+ * (1, 6) 0.0000000293552870
+ *
+ * (2,-6) 0.0000000055689600
+ * (2,-5) 0.0000005766979177
+ * (2,-4) 0.0000252346397581
+ * (2,-3) 0.0004702242198606
+ * (2,-2) 0.0037637377376398
+ * (2,-1) 0.0130476178518054
+ * (2, 0) 0.0196393201280979
+ * (2, 1) 0.0130476178518054
+ * (2, 2) 0.0037637377376398
+ * (2, 3) 0.0004702242198606
+ * (2, 4) 0.0000252346397581
+ * (2, 5) 0.0000005766979177
+ * (2, 6) 0.0000000055689600
+ *
+ * (3,-6) 0.0000000004557438
+ * (3,-5) 0.0000000471948936
+ * (3,-4) 0.0000020651126045
+ * (3,-3) 0.0000384814672482
+ * (3,-2) 0.0003080108262493
+ * (3,-1) 0.0010677703483240
+ * (3, 0) 0.0016072116712955
+ * (3, 1) 0.0010677703483240
+ * (3, 2) 0.0003080108262493
+ * (3, 3) 0.0000384814672482
+ * (3, 4) 0.0000020651126045
+ * (3, 5) 0.0000000471948936
+ * (3, 6) 0.0000000004557438
+ *
+ * (4,-6) 0.0000000000159504
+ * (4,-5) 0.0000000016517591
+ * (4,-4) 0.0000000722762205
+ * (4,-3) 0.0000013468006560
+ * (4,-2) 0.0000107799731278
+ * (4,-1) 0.0000373705554501
+ * (4, 0) 0.0000562502910635
+ * (4, 1) 0.0000373705554501
+ * (4, 2) 0.0000107799731278
+ * (4, 3) 0.0000013468006560
+ * (4, 4) 0.0000000722762205
+ * (4, 5) 0.0000000016517591
+ * (4, 6) 0.0000000000159504
+ *
+ * (5,-6) 0.0000000000002368
+ * (5,-5) 0.0000000000245185
+ * (5,-4) 0.0000000010728573
+ * (5,-3) 0.0000000199917059
+ * (5,-2) 0.0000001600162962
+ * (5,-1) 0.0000005547228921
+ * (5, 0) 0.0000008349708417
+ * (5, 1) 0.0000005547228921
+ * (5, 2) 0.0000001600162962
+ * (5, 3) 0.0000000199917059
+ * (5, 4) 0.0000000010728573
+ * (5, 5) 0.0000000000245185
+ * (5, 6) 0.0000000000002368
+ *
+ * (6,-6) 0.0000000000000012
+ * (6,-5) 0.0000000000001255
+ * (6,-4) 0.0000000000054920
+ * (6,-3) 0.0000000001023385
+ * (6,-2) 0.0000000008191307
+ * (6,-1) 0.0000000028396517
+ * (6, 0) 0.0000000042742538
+ * (6, 1) 0.0000000028396517
+ * (6, 2) 0.0000000008191307
+ * (6, 3) 0.0000000001023385
+ * (6, 4) 0.0000000000054920
+ * (6, 5) 0.0000000000001255
+ * (6, 6) 0.0000000000000012
+ *
+ * p_sum 1.0000000000000011
+ *
+ * entropy = 3.3640 bits/tuple (1722 bits)
+ */
+
+#include "bliss_huffman_code.h"
+
+static bliss_huffman_code_node_t nodes[] = {
+ { 1, 160, -1 }, /* 0: */
+ { 2, 5, -1 }, /* 1: */
+ { 3, 4, -1 }, /* 2: */
+ { -1, -1, 7 }, /* 3: (0, 1) 3 bits */
+ { -1, -1, 5 }, /* 4: (0,-1) 3 bits */
+ { 6, 157, -1 }, /* 5: */
+ { 7, 156, -1 }, /* 6: */
+ { 8, 11, -1 }, /* 7: */
+ { 9, 10, -1 }, /* 8: */
+ { -1, -1, 17 }, /* 9: (1,-2) 6 bits */
+ { -1, -1, 32 }, /* 10: (2, 0) 6 bits */
+ { 12, 155, -1 }, /* 11: */
+ { 13, 18, -1 }, /* 12: */
+ { 14, 15, -1 }, /* 13: */
+ { -1, -1, 3 }, /* 14: (0,-3) 8 bits */
+ { 16, 17, -1 }, /* 15: */
+ { -1, -1, 22 }, /* 16: (1, 3) 9 bits */
+ { -1, -1, 16 }, /* 17: (1,-3) 9 bits */
+ { 19, 154, -1 }, /* 18: */
+ { 20, 23, -1 }, /* 19: */
+ { 21, 22, -1 }, /* 20: */
+ { -1, -1, 46 }, /* 21: (3, 1) 10 bits */
+ { -1, -1, 44 }, /* 22: (3,-1) 10 bits */
+ { 24, 151, -1 }, /* 23: */
+ { 25, 88, -1 }, /* 24: */
+ { 26, 57, -1 }, /* 25: */
+ { 27, 42, -1 }, /* 26: */
+ { 28, 35, -1 }, /* 27: */
+ { 29, 32, -1 }, /* 28: */
+ { 30, 31, -1 }, /* 29: */
+ { -1, -1, 2 }, /* 30: (0,-4) 16 bits */
+ { -1, -1, 23 }, /* 31: (1, 4) 16 bits */
+ { 33, 34, -1 }, /* 32: */
+ { -1, -1, 15 }, /* 33: (1,-4) 16 bits */
+ { -1, -1, 58 }, /* 34: (4, 0) 16 bits */
+ { 36, 39, -1 }, /* 35: */
+ { 37, 38, -1 }, /* 36: */
+ { -1, -1, 48 }, /* 37: (3, 3) 16 bits */
+ { -1, -1, 42 }, /* 38: (3,-3) 16 bits */
+ { 40, 41, -1 }, /* 39: */
+ { -1, -1, 59 }, /* 40: (4, 1) 16 bits */
+ { -1, -1, 57 }, /* 41: (4,-1) 16 bits */
+ { 43, 50, -1 }, /* 42: */
+ { 44, 47, -1 }, /* 43: */
+ { 45, 46, -1 }, /* 44: */
+ { -1, -1, 36 }, /* 45: (2, 4) 16 bits */
+ { -1, -1, 28 }, /* 46: (2,-4) 16 bits */
+ { 48, 49, -1 }, /* 47: */
+ { -1, -1, 60 }, /* 48: (4, 2) 16 bits */
+ { -1, -1, 56 }, /* 49: (4,-2) 16 bits */
+ { 51, 54, -1 }, /* 50: */
+ { 52, 53, -1 }, /* 51: */
+ { -1, -1, 11 }, /* 52: (0, 5) 16 bits */
+ { -1, -1, 1 }, /* 53: (0,-5) 16 bits */
+ { 55, 56, -1 }, /* 54: */
+ { -1, -1, 24 }, /* 55: (1, 5) 16 bits */
+ { -1, -1, 14 }, /* 56: (1,-5) 16 bits */
+ { 58, 73, -1 }, /* 57: */
+ { 59, 66, -1 }, /* 58: */
+ { 60, 63, -1 }, /* 59: */
+ { 61, 62, -1 }, /* 60: */
+ { -1, -1, 49 }, /* 61: (3, 4) 16 bits */
+ { -1, -1, 41 }, /* 62: (3,-4) 16 bits */
+ { 64, 65, -1 }, /* 63: */
+ { -1, -1, 61 }, /* 64: (4, 3) 16 bits */
+ { -1, -1, 55 }, /* 65: (4,-3) 16 bits */
+ { 67, 70, -1 }, /* 66: */
+ { 68, 69, -1 }, /* 67: */
+ { -1, -1, 71 }, /* 68: (5, 0) 16 bits */
+ { -1, -1, 37 }, /* 69: (2, 5) 16 bits */
+ { 71, 72, -1 }, /* 70: */
+ { -1, -1, 27 }, /* 71: (2,-5) 16 bits */
+ { -1, -1, 72 }, /* 72: (5, 1) 16 bits */
+ { 74, 81, -1 }, /* 73: */
+ { 75, 78, -1 }, /* 74: */
+ { 76, 77, -1 }, /* 75: */
+ { -1, -1, 70 }, /* 76: (5,-1) 16 bits */
+ { -1, -1, 73 }, /* 77: (5, 2) 16 bits */
+ { 79, 80, -1 }, /* 78: */
+ { -1, -1, 69 }, /* 79: (5,-2) 16 bits */
+ { -1, -1, 62 }, /* 80: (4, 4) 16 bits */
+ { 82, 85, -1 }, /* 81: */
+ { 83, 84, -1 }, /* 82: */
+ { -1, -1, 54 }, /* 83: (4,-4) 16 bits */
+ { -1, -1, 12 }, /* 84: (0, 6) 16 bits */
+ { 86, 87, -1 }, /* 85: */
+ { -1, -1, 0 }, /* 86: (0,-6) 16 bits */
+ { -1, -1, 50 }, /* 87: (3, 5) 16 bits */
+ { 89, 120, -1 }, /* 88: */
+ { 90, 105, -1 }, /* 89: */
+ { 91, 98, -1 }, /* 90: */
+ { 92, 95, -1 }, /* 91: */
+ { 93, 94, -1 }, /* 92: */
+ { -1, -1, 40 }, /* 93: (3,-5) 16 bits */
+ { -1, -1, 25 }, /* 94: (1, 6) 16 bits */
+ { 96, 97, -1 }, /* 95: */
+ { -1, -1, 13 }, /* 96: (1,-6) 16 bits */
+ { -1, -1, 74 }, /* 97: (5, 3) 16 bits */
+ { 99, 102, -1 }, /* 98: */
+ { 100, 101, -1 }, /* 99: */
+ { -1, -1, 68 }, /* 100: (5,-3) 16 bits */
+ { -1, -1, 38 }, /* 101: (2, 6) 16 bits */
+ { 103, 104, -1 }, /* 102: */
+ { -1, -1, 26 }, /* 103: (2,-6) 16 bits */
+ { -1, -1, 84 }, /* 104: (6, 0) 16 bits */
+ { 106, 113, -1 }, /* 105: */
+ { 107, 110, -1 }, /* 106: */
+ { 108, 109, -1 }, /* 107: */
+ { -1, -1, 85 }, /* 108: (6, 1) 16 bits */
+ { -1, -1, 83 }, /* 109: (6,-1) 16 bits */
+ { 111, 112, -1 }, /* 110: */
+ { -1, -1, 63 }, /* 111: (4, 5) 16 bits */
+ { -1, -1, 53 }, /* 112: (4,-5) 16 bits */
+ { 114, 117, -1 }, /* 113: */
+ { 115, 116, -1 }, /* 114: */
+ { -1, -1, 75 }, /* 115: (5, 4) 16 bits */
+ { -1, -1, 67 }, /* 116: (5,-4) 16 bits */
+ { 118, 119, -1 }, /* 117: */
+ { -1, -1, 86 }, /* 118: (6, 2) 16 bits */
+ { -1, -1, 82 }, /* 119: (6,-2) 16 bits */
+ { 121, 136, -1 }, /* 120: */
+ { 122, 129, -1 }, /* 121: */
+ { 123, 126, -1 }, /* 122: */
+ { 124, 125, -1 }, /* 123: */
+ { -1, -1, 51 }, /* 124: (3, 6) 16 bits */
+ { -1, -1, 39 }, /* 125: (3,-6) 16 bits */
+ { 127, 128, -1 }, /* 126: */
+ { -1, -1, 87 }, /* 127: (6, 3) 16 bits */
+ { -1, -1, 81 }, /* 128: (6,-3) 16 bits */
+ { 130, 133, -1 }, /* 129: */
+ { 131, 132, -1 }, /* 130: */
+ { -1, -1, 76 }, /* 131: (5, 5) 16 bits */
+ { -1, -1, 66 }, /* 132: (5,-5) 16 bits */
+ { 134, 135, -1 }, /* 133: */
+ { -1, -1, 64 }, /* 134: (4, 6) 16 bits */
+ { -1, -1, 52 }, /* 135: (4,-6) 16 bits */
+ { 137, 144, -1 }, /* 136: */
+ { 138, 141, -1 }, /* 137: */
+ { 139, 140, -1 }, /* 138: */
+ { -1, -1, 88 }, /* 139: (6, 4) 16 bits */
+ { -1, -1, 80 }, /* 140: (6,-4) 16 bits */
+ { 142, 143, -1 }, /* 141: */
+ { -1, -1, 77 }, /* 142: (5, 6) 16 bits */
+ { -1, -1, 65 }, /* 143: (5,-6) 16 bits */
+ { 145, 148, -1 }, /* 144: */
+ { 146, 147, -1 }, /* 145: */
+ { -1, -1, 89 }, /* 146: (6, 5) 16 bits */
+ { -1, -1, 79 }, /* 147: (6,-5) 16 bits */
+ { 149, 150, -1 }, /* 148: */
+ { -1, -1, 90 }, /* 149: (6, 6) 16 bits */
+ { -1, -1, 78 }, /* 150: (6,-6) 16 bits */
+ { 152, 153, -1 }, /* 151: */
+ { -1, -1, 29 }, /* 152: (2,-3) 11 bits */
+ { -1, -1, 47 }, /* 153: (3, 2) 11 bits */
+ { -1, -1, 34 }, /* 154: (2, 2) 8 bits */
+ { -1, -1, 33 }, /* 155: (2, 1) 6 bits */
+ { -1, -1, 20 }, /* 156: (1, 1) 4 bits */
+ { 158, 159, -1 }, /* 157: */
+ { -1, -1, 18 }, /* 158: (1,-1) 4 bits */
+ { -1, -1, 8 }, /* 159: (0, 2) 4 bits */
+ { 161, 162, -1 }, /* 160: */
+ { -1, -1, 6 }, /* 161: (0, 0) 2 bits */
+ { 163, 164, -1 }, /* 162: */
+ { -1, -1, 19 }, /* 163: (1, 0) 3 bits */
+ { 165, 166, -1 }, /* 164: */
+ { -1, -1, 4 }, /* 165: (0,-2) 4 bits */
+ { 167, 180, -1 }, /* 166: */
+ { 168, 169, -1 }, /* 167: */
+ { -1, -1, 31 }, /* 168: (2,-1) 6 bits */
+ { 170, 179, -1 }, /* 169: */
+ { 171, 172, -1 }, /* 170: */
+ { -1, -1, 30 }, /* 171: (2,-2) 8 bits */
+ { 173, 174, -1 }, /* 172: */
+ { -1, -1, 45 }, /* 173: (3, 0) 9 bits */
+ { 175, 178, -1 }, /* 174: */
+ { 176, 177, -1 }, /* 175: */
+ { -1, -1, 43 }, /* 176: (3,-2) 11 bits */
+ { -1, -1, 10 }, /* 177: (0, 4) 11 bits */
+ { -1, -1, 35 }, /* 178: (2, 3) 10 bits */
+ { -1, -1, 9 }, /* 179: (0, 3) 7 bits */
+ { -1, -1, 21 }, /* 180: (1, 2) 5 bits */
+};
+
+static bliss_huffman_code_tuple_t tuples[] = {
+ { 19102, 16 }, /* 0: (0,-6) 0100101010011110 */
+ { 19085, 16 }, /* 1: (0,-5) 0100101010001101 */
+ { 19072, 16 }, /* 2: (0,-4) 0100101010000000 */
+ { 72, 8 }, /* 3: (0,-3) 01001000 */
+ { 14, 4 }, /* 4: (0,-2) 1110 */
+ { 1, 3 }, /* 5: (0,-1) 001 */
+ { 2, 2 }, /* 6: (0, 0) 10 */
+ { 0, 3 }, /* 7: (0, 1) 000 */
+ { 7, 4 }, /* 8: (0, 2) 0111 */
+ { 123, 7 }, /* 9: (0, 3) 1111011 */
+ { 1965, 11 }, /* 10: (0, 4) 11110101101 */
+ { 19084, 16 }, /* 11: (0, 5) 0100101010001100 */
+ { 19101, 16 }, /* 12: (0, 6) 0100101010011101 */
+
+ { 19106, 16 }, /* 13: (1,-6) 0100101010100010 */
+ { 19087, 16 }, /* 14: (1,-5) 0100101010001111 */
+ { 19074, 16 }, /* 15: (1,-4) 0100101010000010 */
+ { 147, 9 }, /* 16: (1,-3) 010010011 */
+ { 16, 6 }, /* 17: (1,-2) 010000 */
+ { 6, 4 }, /* 18: (1,-1) 0110 */
+ { 6, 3 }, /* 19: (1, 0) 110 */
+ { 5, 4 }, /* 20: (1, 1) 0101 */
+ { 31, 5 }, /* 21: (1, 2) 11111 */
+ { 146, 9 }, /* 22: (1, 3) 010010010 */
+ { 19073, 16 }, /* 23: (1, 4) 0100101010000001 */
+ { 19086, 16 }, /* 24: (1, 5) 0100101010001110 */
+ { 19105, 16 }, /* 25: (1, 6) 0100101010100001 */
+
+ { 19110, 16 }, /* 26: (2,-6) 0100101010100110 */
+ { 19094, 16 }, /* 27: (2,-5) 0100101010010110 */
+ { 19081, 16 }, /* 28: (2,-4) 0100101010001001 */
+ { 598, 11 }, /* 29: (2,-3) 01001010110 */
+ { 244, 8 }, /* 30: (2,-2) 11110100 */
+ { 60, 6 }, /* 31: (2,-1) 111100 */
+ { 17, 6 }, /* 32: (2, 0) 010001 */
+ { 19, 6 }, /* 33: (2, 1) 010011 */
+ { 75, 8 }, /* 34: (2, 2) 01001011 */
+ { 983, 10 }, /* 35: (2, 3) 1111010111 */
+ { 19080, 16 }, /* 36: (2, 4) 0100101010001000 */
+ { 19093, 16 }, /* 37: (2, 5) 0100101010010101 */
+ { 19109, 16 }, /* 38: (2, 6) 0100101010100101 */
+
+ { 19121, 16 }, /* 39: (3,-6) 0100101010110001 */
+ { 19104, 16 }, /* 40: (3,-5) 0100101010100000 */
+ { 19089, 16 }, /* 41: (3,-4) 0100101010010001 */
+ { 19077, 16 }, /* 42: (3,-3) 0100101010000101 */
+ { 1964, 11 }, /* 43: (3,-2) 11110101100 */
+ { 297, 10 }, /* 44: (3,-1) 0100101001 */
+ { 490, 9 }, /* 45: (3, 0) 111101010 */
+ { 296, 10 }, /* 46: (3, 1) 0100101000 */
+ { 599, 11 }, /* 47: (3, 2) 01001010111 */
+ { 19076, 16 }, /* 48: (3, 3) 0100101010000100 */
+ { 19088, 16 }, /* 49: (3, 4) 0100101010010000 */
+ { 19103, 16 }, /* 50: (3, 5) 0100101010011111 */
+ { 19120, 16 }, /* 51: (3, 6) 0100101010110000 */
+
+ { 19127, 16 }, /* 52: (4,-6) 0100101010110111 */
+ { 19115, 16 }, /* 53: (4,-5) 0100101010101011 */
+ { 19100, 16 }, /* 54: (4,-4) 0100101010011100 */
+ { 19091, 16 }, /* 55: (4,-3) 0100101010010011 */
+ { 19083, 16 }, /* 56: (4,-2) 0100101010001011 */
+ { 19079, 16 }, /* 57: (4,-1) 0100101010000111 */
+ { 19075, 16 }, /* 58: (4, 0) 0100101010000011 */
+ { 19078, 16 }, /* 59: (4, 1) 0100101010000110 */
+ { 19082, 16 }, /* 60: (4, 2) 0100101010001010 */
+ { 19090, 16 }, /* 61: (4, 3) 0100101010010010 */
+ { 19099, 16 }, /* 62: (4, 4) 0100101010011011 */
+ { 19114, 16 }, /* 63: (4, 5) 0100101010101010 */
+ { 19126, 16 }, /* 64: (4, 6) 0100101010110110 */
+
+ { 19131, 16 }, /* 65: (5,-6) 0100101010111011 */
+ { 19125, 16 }, /* 66: (5,-5) 0100101010110101 */
+ { 19117, 16 }, /* 67: (5,-4) 0100101010101101 */
+ { 19108, 16 }, /* 68: (5,-3) 0100101010100100 */
+ { 19098, 16 }, /* 69: (5,-2) 0100101010011010 */
+ { 19096, 16 }, /* 70: (5,-1) 0100101010011000 */
+ { 19092, 16 }, /* 71: (5, 0) 0100101010010100 */
+ { 19095, 16 }, /* 72: (5, 1) 0100101010010111 */
+ { 19097, 16 }, /* 73: (5, 2) 0100101010011001 */
+ { 19107, 16 }, /* 74: (5, 3) 0100101010100011 */
+ { 19116, 16 }, /* 75: (5, 4) 0100101010101100 */
+ { 19124, 16 }, /* 76: (5, 5) 0100101010110100 */
+ { 19130, 16 }, /* 77: (5, 6) 0100101010111010 */
+
+ { 19135, 16 }, /* 78: (6,-6) 0100101010111111 */
+ { 19133, 16 }, /* 79: (6,-5) 0100101010111101 */
+ { 19129, 16 }, /* 80: (6,-4) 0100101010111001 */
+ { 19123, 16 }, /* 81: (6,-3) 0100101010110011 */
+ { 19119, 16 }, /* 82: (6,-2) 0100101010101111 */
+ { 19113, 16 }, /* 83: (6,-1) 0100101010101001 */
+ { 19111, 16 }, /* 84: (6, 0) 0100101010100111 */
+ { 19112, 16 }, /* 85: (6, 1) 0100101010101000 */
+ { 19118, 16 }, /* 86: (6, 2) 0100101010101110 */
+ { 19122, 16 }, /* 87: (6, 3) 0100101010110010 */
+ { 19128, 16 }, /* 88: (6, 4) 0100101010111000 */
+ { 19132, 16 }, /* 89: (6, 5) 0100101010111100 */
+ { 19134, 16 }, /* 90: (6, 6) 0100101010111110 */
+};
+
+/* code_length = 3.3967 bits/tuple (1740 bits) */
+
+bliss_huffman_code_t bliss_huffman_code_4 = {
+ .n_z1 = 7,
+ .n_z2 = 7,
+ .tuples = tuples,
+ .nodes = nodes
+};
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c
new file mode 100644
index 000000000..018ae0efa
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY;https://www.hsr.ch/HSR-intern-Anmeldung.4409.0.html?&no_cache=1 without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_huffman_coder.h"
+
+typedef struct private_bliss_huffman_coder_t private_bliss_huffman_coder_t;
+
+/**
+ * Private data structure for bliss_huffman_coder_t object
+ */
+struct private_bliss_huffman_coder_t {
+ /**
+ * Public interface.
+ */
+ bliss_huffman_coder_t public;
+
+ /**
+ * Bitpacker to write to or read from
+ */
+ bliss_bitpacker_t *packer;
+
+ /**
+ * Huffman code table to be used
+ */
+ bliss_huffman_code_t *code;
+
+ /**
+ * Maximum index into tuples table
+ */
+ int index_max;
+
+ /**
+ * Number of encoded or decoded bits
+ */
+ size_t bits;
+
+};
+
+METHOD(bliss_huffman_coder_t, get_bits, size_t,
+ private_bliss_huffman_coder_t *this)
+{
+ return this->bits;
+}
+
+METHOD(bliss_huffman_coder_t, encode, bool,
+ private_bliss_huffman_coder_t *this, int32_t z1, int16_t z2)
+{
+ uint32_t code;
+ uint16_t bits;
+ int index;
+
+ index = z1 * (2*this->code->n_z2 - 1) + z2 + this->code->n_z2 - 1;
+ if (index >= this->index_max)
+ {
+ DBG1(DBG_LIB, "index exceeded in Huffman encoding table");
+ return FALSE;
+ }
+ code = this->code->tuples[index].code;
+ bits = this->code->tuples[index].bits;
+ if (!this->packer->write_bits(this->packer, code, bits))
+ {
+ DBG1(DBG_LIB, "bitpacker exceeded its buffer");
+ return FALSE;
+ }
+ this->bits += bits;
+
+ return TRUE;
+}
+
+METHOD(bliss_huffman_coder_t, decode, bool,
+ private_bliss_huffman_coder_t *this, int32_t *z1, int16_t *z2)
+{
+ bliss_huffman_code_node_t *node;
+ uint32_t bit;
+
+ node = this->code->nodes;
+ while (node->tuple == BLISS_HUFFMAN_CODE_NO_TUPLE)
+ {
+ if (node->node_0 == BLISS_HUFFMAN_CODE_NO_NODE ||
+ node->node_1 == BLISS_HUFFMAN_CODE_NO_NODE)
+ {
+ DBG1(DBG_LIB, "error in Huffman decoding table");
+ return FALSE;
+ }
+ if (!this->packer->read_bits(this->packer, &bit, 1))
+ {
+ DBG1(DBG_LIB, "bitpacker depleted its buffer");
+ return FALSE;
+ }
+ node = &this->code->nodes[bit ? node->node_1 : node->node_0];
+ this->bits++;
+ }
+ *z1 = node->tuple / (2*this->code->n_z2 - 1);
+ *z2 = node->tuple - (2*this->code->n_z2 - 1) * (*z1) - this->code->n_z2 + 1;
+
+ return TRUE;
+}
+
+METHOD(bliss_huffman_coder_t, destroy, void,
+ private_bliss_huffman_coder_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header.
+ */
+bliss_huffman_coder_t *bliss_huffman_coder_create(bliss_huffman_code_t *code,
+ bliss_bitpacker_t *packer)
+{
+ private_bliss_huffman_coder_t *this;
+
+ INIT(this,
+ .public = {
+ .get_bits = _get_bits,
+ .encode = _encode,
+ .decode = _decode,
+ .destroy = _destroy,
+ },
+ .packer = packer,
+ .code = code,
+ .index_max = (2*code->n_z2 - 1) * code->n_z1,
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_coder.h b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.h
new file mode 100644
index 000000000..59abc49c6
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_huffman_coder bliss_huffman_coder
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_HUFFMAN_CODER_H_
+#define BLISS_HUFFMAN_CODER_H_
+
+#include "bliss_huffman_code.h"
+#include "bliss_bitpacker.h"
+
+#include <library.h>
+
+typedef struct bliss_huffman_coder_t bliss_huffman_coder_t;
+
+/**
+ * Encodes and decodes binary Huffman codes
+ */
+struct bliss_huffman_coder_t {
+
+ /**
+ * Get number of encoded or decoded bits
+ *
+ * @result Number of bits
+ */
+ size_t (*get_bits)(bliss_huffman_coder_t *this);
+
+ /**
+ * Encode a (z1, z2) tuple using a Huffman code
+ *
+ * @param z1 z1 value to be encoded
+ * @param z2 z2 value to be encoded
+ * @result TRUE if value could be encoded
+ */
+ bool (*encode)(bliss_huffman_coder_t *this, int32_t z1, int16_t z2);
+
+
+ /**
+ * Decode a (z1, z2) tuple using a Huffman code
+ *
+ * @param z1 Decoded z1 value returned
+ * @param z2 Decoded z2 value returned
+ * @result TRUE if value could be decoded from bitpacker
+ */
+ bool (*decode)(bliss_huffman_coder_t *this, int32_t *z1, int16_t *z2);
+
+ /**
+ * Destroy bliss_huffman_coder_t object
+ */
+ void (*destroy)(bliss_huffman_coder_t *this);
+};
+
+/**
+ * Create a bliss_huffman_coder_t object
+ *
+ * @param code Huffman code table
+ * @param packer Bitpacker to write to or read from
+ */
+bliss_huffman_coder_t* bliss_huffman_coder_create(bliss_huffman_code_t *code,
+ bliss_bitpacker_t *packer);
+
+#endif /** BLISS_HUFFMAN_CODER_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_param_set.c b/src/libstrongswan/plugins/bliss/bliss_param_set.c
new file mode 100644
index 000000000..3781a588f
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_param_set.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_param_set.h"
+
+#include <asn1/oid.h>
+
+ENUM(bliss_param_set_id_names, BLISS_I, BLISS_B_IV,
+ "BLISS-I",
+ "BLISS-II",
+ "BLISS-III",
+ "BLISS-IV",
+ "BLISS-B-I",
+ "BLISS-B-II",
+ "BLISS-B-III",
+ "BLISS-B-IV"
+);
+
+/**
+ * sigma = 215, k_sigma = ceiling[ sqrt(2*ln 2) * sigma ] = 254
+ *
+ * c[i] = exp(-2^i/f), i = 0..20, with f = k_sigma^2 / ln 2 = 93'076.9
+ */
+static uint8_t c_bliss_i[] = {
+ 255, 255, 75, 191, 247, 94, 30, 51, 147, 246, 89, 59, 99, 248, 26, 128,
+ 255, 254, 151, 128, 109, 166, 88, 143, 30, 175, 149, 20, 240, 81, 138, 111,
+ 255, 253, 47, 2, 214, 243, 188, 76, 236, 235, 40, 62, 54, 35, 33, 205,
+ 255, 250, 94, 13, 156, 120, 121, 216, 255, 120, 90, 11, 39, 232, 120, 111,
+ 255, 244, 188, 58, 242, 219, 157, 174, 6, 31, 131, 75, 88, 109, 112, 107,
+ 255, 233, 120, 244, 202, 151, 25, 10, 197, 109, 113, 255, 157, 89, 182, 141,
+ 255, 210, 243, 229, 18, 88, 50, 239, 130, 192, 12, 167, 62, 254, 211, 202,
+ 255, 165, 239, 183, 102, 186, 123, 249, 251, 59, 116, 143, 50, 174, 125, 198,
+ 255, 75, 255, 30, 65, 137, 228, 148, 14, 17, 113, 251, 81, 177, 151, 168,
+ 254, 152, 124, 205, 192, 136, 102, 79, 5, 62, 214, 95, 36, 223, 7, 20,
+ 253, 50, 242, 124, 187, 59, 68, 224, 90, 156, 53, 202, 9, 44, 191, 226,
+ 250, 109, 189, 110, 40, 124, 88, 12, 83, 78, 176, 86, 12, 102, 13, 41,
+ 244, 250, 133, 6, 3, 13, 45, 9, 120, 121, 150, 237, 69, 190, 62, 16,
+ 234, 110, 130, 187, 138, 174, 82, 229, 217, 154, 88, 138, 228, 153, 230, 13,
+ 214, 174, 54, 179, 117, 116, 223, 152, 97, 84, 31, 99, 68, 150, 122, 244,
+ 180, 7, 186, 2, 112, 3, 68, 13, 123, 133, 244, 184, 232, 216, 133, 18,
+ 126, 154, 221, 207, 32, 206, 66, 171, 94, 100, 164, 194, 117, 191, 1, 209,
+ 62, 156, 208, 7, 129, 173, 200, 3, 23, 248, 140, 60, 69, 217, 195, 235,
+ 15, 80, 84, 209, 213, 2, 107, 160, 1, 152, 43, 130, 93, 95, 241, 218,
+ 0, 234, 131, 37, 182, 53, 201, 231, 26, 2, 151, 161, 13, 214, 150, 145,
+ 0, 0, 214, 212, 4, 32, 184, 94, 84, 90, 244, 139, 48, 69, 33, 38
+};
+
+/**
+ * sigma = 250, k_sigma = ceiling[ sqrt(2*ln 2) * sigma ] = 295
+ *
+ * c[i] = exp(-2^i/f), i = 0..20, with f = k_sigma^2 / ln 2 = 125'550.5
+ */
+static uint8_t c_bliss_iii[] = {
+ 255, 255, 122, 95, 16, 128, 14, 195, 60, 90, 166, 191, 205, 26, 144, 204,
+ 255, 254, 244, 190, 102, 192, 187, 141, 169, 92, 33, 30, 170, 141, 184, 56,
+ 255, 253, 233, 125, 228, 131, 93, 148, 121, 92, 52, 122, 149, 96, 29, 66,
+ 255, 251, 211, 0, 37, 9, 199, 244, 213, 217, 122, 205, 171, 200, 198, 5,
+ 255, 247, 166, 17, 185, 251, 90, 150, 1, 28, 7, 205, 125, 46, 84, 201,
+ 255, 239, 76, 105, 50, 114, 159, 235, 215, 165, 204, 182, 125, 143, 228, 222,
+ 255, 222, 153, 233, 85, 187, 45, 204, 236, 229, 38, 180, 20, 161, 7, 167,
+ 255, 189, 56, 46, 38, 4, 83, 8, 151, 137, 136, 1, 9, 180, 58, 204,
+ 255, 122, 129, 199, 240, 52, 248, 193, 76, 26, 160, 32, 195, 250, 217, 25,
+ 254, 245, 73, 44, 68, 229, 150, 74, 228, 74, 124, 249, 123, 94, 108, 127,
+ 253, 235, 168, 56, 252, 93, 188, 160, 249, 137, 236, 65, 62, 182, 153, 63,
+ 251, 219, 163, 110, 233, 251, 114, 216, 230, 35, 59, 210, 107, 100, 184, 16,
+ 247, 200, 110, 236, 134, 237, 213, 111, 240, 149, 109, 22, 216, 213, 237, 145,
+ 239, 212, 98, 249, 238, 1, 227, 248, 242, 51, 211, 134, 154, 115, 189, 83,
+ 224, 174, 65, 2, 190, 158, 9, 6, 184, 13, 130, 104, 247, 102, 38, 160,
+ 197, 49, 104, 97, 61, 210, 19, 115, 208, 54, 91, 27, 209, 227, 33, 26,
+ 151, 229, 20, 46, 200, 238, 35, 134, 72, 183, 253, 160, 193, 155, 117, 103,
+ 90, 32, 10, 204, 78, 83, 191, 230, 0, 221, 219, 6, 43, 252, 185, 95,
+ 31, 186, 139, 154, 90, 155, 17, 9, 42, 139, 40, 111, 246, 175, 4, 15,
+ 3, 238, 181, 190, 138, 94, 50, 234, 128, 193, 95, 36, 65, 236, 170, 208,
+ 0, 15, 118, 216, 230, 142, 121, 211, 13, 168, 207, 126, 145, 176, 24, 201
+};
+
+/**
+ * sigma = 271, k_sigma = ceiling[ sqrt(2*ln 2) * sigma ] = 320
+ *
+ * c[i] = exp(-2^i/f), i = 0..21, with f = k_sigma^2 / ln 2 = 147'732.0
+ */
+static uint8_t c_bliss_iv[] = {
+ 255, 255, 142, 111, 102, 2, 141, 87, 150, 42, 18, 70, 6, 224, 18, 70,
+ 255, 255, 28, 222, 254, 102, 20, 78, 133, 78, 189, 107, 29, 7, 23, 193,
+ 255, 254, 57, 190, 198, 79, 181, 181, 108, 75, 142, 145, 45, 238, 193, 29,
+ 255, 252, 115, 128, 178, 170, 212, 166, 120, 157, 85, 96, 209, 180, 211, 83,
+ 255, 248, 231, 13, 253, 108, 245, 46, 238, 155, 30, 99, 141, 228, 149, 239,
+ 255, 241, 206, 78, 90, 132, 83, 172, 228, 179, 119, 115, 240, 51, 216, 6,
+ 255, 227, 157, 102, 46, 28, 61, 128, 58, 114, 174, 136, 8, 224, 133, 84,
+ 255, 199, 61, 242, 19, 216, 133, 241, 240, 22, 146, 43, 92, 57, 82, 248,
+ 255, 142, 136, 121, 160, 225, 119, 214, 241, 44, 159, 34, 133, 118, 96, 60,
+ 255, 29, 67, 61, 254, 49, 27, 152, 48, 124, 184, 87, 66, 214, 63, 133,
+ 254, 59, 79, 77, 206, 26, 238, 42, 69, 81, 191, 149, 146, 76, 255, 232,
+ 252, 121, 191, 28, 11, 107, 141, 223, 234, 42, 226, 50, 138, 102, 16, 97,
+ 248, 255, 234, 37, 109, 169, 103, 25, 240, 109, 93, 165, 177, 22, 133, 100,
+ 242, 48, 213, 124, 209, 49, 33, 48, 57, 237, 202, 62, 102, 132, 219, 48,
+ 229, 32, 92, 240, 188, 88, 70, 34, 179, 94, 244, 70, 25, 123, 76, 140,
+ 205, 18, 234, 94, 14, 226, 237, 76, 192, 18, 240, 50, 79, 63, 34, 96,
+ 164, 71, 76, 192, 111, 161, 157, 188, 19, 189, 133, 246, 67, 127, 6, 28,
+ 105, 107, 110, 50, 56, 199, 208, 174, 16, 95, 153, 106, 217, 198, 194, 179,
+ 43, 105, 77, 122, 127, 254, 146, 221, 44, 235, 61, 22, 179, 9, 113, 118,
+ 7, 92, 139, 87, 204, 239, 111, 200, 41, 129, 122, 49, 69, 113, 122, 239,
+ 0, 54, 49, 19, 64, 40, 218, 222, 60, 82, 186, 246, 64, 155, 184, 47,
+ 0, 0, 11, 120, 189, 135, 113, 62, 143, 175, 118, 239, 190, 120, 189, 250
+};
+
+/**
+ * BLISS signature parameter set definitions
+ */
+static bliss_param_set_t bliss_param_sets[] = {
+
+ /* BLISS-I scheme */
+ {
+ .id = BLISS_I,
+ .oid = OID_BLISS_I,
+ .strength = 128,
+ .q = 12289,
+ .q_bits = 14,
+ .q2_inv = 6145,
+ .n = 512,
+ .n_bits = 9,
+ .fft_params = &bliss_fft_12289_512,
+ .non_zero1 = 154,
+ .non_zero2 = 0,
+ .kappa = 23,
+ .nks_max = 46479,
+ .p_max = 0, /* not needed */
+ .sigma = 215,
+ .k_sigma = 254,
+ .k_sigma_bits = 8,
+ .c = c_bliss_i,
+ .c_cols = 16,
+ .c_rows = 21,
+ .z1_bits = 12,
+ .d = 10,
+ .p = 24,
+ .M = 46539, /* with alpha = 1.000 */
+ .B_inf = 2047, /* reduced from 2100 due to 12 bit z1 encoding */
+ .B_l2 = 12872 * 12872
+ },
+
+ /* BLISS-III scheme */
+ {
+ .id = BLISS_III,
+ .oid = OID_BLISS_III,
+ .strength = 160,
+ .q = 12289,
+ .q_bits = 14,
+ .q2_inv = 6145,
+ .n = 512,
+ .n_bits = 9,
+ .fft_params = &bliss_fft_12289_512,
+ .non_zero1 = 216,
+ .non_zero2 = 16,
+ .kappa = 30,
+ .nks_max = 128626,
+ .p_max = 0, /* not needed */
+ .sigma = 250,
+ .k_sigma = 295,
+ .k_sigma_bits = 9,
+ .c = c_bliss_iii,
+ .c_cols = 16,
+ .c_rows = 21,
+ .z1_bits = 12,
+ .d = 9,
+ .p = 48,
+ .M = 128113, /* with alpha = 0.700 */
+ .B_inf = 1760,
+ .B_l2 = 10206 * 10206
+ },
+
+ /* BLISS-IV scheme */
+ {
+ .id = BLISS_IV,
+ .oid = OID_BLISS_IV,
+ .strength = 192,
+ .q = 12289,
+ .q_bits = 14,
+ .q2_inv = 6145,
+ .n = 512,
+ .n_bits = 9,
+ .fft_params = &bliss_fft_12289_512,
+ .non_zero1 = 231,
+ .non_zero2 = 31,
+ .kappa = 39,
+ .nks_max = 244669,
+ .p_max = 0, /* not needed */
+ .sigma = 271,
+ .k_sigma = 320,
+ .k_sigma_bits = 9,
+ .c = c_bliss_iv,
+ .c_cols = 16,
+ .c_rows = 22,
+ .z1_bits = 12,
+ .d = 8,
+ .p = 96,
+ .M = 244186, /* with alpha = 0.550 */
+ .B_inf = 1613,
+ .B_l2 = 9901 * 9901
+ },
+
+ /* BLISS-B-I scheme */
+ {
+ .id = BLISS_B_I,
+ .oid = OID_BLISS_B_I,
+ .strength = 128,
+ .q = 12289,
+ .q_bits = 14,
+ .q2_inv = 6145,
+ .n = 512,
+ .n_bits = 9,
+ .fft_params = &bliss_fft_12289_512,
+ .non_zero1 = 154,
+ .non_zero2 = 0,
+ .kappa = 23,
+ .nks_max = 0, /* not needed */
+ .p_max = 17825,
+ .sigma = 215,
+ .k_sigma = 254,
+ .k_sigma_bits = 8,
+ .c = c_bliss_i,
+ .c_cols = 16,
+ .c_rows = 21,
+ .z1_bits = 12,
+ .d = 10,
+ .p = 24,
+ .M = 17954, /* with alpha = 1.610 */
+ .B_inf = 2047, /* reduced from 2100 due to 12 bit z1 encoding */
+ .B_l2 = 12872 * 12872
+ },
+
+ /* BLISS-B-III scheme */
+ {
+ .id = BLISS_B_III,
+ .oid = OID_BLISS_B_III,
+ .strength = 160,
+ .q = 12289,
+ .q_bits = 14,
+ .q2_inv = 6145,
+ .n = 512,
+ .n_bits = 9,
+ .fft_params = &bliss_fft_12289_512,
+ .non_zero1 = 216,
+ .non_zero2 = 16,
+ .kappa = 30,
+ .nks_max = 0, /* not needed */
+ .p_max = 42270,
+ .sigma = 250,
+ .k_sigma = 295,
+ .k_sigma_bits = 9,
+ .c = c_bliss_iii,
+ .c_cols = 16,
+ .c_rows = 21,
+ .z1_bits = 12,
+ .d = 9,
+ .p = 48,
+ .M = 42455, /* with alpha = 1.216 */
+ .B_inf = 1760,
+ .B_l2 = 10206 * 10206
+ },
+
+ /* BLISS-B-IV scheme */
+ {
+ .id = BLISS_B_IV,
+ .oid = OID_BLISS_B_IV,
+ .strength = 192,
+ .q = 12289,
+ .q_bits = 14,
+ .q2_inv = 6145,
+ .n = 512,
+ .n_bits = 9,
+ .fft_params = &bliss_fft_12289_512,
+ .non_zero1 = 231,
+ .non_zero2 = 31,
+ .kappa = 39,
+ .nks_max = 0, /* not needed */
+ .p_max = 69576,
+ .sigma = 271,
+ .k_sigma = 320,
+ .k_sigma_bits = 9,
+ .c = c_bliss_iv,
+ .c_cols = 16,
+ .c_rows = 22,
+ .z1_bits = 12,
+ .d = 8,
+ .p = 96,
+ .M = 70034, /* with alpha = 1.027 */
+ .B_inf = 1613,
+ .B_l2 = 9901 * 9901
+ }
+
+};
+
+/**
+ * See header.
+ */
+bliss_param_set_t* bliss_param_set_get_by_id(bliss_param_set_id_t id)
+{
+ int i;
+
+ for (i = 0; i < countof(bliss_param_sets); i++)
+ {
+ if (bliss_param_sets[i].id == id)
+ {
+ return &bliss_param_sets[i];
+ }
+ }
+ return NULL;
+}
+
+
+/**
+ * See header.
+ */
+bliss_param_set_t* bliss_param_set_get_by_oid(int oid)
+{
+ int i;
+
+ for (i = 0; i < countof(bliss_param_sets); i++)
+ {
+ if (bliss_param_sets[i].oid == oid)
+ {
+ return &bliss_param_sets[i];
+ }
+ }
+ return NULL;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_param_set.h b/src/libstrongswan/plugins/bliss/bliss_param_set.h
new file mode 100644
index 000000000..33a8009ff
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_param_set.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_param_set bliss_param_set
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_PARAM_SET_H_
+#define BLISS_PARAM_SET_H_
+
+typedef enum bliss_param_set_id_t bliss_param_set_id_t;
+typedef struct bliss_param_set_t bliss_param_set_t;
+
+#include "bliss_fft_params.h"
+#include "bliss_huffman_code.h"
+
+#include <library.h>
+
+/**
+ * BLISS signature parameter set ID list
+ */
+enum bliss_param_set_id_t {
+ BLISS_I = 1,
+ BLISS_II = 2,
+ BLISS_III = 3,
+ BLISS_IV = 4,
+ BLISS_B_I = 5,
+ BLISS_B_II = 6,
+ BLISS_B_III = 7,
+ BLISS_B_IV = 8
+};
+
+extern enum_name_t *bliss_param_set_id_names;
+
+/**
+ * BLISS
+ */
+struct bliss_param_set_t {
+
+ /**
+ * BLISS parameter set ID
+ */
+ bliss_param_set_id_t id;
+
+ /**
+ * BLISS parameter set OID
+ */
+ int oid;
+
+ /**
+ * Security strength in bits
+ */
+ uint16_t strength;
+
+ /**
+ * Prime modulus
+ */
+ uint16_t q;
+
+ /**
+ * Number of bits in q
+ */
+ uint16_t q_bits;
+
+ /**
+ * Inverse of (q + 2) mod 2q
+ */
+ uint16_t q2_inv;
+
+ /**
+ * Ring dimension equal to the number of polynomial coefficients
+ */
+ uint16_t n;
+
+ /**
+ * Number of bits in n
+ */
+ uint16_t n_bits;
+
+ /**
+ * FFT parameters
+ */
+ bliss_fft_params_t *fft_params;
+
+ /**
+ * Number of [-1, +1] secret key coefficients
+ */
+ uint16_t non_zero1;
+
+ /**
+ * Number of [-2, +2] secret key coefficients
+ */
+ uint16_t non_zero2;
+
+ /**
+ * Number of secret key terms that go into Nk(S) norm
+ */
+ uint16_t kappa;
+
+ /**
+ * Maximum Nk(S) tolerable NK(S) norm (BLISS only)
+ */
+ uint32_t nks_max;
+
+ /**
+ * Maximum value Pmax for ||Sc'||^2 norm (BLISS-B only)
+ */
+ uint32_t p_max;
+
+ /**
+ * Standard deviation sigma
+ */
+ uint16_t sigma;
+
+ /**
+ * k_sigma = ceiling[ sqrt(2*ln 2) * sigma ]
+ */
+ uint16_t k_sigma;
+
+ /**
+ * Number of bits in k_sigma
+ */
+ uint16_t k_sigma_bits;
+
+ /**
+ * Coefficients for Bernoulli sampling with exponential biases
+ */
+ uint8_t *c;
+
+ /**
+ * Number of columns in Bernoulli coefficient table
+ */
+ size_t c_cols;
+
+ /**
+ * Number of rows in Bernoulli coefficient table
+ */
+ size_t c_rows;
+
+ /**
+ * Number of bits in z1
+ */
+ uint16_t z1_bits;
+
+ /**
+ * Number of z2 bits to be dropped after rounding
+ */
+ uint16_t d;
+
+ /**
+ * Modulus p = floor(2q / 2^d) applied after bit dropping
+ */
+ uint16_t p;
+
+ /**
+ * M = sigma^2 / alpha_rejection^2
+ */
+ uint32_t M;
+
+ /**
+ * B_infinity bound
+ */
+ uint16_t B_inf;
+
+ /**
+ * B_verify bound
+ */
+ uint32_t B_l2;
+
+};
+
+/**
+ * Get BLISS signature parameter set by BLISS parameter set ID
+ *
+ * @param id BLISS parameter set ID
+ * @return BLISS parameter set
+*/
+bliss_param_set_t* bliss_param_set_get_by_id(bliss_param_set_id_t id);
+
+/**
+ * Get BLISS signature parameter set by BLISS parameter set OID
+ *
+ * @param oid BLISS parameter set OID
+ * @return BLISS parameter set
+*/
+bliss_param_set_t* bliss_param_set_get_by_oid(int oid);
+
+#endif /** BLISS_PARAM_SET_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_plugin.c b/src/libstrongswan/plugins/bliss/bliss_plugin.c
new file mode 100644
index 000000000..07597c318
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_plugin.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_plugin.h"
+#include "bliss_private_key.h"
+#include "bliss_public_key.h"
+
+#include <library.h>
+
+typedef struct private_bliss_plugin_t private_bliss_plugin_t;
+
+/**
+ * private data of bliss_plugin
+ */
+struct private_bliss_plugin_t {
+
+ /**
+ * public functions
+ */
+ bliss_plugin_t public;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_bliss_plugin_t *this)
+{
+ return "bliss";
+}
+
+METHOD(plugin_t, get_features, int,
+ private_bliss_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ /* private/public keys */
+ PLUGIN_REGISTER(PRIVKEY, bliss_private_key_load, TRUE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_BLISS),
+ PLUGIN_REGISTER(PRIVKEY, bliss_private_key_load, TRUE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
+ PLUGIN_REGISTER(PRIVKEY_GEN, bliss_private_key_gen, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_BLISS),
+ PLUGIN_DEPENDS(RNG, RNG_TRUE),
+ PLUGIN_REGISTER(PUBKEY, bliss_public_key_load, TRUE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_BLISS),
+ PLUGIN_REGISTER(PUBKEY, bliss_public_key_load, TRUE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
+ /* signature schemes, private */
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA256),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA256),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA384),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA384),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA512),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA512),
+ /* signature verification schemes */
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA256),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA256),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA384),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA384),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA512),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA512),
+ };
+ *features = f;
+
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_bliss_plugin_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *bliss_plugin_create()
+{
+ private_bliss_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ );
+
+ return &this->public.plugin;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_plugin.h b/src/libstrongswan/plugins/bliss/bliss_plugin.h
new file mode 100644
index 000000000..d3d80ac5d
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_p bliss
+ * @ingroup plugins
+ *
+ * @defgroup bliss_plugin bliss_plugin
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_PLUGIN_H_
+#define BLISS_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct bliss_plugin_t bliss_plugin_t;
+
+/**
+ * Plugin implementing the BLISS post-quantu authentication algorithm
+ */
+struct bliss_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** BLISS_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_private_key.c b/src/libstrongswan/plugins/bliss/bliss_private_key.c
new file mode 100644
index 000000000..e1064d2f2
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_private_key.c
@@ -0,0 +1,1316 @@
+/*
+ * Copyright (C) 2014-2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * 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 "bliss_private_key.h"
+#include "bliss_public_key.h"
+#include "bliss_param_set.h"
+#include "bliss_utils.h"
+#include "bliss_sampler.h"
+#include "bliss_signature.h"
+#include "bliss_bitpacker.h"
+#include "bliss_fft.h"
+
+#include <crypto/mgf1/mgf1_bitspender.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+
+typedef struct private_bliss_private_key_t private_bliss_private_key_t;
+
+#define SECRET_KEY_TRIALS_MAX 50
+
+/**
+ * Private data of a bliss_private_key_t object.
+ */
+struct private_bliss_private_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ bliss_private_key_t public;
+
+ /**
+ * BLISS signature parameter set
+ */
+ bliss_param_set_t *set;
+
+ /**
+ * BLISS secret key S1 (coefficients of polynomial f)
+ */
+ int8_t *s1;
+
+ /**
+ * BLISS secret key S2 (coefficients of polynomial 2g + 1)
+ */
+ int8_t *s2;
+
+ /**
+ * NTT of BLISS public key a (coefficients of polynomial (2g + 1)/f)
+ */
+ uint32_t *A;
+
+ /**
+ * reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(private_key_t, get_type, key_type_t,
+ private_bliss_private_key_t *this)
+{
+ return KEY_BLISS;
+}
+
+/**
+ * Multiply secret vector s with binary challenge vector c
+ */
+static void multiply_by_c(int8_t *s, int n, uint16_t *c_indices,
+ uint16_t kappa, int32_t *product)
+{
+ int i, j, index;
+
+ for (i = 0; i < n; i++)
+ {
+ product[i] = 0;
+
+ for (j = 0; j < kappa; j++)
+ {
+ index = c_indices[j];
+ if (i - index < 0)
+ {
+ product[i] -= s[i - index + n];
+ }
+ else
+ {
+ product[i] += s[i - index];
+ }
+ }
+ }
+}
+
+/**
+ * BLISS-B GreedySC algorithm
+ */
+static void greedy_sc(int8_t *s1, int8_t *s2, int n, uint16_t *c_indices,
+ uint16_t kappa, int32_t *v1, int32_t *v2)
+{
+ int i, j, index;
+ int32_t sign;
+
+ for (i = 0; i < n; i++)
+ {
+ v1[i] = v2[i] = 0;
+ }
+ for (j = 0; j < kappa; j++)
+ {
+ index = c_indices[j];
+ sign = 0;
+
+ for (i = 0; i < index; i++)
+ {
+ sign -= (v1[i] * s1[i - index + n] + v2[i] * s2[i - index + n]);
+ }
+ for (i = index; i < n; i++)
+ {
+ sign += (v1[i] * s1[i - index] + v2[i] * s2[i - index]);
+ }
+ for (i = 0; i < index; i++)
+ {
+ if (sign > 0)
+ {
+ v1[i] += s1[i - index + n];
+ v2[i] += s2[i - index + n];
+ }
+ else
+ {
+ v1[i] -= s1[i - index + n];
+ v2[i] -= s2[i - index + n];
+ }
+ }
+ for (i = index; i < n; i++)
+ {
+ if (sign > 0)
+ {
+ v1[i] -= s1[i - index];
+ v2[i] -= s2[i - index];
+ }
+ else
+ {
+ v1[i] += s1[i - index];
+ v2[i] += s2[i - index];
+ }
+ }
+ }
+}
+
+/**
+ * Compute a BLISS signature
+ */
+static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
+ chunk_t data, chunk_t *signature)
+{
+ bliss_fft_t *fft;
+ bliss_signature_t *sig;
+ bliss_sampler_t *sampler = NULL;
+ rng_t *rng;
+ hasher_t *hasher;
+ hash_algorithm_t mgf1_alg;
+ size_t mgf1_seed_len;
+ uint8_t mgf1_seed_buf[HASH_SIZE_SHA512], data_hash_buf[HASH_SIZE_SHA512];
+ chunk_t mgf1_seed, data_hash;
+ uint16_t q, q2, p, p2, *c_indices, tests = 0;
+ uint32_t *ay;
+ int32_t *y1, *y2, *z1, *z2, *u, *s1c, *s2c;
+ int32_t y1_min = 0, y1i, y1_max = 0, y2_min = 0, y2i, y2_max = 0;
+ int32_t scalar, norm, ui;
+ int16_t *ud, *uz2d, *z2d, value;
+ int i, n;
+ double mean1 = 0, mean2 = 0, sigma1 = 0, sigma2 = 0;
+ bool accepted, positive, success = FALSE, use_bliss_b;
+
+ /* Initialize signature */
+ *signature = chunk_empty;
+
+ /* Create data hash */
+ hasher = lib->crypto->create_hasher(lib->crypto, alg);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+ data_hash = chunk_create(data_hash_buf, hasher->get_hash_size(hasher));
+
+ if (!hasher->get_hash(hasher, data, data_hash_buf))
+ {
+ hasher->destroy(hasher);
+ return FALSE;
+ }
+ hasher->destroy(hasher);
+
+ /* Create SHA512 hasher for c_indices oracle */
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+
+ /* Set MGF1 hash algorithm and seed length based on security strength */
+ if (this->set->strength > 160)
+ {
+ mgf1_alg = HASH_SHA256;
+ mgf1_seed_len = HASH_SIZE_SHA256;
+ }
+ else
+ {
+ mgf1_alg = HASH_SHA1;
+ mgf1_seed_len = HASH_SIZE_SHA1;
+ }
+ mgf1_seed = chunk_create(mgf1_seed_buf, mgf1_seed_len);
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ if (!rng)
+ {
+ hasher->destroy(hasher);
+ return FALSE;
+ }
+
+ /* Initialize a couple of needed variables */
+ n = this->set->n;
+ q = this->set->q;
+ p = this->set->p;
+ q2 = 2 * q;
+ p2 = p / 2;
+ ay = malloc(n * sizeof(uint32_t));
+ z2 = malloc(n * sizeof(int32_t));
+ s1c = malloc(n * sizeof(int32_t));
+ s2c = malloc(n * sizeof(int32_t));
+ u = malloc(n * sizeof(int32_t));
+ uz2d = malloc(n * sizeof(int16_t));
+
+ sig = bliss_signature_create(this->set);
+ sig->get_parameters(sig, &z1, &z2d, &c_indices);
+ y1 = z1;
+ y2 = z2;
+ ud = z2d;
+
+ fft = bliss_fft_create(this->set->fft_params);
+
+ /* Use of the enhanced BLISS-B signature algorithm? */
+ switch (this->set->id)
+ {
+ default:
+ case BLISS_I:
+ case BLISS_II:
+ case BLISS_III:
+ case BLISS_IV:
+ use_bliss_b = FALSE;
+ break;
+ case BLISS_B_I:
+ case BLISS_B_II:
+ case BLISS_B_III:
+ case BLISS_B_IV:
+ use_bliss_b = TRUE;
+ break;
+ }
+
+ while (true)
+ {
+ tests++;
+
+ if (!rng->get_bytes(rng, mgf1_seed_len, mgf1_seed_buf))
+ {
+ goto end;
+ }
+ DESTROY_IF(sampler);
+
+ sampler = bliss_sampler_create(mgf1_alg, mgf1_seed, this->set);
+ if (!sampler)
+ {
+ goto end;
+ }
+
+ /* Gaussian sampling for vectors y1 and y2 */
+ for (i = 0; i < n; i++)
+ {
+ if (!sampler->gaussian(sampler, &y1i) ||
+ !sampler->gaussian(sampler, &y2i))
+ {
+ goto end;
+ }
+ y1[i] = y1i;
+ y2[i] = y2i;
+
+ /* Collect statistical data on rejection sampling */
+ if (i == 0)
+ {
+ y1_min = y1_max = y1i;
+ y2_min = y2_max = y2i;
+ }
+ else
+ {
+ if (y1i < y1_min)
+ {
+ y1_min = y1i;
+ }
+ else if (y1i > y1_max)
+ {
+ y1_max = y1i;
+ }
+ if (y2i < y2_min)
+ {
+ y2_min = y2i;
+ }
+ else if (y2i > y2_max)
+ {
+ y2_max = y2i;
+ }
+ }
+ mean1 += y1i;
+ mean2 += y2i;
+ sigma1 += y1i * y1i;
+ sigma2 += y2i * y2i;
+
+ ay[i] = y1i < 0 ? q + y1i : y1i;
+ }
+
+ /* Compute statistics on vectors y1 and y2 */
+ mean1 /= n;
+ mean2 /= n;
+ sigma1 /= n;
+ sigma2 /= n;
+ sigma2 -= mean1 * mean1;
+ sigma2 -= mean2 * mean2;
+ DBG2(DBG_LIB, "y1 = %d..%d (sigma2 = %5.0f, mean = %4.1f)",
+ y1_min, y1_max, sigma1, mean1);
+ DBG2(DBG_LIB, "y2 = %d..%d (sigma2 = %5.0f, mean = %4.1f)",
+ y2_min, y2_max, sigma2, mean2);
+
+ fft->transform(fft, ay, ay, FALSE);
+
+ for (i = 0; i < n; i++)
+ {
+ ay[i] = (this->A[i] * ay[i]) % q;
+ }
+ fft->transform(fft, ay, ay, TRUE);
+
+ for (i = 0; i < n; i++)
+ {
+ ui = 2 * this->set->q2_inv * (int32_t)ay[i] + y2[i];
+ u[i] = ((ui < 0) ? q2 + ui : ui) % q2;
+ }
+ bliss_utils_round_and_drop(this->set, u, ud);
+
+ /* Detailed debugging information */
+ DBG3(DBG_LIB, " i u[i] ud[i]");
+ for (i = 0; i < n; i++)
+ {
+ DBG3(DBG_LIB, "%3d %6d %4d", i, u[i], ud[i]);
+ }
+
+ if (!bliss_utils_generate_c(hasher, data_hash, ud, n, this->set->kappa,
+ c_indices))
+ {
+ goto end;
+ }
+
+ if (use_bliss_b)
+ {
+ /* Compute v = (s1c, s2c) with the GreedySC algorithm */
+ greedy_sc(this->s1, this->s2, n, c_indices, this->set->kappa,
+ s1c, s2c);
+
+ /* Compute norm = ||v||^2 = ||Sc'||^2 */
+ norm = bliss_utils_scalar_product(s1c, s1c, n) +
+ bliss_utils_scalar_product(s2c, s2c, n);
+
+ /* Just in case. ||v||^2 <= P_max should always be fulfilled */
+ if (norm > this->set->p_max)
+ {
+ goto end;
+ }
+ }
+ else
+ {
+ /* Compute s*c */
+ multiply_by_c(this->s1, n, c_indices, this->set->kappa, s1c);
+ multiply_by_c(this->s2, n, c_indices, this->set->kappa, s2c);
+
+ /* Compute norm = |Sc||^2 */
+ norm = bliss_utils_scalar_product(s1c, s1c, n) +
+ bliss_utils_scalar_product(s2c, s2c, n);
+ }
+
+ if (!sampler->bernoulli_exp(sampler, this->set->M - norm, &accepted))
+ {
+ goto end;
+ }
+ if (use_bliss_b)
+ {
+ DBG2(DBG_LIB, "norm2(s1*c') + norm2(s2*c') = %u (%u max), %s",
+ norm, this->set->p_max, accepted ? "accepted" : "rejected");
+
+ }
+ else
+ {
+ DBG2(DBG_LIB, "norm2(s1*c) + norm2(s2*c) = %u, %s",
+ norm, accepted ? "accepted" : "rejected");
+ }
+ if (!accepted)
+ {
+ continue;
+ }
+
+ /* Compute z */
+ if (!sampler->sign(sampler, &positive))
+ {
+ goto end;
+ }
+ for (i = 0; i < n; i++)
+ {
+ if (positive)
+ {
+ z1[i] = y1[i] + s1c[i];
+ z2[i] = y2[i] + s2c[i];
+ }
+ else
+ {
+ z1[i] = y1[i] - s1c[i];
+ z2[i] = y2[i] - s2c[i];
+ }
+ }
+ /* Reject with probability 1/cosh(scalar/sigma^2) */
+ scalar = bliss_utils_scalar_product(z1, s1c, n) +
+ bliss_utils_scalar_product(z2, s2c, n);
+
+ if (!sampler->bernoulli_cosh(sampler, scalar, &accepted))
+ {
+ goto end;
+ }
+ DBG2(DBG_LIB, "scalar(z1,s1*c) + scalar(z2,s2*c) = %d, %s",
+ scalar, accepted ? "accepted" : "rejected");
+ if (!accepted)
+ {
+ continue;
+ }
+
+ /* Compute z2 with dropped bits */
+ for (i = 0; i < n; i++)
+ {
+ u[i] -= z2[i];
+ if (u[i] < 0)
+ {
+ u[i] += q2;
+ }
+ else if (u[i] >= q2)
+ {
+ u[i] -= q2;
+ }
+ }
+ bliss_utils_round_and_drop(this->set, u, uz2d);
+
+ for (i = 0; i < n; i++)
+ {
+ value = ud[i] - uz2d[i];
+ if (value <= -p2)
+ {
+ value += p;
+ }
+ else if (value > p2)
+ {
+ value -= p;
+ }
+ z2d[i] = value;
+ }
+
+ if (!bliss_utils_check_norms(this->set, z1, z2d))
+ {
+ continue;
+ }
+
+ *signature = sig->get_encoding(sig);
+ if (signature->len == 0)
+ {
+ DBG1(DBG_LIB, "inefficient Huffman coding of signature");
+ continue;
+ }
+ DBG2(DBG_LIB, "signature generation needed %u round%s", tests,
+ (tests == 1) ? "" : "s");
+ break;
+ }
+ success = TRUE;
+
+end:
+ /* cleanup */
+ DESTROY_IF(sampler);
+ hasher->destroy(hasher);
+ sig->destroy(sig);
+ fft->destroy(fft);
+ rng->destroy(rng);
+ memwipe(s1c, n * sizeof(int32_t));
+ memwipe(s2c, n * sizeof(int32_t));
+ free(s1c);
+ free(s2c);
+ free(ay);
+ free(z2);
+ free(u);
+ free(uz2d);
+
+ return success;
+}
+
+METHOD(private_key_t, sign, bool,
+ private_bliss_private_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t *signature)
+{
+ switch (scheme)
+ {
+ case SIGN_BLISS_WITH_SHA256:
+ return sign_bliss(this, HASH_SHA256, data, signature);
+ case SIGN_BLISS_WITH_SHA384:
+ return sign_bliss(this, HASH_SHA384, data, signature);
+ case SIGN_BLISS_WITH_SHA512:
+ return sign_bliss(this, HASH_SHA512, data, signature);
+ default:
+ DBG1(DBG_LIB, "signature scheme %N not supported with BLISS",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+METHOD(private_key_t, decrypt, bool,
+ private_bliss_private_key_t *this, encryption_scheme_t scheme,
+ chunk_t crypto, chunk_t *plain)
+{
+ DBG1(DBG_LIB, "encryption scheme %N not supported",
+ encryption_scheme_names, scheme);
+ return FALSE;
+}
+
+METHOD(private_key_t, get_keysize, int,
+ private_bliss_private_key_t *this)
+{
+ return this->set->strength;
+}
+
+METHOD(private_key_t, get_public_key, public_key_t*,
+ private_bliss_private_key_t *this)
+{
+ public_key_t *public;
+ chunk_t pubkey;
+
+ pubkey = bliss_public_key_info_encode(this->set->oid, this->A, this->set);
+ public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_BLISS,
+ BUILD_BLOB_ASN1_DER, pubkey, BUILD_END);
+ free(pubkey.ptr);
+
+ return public;
+}
+
+METHOD(private_key_t, get_encoding, bool,
+ private_bliss_private_key_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
+{
+ switch (type)
+ {
+ case PRIVKEY_ASN1_DER:
+ case PRIVKEY_PEM:
+ {
+ chunk_t s1, s2, pubkey;
+ bliss_bitpacker_t *packer;
+ size_t s_bits;
+ int8_t value;
+ bool success = TRUE;
+ int i;
+
+ pubkey = bliss_public_key_encode(this->A, this->set);
+
+ /* Use either 2 or 3 bits per array element */
+ s_bits = 2 + (this->set->non_zero2 > 0);
+
+ /* Encode secret s1 */
+ packer = bliss_bitpacker_create(s_bits * this->set->n);
+ for (i = 0; i < this->set->n; i++)
+ {
+ packer->write_bits(packer, this->s1[i], s_bits);
+ }
+ s1 = packer->extract_buf(packer);
+ packer->destroy(packer);
+
+ /* Encode secret s2 */
+ packer = bliss_bitpacker_create(s_bits * this->set->n);
+ for (i = 0; i < this->set->n; i++)
+ {
+ value = this->s2[i];
+ if (i == 0)
+ {
+ value -= 1;
+ }
+ value /= 2;
+ packer->write_bits(packer, value, s_bits);
+ }
+ s2 = packer->extract_buf(packer);
+ packer->destroy(packer);
+
+ *encoding = asn1_wrap(ASN1_SEQUENCE, "mmss",
+ asn1_build_known_oid(this->set->oid),
+ asn1_bitstring("m", pubkey),
+ asn1_bitstring("m", s1),
+ asn1_bitstring("m", s2)
+ );
+ if (type == PRIVKEY_PEM)
+ {
+ chunk_t asn1_encoding = *encoding;
+
+ success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM,
+ NULL, encoding, CRED_PART_BLISS_PRIV_ASN1_DER,
+ asn1_encoding, CRED_PART_END);
+ chunk_clear(&asn1_encoding);
+ }
+ return success;
+ }
+ default:
+ return FALSE;
+ }
+}
+
+METHOD(private_key_t, get_fingerprint, bool,
+ private_bliss_private_key_t *this, cred_encoding_type_t type, chunk_t *fp)
+{
+ bool success;
+
+ if (lib->encoding->get_cache(lib->encoding, type, this, fp))
+ {
+ return TRUE;
+ }
+ success = bliss_public_key_fingerprint(this->set->oid, this->A,
+ this->set, type, fp);
+ if (success)
+ {
+ lib->encoding->cache(lib->encoding, type, this, *fp);
+ }
+ return success;
+}
+
+METHOD(private_key_t, get_ref, private_key_t*,
+ private_bliss_private_key_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.key;
+}
+
+METHOD(private_key_t, destroy, void,
+ private_bliss_private_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ lib->encoding->clear_cache(lib->encoding, this);
+ if (this->s1)
+ {
+ memwipe(this->s1, this->set->n * sizeof(int8_t));
+ free(this->s1);
+ }
+ if (this->s2)
+ {
+ memwipe(this->s2, this->set->n * sizeof(int8_t));
+ free(this->s2);
+ }
+ free(this->A);
+ free(this);
+ }
+}
+
+/**
+ * Internal generic constructor
+ */
+static private_bliss_private_key_t *bliss_private_key_create_empty(void)
+{
+ private_bliss_private_key_t *this;
+
+ INIT(this,
+ .public = {
+ .key = {
+ .get_type = _get_type,
+ .sign = _sign,
+ .decrypt = _decrypt,
+ .get_keysize = _get_keysize,
+ .get_public_key = _get_public_key,
+ .equals = private_key_equals,
+ .belongs_to = private_key_belongs_to,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = private_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .ref = 1,
+ );
+ return this;
+}
+
+/**
+ * Compute the scalar product of a vector x with a negative wrapped vector y
+ */
+static int16_t wrapped_product(int8_t *x, int8_t *y, int n, int shift)
+{
+ int16_t product = 0;
+ int i;
+
+ for (i = 0; i < n - shift; i++)
+ {
+ product += x[i] * y[i + shift];
+ }
+ for (i = n - shift; i < n; i++)
+ {
+ product -= x[i] * y[i + shift - n];
+ }
+ return product;
+}
+
+/**
+ * Apply a negative wrapped rotation to a vector x
+ */
+static void wrap(int16_t *x, int n, int shift, int16_t *x_wrapped)
+{
+ int i;
+
+ for (i = 0; i < n - shift; i++)
+ {
+ x_wrapped[i + shift] = x[i];
+ }
+ for (i = n - shift; i < n; i++)
+ {
+ x_wrapped[i + shift - n] = -x[i];
+ }
+}
+
+/**
+ * int16_t compare function needed for qsort()
+ */
+static int compare(const int16_t *a, const int16_t *b)
+{
+ int16_t temp = *a - *b;
+
+ if (temp > 0)
+ {
+ return 1;
+ }
+ else if (temp < 0)
+ {
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/**
+ * Compute the Nk(S) norm of S = (s1, s2)
+ */
+static uint32_t nks_norm(int8_t *s1, int8_t *s2, int n, uint16_t kappa)
+{
+ int16_t t[n], t_wrapped[n], max_kappa[n];
+ uint32_t nks = 0;
+ int i, j;
+
+ for (i = 0; i < n; i++)
+ {
+ t[i] = wrapped_product(s1, s1, n, i) + wrapped_product(s2, s2, n, i);
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ wrap(t, n, i, t_wrapped);
+ qsort(t_wrapped, n, sizeof(int16_t), (__compar_fn_t)compare);
+ max_kappa[i] = 0;
+
+ for (j = 1; j <= kappa; j++)
+ {
+ max_kappa[i] += t_wrapped[n - j];
+ }
+ }
+ qsort(max_kappa, n, sizeof(int16_t), (__compar_fn_t)compare);
+
+ for (i = 1; i <= kappa; i++)
+ {
+ nks += max_kappa[n - i];
+ }
+ return nks;
+}
+
+/**
+ * Compute the inverse x1 of x modulo q as x^(-1) = x^(q-2) mod q
+ */
+static uint32_t invert(uint32_t x, uint16_t q)
+{
+ uint32_t x1, x2;
+ uint16_t q2;
+ int i, i_max;
+
+ q2 = q - 2;
+ x1 = (q2 & 1) ? x : 1;
+ x2 = x;
+ i_max = 15;
+
+ while ((q2 & (1 << i_max)) == 0)
+ {
+ i_max--;
+ }
+ for (i = 1; i <= i_max; i++)
+ {
+ x2 = (x2 * x2) % q;
+
+ if (q2 & (1 << i))
+ {
+ x1 = (x1 * x2) % q;
+ }
+ }
+
+ return x1;
+}
+
+/**
+ * Create a vector with sparse and small coefficients from seed
+ */
+static int8_t* create_vector_from_seed(private_bliss_private_key_t *this,
+ hash_algorithm_t alg, chunk_t seed)
+{
+ mgf1_bitspender_t *bitspender;
+ uint32_t index, sign;
+ int8_t *vector;
+ int non_zero;
+
+ bitspender = mgf1_bitspender_create(alg, seed, FALSE);
+ if (!bitspender)
+ {
+ return NULL;
+ }
+
+ vector = malloc(sizeof(int8_t) * this->set->n);
+ memset(vector, 0x00, this->set->n);
+
+ non_zero = this->set->non_zero1;
+ while (non_zero)
+ {
+ if (!bitspender->get_bits(bitspender, this->set->n_bits, &index))
+ {
+ free(vector);
+ return NULL;
+ }
+ if (vector[index] != 0)
+ {
+ continue;
+ }
+
+ if (!bitspender->get_bits(bitspender, 1, &sign))
+ {
+ free(vector);
+ return NULL;
+ }
+ vector[index] = sign ? 1 : -1;
+ non_zero--;
+ }
+
+ non_zero = this->set->non_zero2;
+ while (non_zero)
+ {
+ if (!bitspender->get_bits(bitspender, this->set->n_bits, &index))
+ {
+ free(vector);
+ return NULL;
+ }
+ if (vector[index] != 0)
+ {
+ continue;
+ }
+
+ if (!bitspender->get_bits(bitspender, 1, &sign))
+ {
+ free(vector);
+ return NULL;
+ }
+ vector[index] = sign ? 2 : -2;
+ non_zero--;
+ }
+ bitspender->destroy(bitspender);
+
+ return vector;
+}
+
+/**
+ * Generate the secret key S = (s1, s2) fulfilling the Nk(S) norm
+ */
+static bool create_secret(private_bliss_private_key_t *this, rng_t *rng,
+ int8_t **s1, int8_t **s2, int *trials)
+{
+ uint8_t seed_buf[32];
+ uint8_t *f, *g;
+ uint32_t l2_norm, nks;
+ int i, n;
+ chunk_t seed;
+ size_t seed_len;
+ hash_algorithm_t alg;
+
+ n = this->set->n;
+ *s1 = NULL;
+ *s2 = NULL;
+
+ /* Set MGF1 hash algorithm and seed length based on security strength */
+ if (this->set->strength > 160)
+ {
+ alg = HASH_SHA256;
+ seed_len = HASH_SIZE_SHA256;
+ }
+ else
+ {
+ alg = HASH_SHA1;
+ seed_len = HASH_SIZE_SHA1;
+ }
+ seed = chunk_create(seed_buf, seed_len);
+
+ while (*trials < SECRET_KEY_TRIALS_MAX)
+ {
+ (*trials)++;
+
+ if (!rng->get_bytes(rng, seed_len, seed_buf))
+ {
+ return FALSE;
+ }
+ f = create_vector_from_seed(this, alg, seed);
+ if (f == NULL)
+ {
+ return FALSE;
+ }
+ if (!rng->get_bytes(rng, seed_len, seed_buf))
+ {
+ free(f);
+ return FALSE;
+ }
+ g = create_vector_from_seed(this, alg, seed);
+ if (g == NULL)
+ {
+ free(f);
+ return FALSE;
+ }
+
+ /* Compute 2g + 1 */
+ for (i = 0; i < n; i++)
+ {
+ g[i] *= 2;
+ }
+ g[0] += 1;
+
+ l2_norm = wrapped_product(f, f, n, 0) + wrapped_product(g, g, n, 0);
+ nks = nks_norm(f, g, n, this->set->kappa);
+
+ switch (this->set->id)
+ {
+ case BLISS_I:
+ case BLISS_II:
+ case BLISS_III:
+ case BLISS_IV:
+ DBG2(DBG_LIB, "l2 norm of s1||s2: %d, Nk(S): %u (%u max)",
+ l2_norm, nks, this->set->nks_max);
+ if (nks < this->set->nks_max)
+ {
+ *s1 = f;
+ *s2 = g;
+ return TRUE;
+ }
+ free(f);
+ free(g);
+ break;
+ case BLISS_B_I:
+ case BLISS_B_II:
+ case BLISS_B_III:
+ case BLISS_B_IV:
+ DBG2(DBG_LIB, "l2 norm of s1||s2: %d, Nk(S): %u",
+ l2_norm, nks);
+ *s1 = f;
+ *s2 = g;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ * See header.
+ */
+bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
+{
+ private_bliss_private_key_t *this;
+ u_int key_size = BLISS_B_I;
+ int i, n, trials = 0;
+ uint32_t *S1, *S2, *a;
+ uint16_t q;
+ bool success = FALSE;
+ bliss_param_set_t *set;
+ bliss_fft_t *fft;
+ rng_t *rng;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_KEY_SIZE:
+ key_size = va_arg(args, u_int);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ if (lib->settings->get_bool(lib->settings, "%s.plugins.bliss.use_bliss_b",
+ TRUE, lib->ns))
+ {
+ switch (key_size)
+ {
+ case BLISS_I:
+ key_size = BLISS_B_I;
+ break;
+ case BLISS_II:
+ key_size = BLISS_B_II;
+ break;
+ case BLISS_III:
+ key_size = BLISS_B_III;
+ break;
+ case BLISS_IV:
+ key_size = BLISS_B_IV;
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Only BLISS or BLISS-B types I, III, or IV are currently supported */
+ set = bliss_param_set_get_by_id(key_size);
+ if (!set)
+ {
+ DBG1(DBG_LIB, "BLISS parameter set %u not supported", key_size);
+ return NULL;
+ }
+
+ /* Some shortcuts for often used variables */
+ n = set->n;
+ q = set->q;
+
+ if (set->fft_params->n != n || set->fft_params->q != q)
+ {
+ DBG1(DBG_LIB, "FFT parameters do not match BLISS parameters");
+ return NULL;
+ }
+ this = bliss_private_key_create_empty();
+ this->set = set;
+
+ /* We derive the public key from the private key using the FFT */
+ fft = bliss_fft_create(set->fft_params);
+
+ /* Some vectors needed to derive the publi key */
+ S1 = malloc(n * sizeof(uint32_t));
+ S2 = malloc(n * sizeof(uint32_t));
+ a = malloc(n * sizeof(uint32_t));
+ this->A = malloc(n * sizeof(uint32_t));
+
+ /* Instantiate a true random generator */
+ rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
+
+ /* Loop until we have an invertible polynomial s1 */
+ do
+ {
+ if (!create_secret(this, rng, &this->s1, &this->s2, &trials))
+ {
+ break;
+ }
+
+ /* Convert signed arrays to unsigned arrays before FFT */
+ for (i = 0; i < n; i++)
+ {
+ S1[i] = (this->s1[i] < 0) ? this->s1[i] + q : this->s1[i];
+ S2[i] = (this->s2[i] > 0) ? q - this->s2[i] : -this->s2[i];
+ }
+ fft->transform(fft, S1, S1, FALSE);
+ fft->transform(fft, S2, S2, FALSE);
+
+ success = TRUE;
+ for (i = 0; i < n; i++)
+ {
+ if (S1[i] == 0)
+ {
+ DBG1(DBG_LIB, "S1[%d] is zero - s1 is not invertible", i);
+ free(this->s1);
+ free(this->s2);
+ this->s1 = NULL;
+ this->s2 = NULL;
+ success = FALSE;
+ break;
+ }
+ this->A[i] = invert(S1[i], q);
+ this->A[i] = (S2[i] * this->A[i]) % q;
+ }
+ }
+ while (!success && trials < SECRET_KEY_TRIALS_MAX);
+
+ DBG1(DBG_LIB, "secret key generation %s after %d trial%s",
+ success ? "succeeded" : "failed", trials, (trials == 1) ? "" : "s");
+
+ if (success)
+ {
+ fft->transform(fft, this->A, a, TRUE);
+
+ DBG4(DBG_LIB, " i f g a F G A");
+ for (i = 0; i < n; i++)
+ {
+ DBG4(DBG_LIB, "%4d %3d %3d %5u %5u %5u %5u",
+ i, this->s1[i], this->s2[i], a[i], S1[i], S2[i], this->A[i]);
+ }
+ }
+ else
+ {
+ destroy(this);
+ }
+
+ /* Cleanup */
+ fft->destroy(fft);
+ rng->destroy(rng);
+ memwipe(S1, n * sizeof(uint32_t));
+ memwipe(S2, n * sizeof(uint32_t));
+ free(S1);
+ free(S2);
+ free(a);
+
+ return success ? &this->public : NULL;
+}
+
+/**
+ * ASN.1 definition of a BLISS private key
+ */
+static const asn1Object_t privkeyObjects[] = {
+ { 0, "BLISSPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "keyType", ASN1_OID, ASN1_BODY }, /* 1 */
+ { 1, "public", ASN1_BIT_STRING, ASN1_BODY }, /* 2 */
+ { 1, "secret1", ASN1_BIT_STRING, ASN1_BODY }, /* 3 */
+ { 1, "secret2", ASN1_BIT_STRING, ASN1_BODY }, /* 4 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PRIV_KEY_TYPE 1
+#define PRIV_KEY_PUBLIC 2
+#define PRIV_KEY_SECRET1 3
+#define PRIV_KEY_SECRET2 4
+
+/**
+ * See header.
+ */
+bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args)
+{
+ private_bliss_private_key_t *this;
+ chunk_t key = chunk_empty, object;
+ bliss_bitpacker_t *packer;
+ asn1_parser_t *parser;
+ size_t s_bits = 0;
+ int8_t s, s_min = 0, s_max = 0;
+ uint32_t s_sign = 0x02, s_mask = 0xfffffffc, value;
+ bool success = FALSE;
+ int objectID, oid, i;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_BLOB_ASN1_DER:
+ key = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ if (key.len == 0)
+ {
+ return NULL;
+ }
+ this = bliss_private_key_create_empty();
+
+ parser = asn1_parser_create(privkeyObjects, key);
+ parser->set_flags(parser, FALSE, TRUE);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PRIV_KEY_TYPE:
+ oid = asn1_known_oid(object);
+ if (oid == OID_UNKNOWN)
+ {
+ goto end;
+ }
+ this->set = bliss_param_set_get_by_oid(oid);
+ if (this->set == NULL)
+ {
+ goto end;
+ }
+ if (lib->settings->get_bool(lib->settings,
+ "%s.plugins.bliss.use_bliss_b",TRUE, lib->ns))
+ {
+ switch (this->set->id)
+ {
+ case BLISS_I:
+ this->set = bliss_param_set_get_by_id(BLISS_B_I);
+ break;
+ case BLISS_III:
+ this->set = bliss_param_set_get_by_id(BLISS_B_III);
+ break;
+ case BLISS_IV:
+ this->set = bliss_param_set_get_by_id(BLISS_B_IV);
+ break;
+ default:
+ break;
+ }
+ }
+ if (this->set->non_zero2)
+ {
+ s_min = -2;
+ s_max = 2;
+ s_bits = 3;
+ }
+ else
+ {
+ s_min = -1;
+ s_max = 1;
+ s_bits = 2;
+ }
+ s_sign = 1 << (s_bits - 1);
+ s_mask = ((1 << (32 - s_bits)) - 1) << s_bits;
+ break;
+ case PRIV_KEY_PUBLIC:
+ if (!bliss_public_key_from_asn1(object, this->set, &this->A))
+ {
+ goto end;
+ }
+ break;
+ case PRIV_KEY_SECRET1:
+ if (object.len != 1 + (s_bits * this->set->n + 7)/8)
+ {
+ goto end;
+ }
+ this->s1 = malloc(this->set->n);
+
+ /* Skip unused bits octet */
+ object = chunk_skip(object, 1);
+ packer = bliss_bitpacker_create_from_data(object);
+ for (i = 0; i < this->set->n; i++)
+ {
+ packer->read_bits(packer, &value, s_bits);
+ s = (value & s_sign) ? value | s_mask : value;
+ if (s < s_min || s > s_max)
+ {
+ packer->destroy(packer);
+ goto end;
+ }
+ this->s1[i] = s;
+ }
+ packer->destroy(packer);
+ break;
+ case PRIV_KEY_SECRET2:
+ if (object.len != 1 + (s_bits * this->set->n + 7)/8)
+ {
+ goto end;
+ }
+ this->s2 = malloc(this->set->n);
+
+ /* Skip unused bits octet */
+ object = chunk_skip(object, 1);
+ packer = bliss_bitpacker_create_from_data(object);
+ for (i = 0; i < this->set->n; i++)
+ {
+ packer->read_bits(packer, &value, s_bits);
+ s = (value & s_sign) ? value | s_mask : value;
+ if (s < s_min || s > s_max)
+ {
+ packer->destroy(packer);
+ goto end;
+ }
+ this->s2[i] = 2 * s;
+ if (i == 0)
+ {
+ this->s2[0] += 1;
+ }
+ }
+ packer->destroy(packer);
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ if (!success)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/bliss/bliss_private_key.h b/src/libstrongswan/plugins/bliss/bliss_private_key.h
new file mode 100644
index 000000000..cb4ff807a
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_private_key.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_private_key bliss_private_key
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_PRIVATE_KEY_H_
+#define BLISS_PRIVATE_KEY_H_
+
+#include <credentials/builder.h>
+#include <credentials/keys/private_key.h>
+
+typedef struct bliss_private_key_t bliss_private_key_t;
+
+/**
+ * Private_key_t implementation of BLISS signature algorithm.
+ */
+struct bliss_private_key_t {
+
+ /**
+ * Implements private_key_t interface
+ */
+ private_key_t key;
+};
+
+/**
+ * Generate a BLISS private key.
+ *
+ * Accepts the BUILD_KEY_SIZE argument.
+ *
+ * @param type type of the key, must be KEY_BLISS
+ * @param args builder_part_t argument list
+ * @return generated key, NULL on failure
+ */
+bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args);
+
+/**
+ * Load a BLISS private key.
+ *
+ * Accepts BUILD_BLISS_* components.
+ *
+ * @param type type of the key, must be KEY_BLISS
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
+ */
+bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args);
+
+#endif /** BLISS_PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_public_key.c b/src/libstrongswan/plugins/bliss/bliss_public_key.c
new file mode 100644
index 000000000..0175b0f8e
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_public_key.c
@@ -0,0 +1,515 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_public_key.h"
+#include "bliss_signature.h"
+#include "bliss_bitpacker.h"
+#include "bliss_fft.h"
+#include "bliss_utils.h"
+
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+
+typedef struct private_bliss_public_key_t private_bliss_public_key_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_bliss_public_key_t {
+ /**
+ * Public interface for this signer.
+ */
+ bliss_public_key_t public;
+
+ /**
+ * BLISS signature parameter set
+ */
+ bliss_param_set_t *set;
+
+ /**
+ * NTT of BLISS public key a (coefficients of polynomial (2g + 1)/f)
+ */
+ uint32_t *A;
+
+ /**
+ * reference counter
+ */
+ refcount_t ref;
+};
+
+METHOD(public_key_t, get_type, key_type_t,
+ private_bliss_public_key_t *this)
+{
+ return KEY_BLISS;
+}
+
+/**
+ * Verify a BLISS signature based on a SHA-512 hash
+ */
+static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
+ chunk_t data, chunk_t signature)
+{
+ int i, n;
+ int32_t *z1, *u;
+ int16_t *ud, *z2d;
+ uint16_t q, q2, p, *c_indices, *indices;
+ uint32_t *az;
+ uint8_t data_hash_buf[HASH_SIZE_SHA512];
+ chunk_t data_hash;
+ hasher_t *hasher;
+ bliss_fft_t *fft;
+ bliss_signature_t *sig;
+ bool success = FALSE;
+
+ /* Create data hash */
+ hasher = lib->crypto->create_hasher(lib->crypto, alg);
+ if (!hasher )
+ {
+ return FALSE;
+ }
+ data_hash = chunk_create(data_hash_buf, hasher->get_hash_size(hasher));
+
+ if (!hasher->get_hash(hasher, data, data_hash_buf))
+ {
+ hasher->destroy(hasher);
+ return FALSE;
+ }
+ hasher->destroy(hasher);
+
+ /* Create SHA512 hasher for c_indices oracle */
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
+ if (!hasher)
+ {
+ return FALSE;
+ }
+
+ sig = bliss_signature_create_from_data(this->set, signature);
+ if (!sig)
+ {
+ hasher->destroy(hasher);
+ return FALSE;
+ }
+ sig->get_parameters(sig, &z1, &z2d, &c_indices);
+
+ if (!bliss_utils_check_norms(this->set, z1, z2d))
+ {
+ hasher->destroy(hasher);
+ sig->destroy(sig);
+ return FALSE;
+ }
+
+ /* Initialize a couple of needed variables */
+ n = this->set->n;
+ q = this->set->q;
+ p = this->set->p;
+ q2 = 2 * q;
+ az = malloc(n * sizeof(uint32_t));
+ u = malloc(n * sizeof(int32_t));
+ ud = malloc(n * sizeof(int16_t));
+ indices = malloc(this->set->kappa * sizeof(uint16_t));
+
+ for (i = 0; i < n; i++)
+ {
+ az[i] = z1[i] < 0 ? q + z1[i] : z1[i];
+ }
+ fft = bliss_fft_create(this->set->fft_params);
+ fft->transform(fft, az, az, FALSE);
+
+ for (i = 0; i < n; i++)
+ {
+ az[i] = (this->A[i] * az[i]) % q;
+ }
+ fft->transform(fft, az, az, TRUE);
+
+ for (i = 0; i < n; i++)
+ {
+ u[i] = (2 * this->set->q2_inv * az[i]) % q2;
+ }
+
+ for (i = 0; i < this->set->kappa; i++)
+ {
+ u[c_indices[i]] = (u[c_indices[i]] + q * this->set->q2_inv) % q2;
+ }
+ bliss_utils_round_and_drop(this->set, u, ud);
+
+ for (i = 0; i < n; i++)
+ {
+ ud[i] += z2d[i];
+ if (ud[i] < 0)
+ {
+ ud[i] += p;
+ }
+ else if (ud[i] >= p)
+ {
+ ud[i] -= p;
+ }
+ }
+
+ /* Detailed debugging information */
+ DBG3(DBG_LIB, " i u[i] ud[i] z2d[i]");
+ for (i = 0; i < n; i++)
+ {
+ DBG3(DBG_LIB, "%3d %6d %4d %4d", i, u[i], ud[i], z2d[i]);
+ }
+
+ if (!bliss_utils_generate_c(hasher, data_hash, ud, n, this->set->kappa,
+ indices))
+ {
+ goto end;
+ }
+
+ for (i = 0; i < this->set->kappa; i++)
+ {
+ if (indices[i] != c_indices[i])
+ {
+ DBG1(DBG_LIB, "signature verification failed");
+ goto end;
+ }
+ }
+ success = TRUE;
+
+end:
+ /* cleanup */
+ hasher->destroy(hasher);
+ sig->destroy(sig);
+ fft->destroy(fft);
+ free(az);
+ free(u);
+ free(ud);
+ free(indices);
+
+ return success;
+}
+
+METHOD(public_key_t, verify, bool,
+ private_bliss_public_key_t *this, signature_scheme_t scheme,
+ chunk_t data, chunk_t signature)
+{
+ switch (scheme)
+ {
+ case SIGN_BLISS_WITH_SHA256:
+ return verify_bliss(this, HASH_SHA256, data, signature);
+ case SIGN_BLISS_WITH_SHA384:
+ return verify_bliss(this, HASH_SHA384, data, signature);
+ case SIGN_BLISS_WITH_SHA512:
+ return verify_bliss(this, HASH_SHA512, data, signature);
+ default:
+ DBG1(DBG_LIB, "signature scheme %N not supported by BLISS",
+ signature_scheme_names, scheme);
+ return FALSE;
+ }
+}
+
+METHOD(public_key_t, encrypt_, bool,
+ private_bliss_public_key_t *this, encryption_scheme_t scheme,
+ chunk_t plain, chunk_t *crypto)
+{
+ DBG1(DBG_LIB, "encryption scheme %N not supported",
+ encryption_scheme_names, scheme);
+ return FALSE;
+}
+
+METHOD(public_key_t, get_keysize, int,
+ private_bliss_public_key_t *this)
+{
+ return this->set->strength;
+}
+
+METHOD(public_key_t, get_encoding, bool,
+ private_bliss_public_key_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
+{
+ bool success = TRUE;
+
+ *encoding = bliss_public_key_info_encode(this->set->oid, this->A, this->set);
+
+ if (type != PUBKEY_SPKI_ASN1_DER)
+ {
+ chunk_t asn1_encoding = *encoding;
+
+ success = lib->encoding->encode(lib->encoding, type,
+ NULL, encoding, CRED_PART_BLISS_PUB_ASN1_DER,
+ asn1_encoding, CRED_PART_END);
+ chunk_clear(&asn1_encoding);
+ }
+ return success;
+}
+
+METHOD(public_key_t, get_fingerprint, bool,
+ private_bliss_public_key_t *this, cred_encoding_type_t type, chunk_t *fp)
+{
+ bool success;
+
+ if (lib->encoding->get_cache(lib->encoding, type, this, fp))
+ {
+ return TRUE;
+ }
+ success = bliss_public_key_fingerprint(this->set->oid, this->A,
+ this->set, type, fp);
+ if (success)
+ {
+ lib->encoding->cache(lib->encoding, type, this, *fp);
+ }
+ return success;
+}
+
+METHOD(public_key_t, get_ref, public_key_t*,
+ private_bliss_public_key_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.key;
+}
+
+METHOD(public_key_t, destroy, void,
+ private_bliss_public_key_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ lib->encoding->clear_cache(lib->encoding, this);
+ free(this->A);
+ free(this);
+ }
+}
+
+/**
+ * ASN.1 definition of a BLISS public key
+ */
+static const asn1Object_t pubkeyObjects[] = {
+ { 0, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "algorithm", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 1, "subjectPublicKey", ASN1_BIT_STRING, ASN1_BODY }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define BLISS_SUBJECT_PUBLIC_KEY_ALGORITHM 1
+#define BLISS_SUBJECT_PUBLIC_KEY 2
+
+/**
+ * See header.
+ */
+bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args)
+{
+ private_bliss_public_key_t *this;
+ chunk_t blob = chunk_empty, object, param;
+ asn1_parser_t *parser;
+ bool success = FALSE;
+ int objectID, oid;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_BLOB_ASN1_DER:
+ blob = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+
+ if (blob.len == 0)
+ {
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .key = {
+ .get_type = _get_type,
+ .verify = _verify,
+ .encrypt = _encrypt_,
+ .equals = public_key_equals,
+ .get_keysize = _get_keysize,
+ .get_fingerprint = _get_fingerprint,
+ .has_fingerprint = public_key_has_fingerprint,
+ .get_encoding = _get_encoding,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .ref = 1,
+ );
+
+ parser = asn1_parser_create(pubkeyObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case BLISS_SUBJECT_PUBLIC_KEY_ALGORITHM:
+ {
+ oid = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, &param);
+ if (oid != OID_BLISS_PUBLICKEY)
+ {
+ goto end;
+ }
+ if (!asn1_parse_simple_object(&param, ASN1_OID,
+ parser->get_level(parser)+3, "blissKeyType"))
+ {
+ goto end;
+ }
+ oid = asn1_known_oid(param);
+ if (oid == OID_UNKNOWN)
+ {
+ goto end;
+ }
+ this->set = bliss_param_set_get_by_oid(oid);
+ if (this->set == NULL)
+ {
+ goto end;
+ }
+ break;
+ }
+ case BLISS_SUBJECT_PUBLIC_KEY:
+ if (!bliss_public_key_from_asn1(object, this->set, &this->A))
+ {
+ goto end;
+ }
+ break;
+ }
+ }
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ if (!success)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
+/**
+ * See header.
+ */
+bool bliss_public_key_from_asn1(chunk_t object, bliss_param_set_t *set,
+ uint32_t **pubkey)
+{
+ bliss_bitpacker_t *packer;
+ uint32_t coefficient;
+ uint16_t needed_bits;
+ int i;
+
+ /* skip initial bit string octet defining unused bits */
+ object = chunk_skip(object, 1);
+
+ needed_bits = set->n * set->q_bits;
+
+ if (8 * object.len < needed_bits)
+ {
+ return FALSE;
+ }
+ *pubkey = malloc(set->n * sizeof(uint32_t));
+
+ packer = bliss_bitpacker_create_from_data(object);
+
+ for (i = 0; i < set->n; i++)
+ {
+ packer->read_bits(packer, &coefficient, set->q_bits);
+ if (coefficient >= set->q)
+ {
+ packer->destroy(packer);
+ return FALSE;
+ }
+ (*pubkey)[i] = coefficient;
+ }
+ packer->destroy(packer);
+
+ return TRUE;
+}
+
+/**
+ * See header.
+ */
+chunk_t bliss_public_key_encode(uint32_t *pubkey, bliss_param_set_t *set)
+{
+ bliss_bitpacker_t *packer;
+ chunk_t encoding;
+ int i;
+
+ packer = bliss_bitpacker_create(set->n * set->q_bits);
+
+ for (i = 0; i < set->n; i++)
+ {
+ packer->write_bits(packer, pubkey[i], set->q_bits);
+ }
+ encoding = packer->extract_buf(packer);
+ packer->destroy(packer);
+
+ return encoding;
+}
+
+/**
+ * See header.
+ */
+chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey,
+ bliss_param_set_t *set)
+{
+ chunk_t encoding, pubkey_encoding;
+
+ pubkey_encoding = bliss_public_key_encode(pubkey, set);
+
+ encoding = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_build_known_oid(OID_BLISS_PUBLICKEY),
+ asn1_build_known_oid(oid)),
+ asn1_bitstring("m", pubkey_encoding));
+
+ return encoding;
+}
+
+/**
+ * See header.
+ */
+bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey,
+ bliss_param_set_t *set,
+ cred_encoding_type_t type, chunk_t *fp)
+{
+ hasher_t *hasher;
+ chunk_t key;
+
+ switch (type)
+ {
+ case KEYID_PUBKEY_SHA1:
+ key = bliss_public_key_encode(pubkey, set);
+ break;
+ case KEYID_PUBKEY_INFO_SHA1:
+ key = bliss_public_key_info_encode(oid, pubkey, set);
+ break;
+ default:
+ return FALSE;
+ }
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (!hasher || !hasher->allocate_hash(hasher, key, fp))
+ {
+ DBG1(DBG_LIB, "SHA1 hash algorithm not supported, fingerprinting failed");
+ DESTROY_IF(hasher);
+ free(key.ptr);
+
+ return FALSE;
+ }
+ hasher->destroy(hasher);
+ free(key.ptr);
+
+ return TRUE;
+}
+
diff --git a/src/libstrongswan/plugins/bliss/bliss_public_key.h b/src/libstrongswan/plugins/bliss/bliss_public_key.h
new file mode 100644
index 000000000..cd8f231b2
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_public_key.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_public_key bliss_public_key
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_PUBLIC_KEY_H_
+#define BLISS_PUBLIC_KEY_H_
+
+#include "bliss_param_set.h"
+
+#include <credentials/builder.h>
+#include <credentials/cred_encoding.h>
+#include <credentials/keys/public_key.h>
+
+typedef struct bliss_public_key_t bliss_public_key_t;
+
+/**
+ * public_key_t implementation of BLISS signature algorithm
+ */
+struct bliss_public_key_t {
+
+ /**
+ * Implements the public_key_t interface
+ */
+ public_key_t key;
+};
+
+/**
+ * Load a BLISS public key.
+ *
+ * Accepts BUILD_BLISS_* components.
+ *
+ * @param type type of the key, must be KEY_BLISS
+ * @param args builder_part_t argument list
+ * @return loaded key, NULL on failure
+ */
+bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args);
+
+/* The following functions are shared with the bliss_private_key class */
+
+/**
+ * Parse an ASN.1 BIT STRING into an array of public key coefficients
+ *
+ * @param object packed subjectPublicKey
+ * @param set BLISS parameter set for public key vector
+ * @param pubkey coefficients of public key vector
+ * @return TRUE if parsing successful
+ */
+bool bliss_public_key_from_asn1(chunk_t object, bliss_param_set_t *set,
+ uint32_t **pubkey);
+
+/**
+ * Encode a raw BLISS subjectPublicKey in ASN.1 DER format
+ *
+ * @param pubkey coefficients of public key vector
+ * @param set BLISS parameter set for the public key vector
+ * @result ASN.1 encoded subjectPublicKey
+ */
+chunk_t bliss_public_key_encode(uint32_t *pubkey, bliss_param_set_t *set);
+
+/**
+ * Encode a BLISS subjectPublicKeyInfo record in ASN.1 DER format
+ *
+ * @param oid BLISS public key type OID
+ * @param pubkey coefficients of public key vector
+ * @param set BLISS parameter set for the public key vector
+ * @result ASN.1 encoded subjectPublicKeyInfo record
+ */
+chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey,
+ bliss_param_set_t *set);
+
+/**
+ * Generate a BLISS public key fingerprint
+ *
+ * @param oid BLISS public key type OID
+ * @param pubkey coefficients of public key vector
+ * @param set BLISS parameter set for the public key vector
+ * @param type type of fingerprint to be generated
+ * @param fp generated fingerprint (must be freed by caller)
+ * @result TRUE if generation was successful
+ */
+bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey,
+ bliss_param_set_t *set,
+ cred_encoding_type_t type, chunk_t *fp);
+
+#endif /** BLISS_PUBLIC_KEY_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_sampler.c b/src/libstrongswan/plugins/bliss/bliss_sampler.c
new file mode 100644
index 000000000..fa45a2fac
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_sampler.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_sampler.h"
+
+typedef struct private_bliss_sampler_t private_bliss_sampler_t;
+
+#include <crypto/mgf1/mgf1_bitspender.h>
+
+/**
+ * Private data of a bliss_sampler_t object.
+ */
+struct private_bliss_sampler_t {
+
+ /**
+ * Public interface.
+ */
+ bliss_sampler_t public;
+
+ /**
+ * BLISS parameter the rejection sampling is to be based on
+ */
+ bliss_param_set_t *set;
+
+ /**
+ * Bitspender used for random rejection sampling
+ */
+ mgf1_bitspender_t *bitspender;
+
+};
+
+METHOD(bliss_sampler_t, bernoulli_exp, bool,
+ private_bliss_sampler_t *this, uint32_t x, bool *accepted)
+{
+ uint32_t x_mask;
+ uint8_t *c, u;
+ int i;
+
+ x_mask = 1 << (this->set->c_rows - 1);
+ c = this->set->c;
+ c += (this->set->c_rows - 1) * this->set->c_cols;
+
+ while (x_mask > 0)
+ {
+ if (x & x_mask)
+ {
+ for (i = 0; i < this->set->c_cols; i++)
+ {
+ if (!this->bitspender->get_byte(this->bitspender, &u))
+ {
+ return FALSE;
+ }
+ if (u < c[i])
+ {
+ break;
+ }
+ else if (u > c[i])
+ {
+ *accepted = FALSE;
+ return TRUE;
+ }
+ }
+ }
+ x_mask >>= 1;
+ c -= this->set->c_cols;
+ }
+
+ *accepted = TRUE;
+ return TRUE;
+}
+
+METHOD(bliss_sampler_t, bernoulli_cosh, bool,
+ private_bliss_sampler_t *this, int32_t x, bool *accepted)
+{
+ uint32_t u;
+
+ x = 2 * (x < 0 ? -x : x);
+
+ while (TRUE)
+ {
+ if (!bernoulli_exp(this, x, accepted))
+ {
+ return FALSE;
+ }
+ if (*accepted)
+ {
+ return TRUE;
+ }
+ if (!this->bitspender->get_bits(this->bitspender, 1, &u))
+ {
+ return FALSE;
+ }
+ if (u)
+ {
+ continue;
+ }
+ if (!bernoulli_exp(this, x, accepted))
+ {
+ return FALSE;
+ }
+ if (!(*accepted))
+ {
+ return TRUE;
+ }
+ }
+}
+
+#define MAX_SAMPLE_INDEX 16
+
+METHOD(bliss_sampler_t, pos_binary, bool,
+ private_bliss_sampler_t *this, uint32_t *x)
+{
+ uint32_t u, i;
+
+ while (TRUE)
+ {
+ for (i = 0; i <= MAX_SAMPLE_INDEX; i++)
+ {
+ if (!this->bitspender->get_bits(this->bitspender,
+ i ? (2*i - 1) : 1, &u))
+ {
+ return FALSE;
+ }
+ if (u == 0)
+ {
+ *x = i;
+ return TRUE;
+ }
+ if ((u >> 1) != 0)
+ {
+ break;
+ }
+ }
+ if (i > MAX_SAMPLE_INDEX)
+ {
+ return FALSE;
+ }
+ }
+}
+
+METHOD(bliss_sampler_t, gaussian, bool,
+ private_bliss_sampler_t *this, int32_t *z)
+{
+ uint32_t u, x, y, z_pos;
+ bool accepted;
+
+ while (TRUE)
+ {
+ if (!pos_binary(this, &x))
+ {
+ return FALSE;
+ }
+
+ do
+ {
+ if (!this->bitspender->get_bits(this->bitspender,
+ this->set->k_sigma_bits, &y))
+ {
+ return FALSE;
+ }
+ }
+ while (y >= this->set->k_sigma);
+
+ if (!bernoulli_exp(this, y * (y + 2*this->set->k_sigma * x), &accepted))
+ {
+ return FALSE;
+ }
+ if (accepted)
+ {
+ if (!this->bitspender->get_bits(this->bitspender, 1, &u))
+ {
+ return FALSE;
+ }
+ if (x || y || u)
+ {
+ break;
+ }
+ }
+ }
+
+ z_pos = this->set->k_sigma * x + y;
+ *z = u ? z_pos : -z_pos;
+
+ return TRUE;
+}
+
+METHOD(bliss_sampler_t, sign, bool,
+ private_bliss_sampler_t *this, bool *positive)
+{
+ uint32_t u;
+
+ if (!this->bitspender->get_bits(this->bitspender, 1, &u))
+ {
+ return FALSE;
+ }
+ *positive = u;
+
+ return TRUE;
+}
+
+METHOD(bliss_sampler_t, destroy, void,
+ private_bliss_sampler_t *this)
+{
+ this->bitspender->destroy(this->bitspender);
+ free(this);
+}
+
+
+/**
+ * See header.
+ */
+bliss_sampler_t *bliss_sampler_create(hash_algorithm_t alg, chunk_t seed,
+ bliss_param_set_t *set)
+{
+ private_bliss_sampler_t *this;
+ mgf1_bitspender_t *bitspender;
+
+ bitspender = mgf1_bitspender_create(alg, seed, FALSE);
+ if (!bitspender)
+ {
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .bernoulli_exp = _bernoulli_exp,
+ .bernoulli_cosh = _bernoulli_cosh,
+ .pos_binary = _pos_binary,
+ .gaussian = _gaussian,
+ .sign = _sign,
+ .destroy = _destroy,
+ },
+ .set = set,
+ .bitspender = bitspender,
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_sampler.h b/src/libstrongswan/plugins/bliss/bliss_sampler.h
new file mode 100644
index 000000000..2c75d4480
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_sampler.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_sampler bliss_sampler
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_SAMPLER_H_
+#define BLISS_SAMPLER_H_
+
+typedef struct bliss_sampler_t bliss_sampler_t;
+
+#include "bliss_param_set.h"
+
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
+/**
+ * Implementation various rejection sampling algorithms.
+ */
+struct bliss_sampler_t {
+
+ /**
+ * Sample according to exp(-x/(2*sigma^2))
+ *
+ * @param x Value to be sampled
+ * @param accepted TRUE if value is accepted, FALSE if rejected
+ * @result TRUE if sampling was successful
+ */
+ bool (*bernoulli_exp)(bliss_sampler_t *this, uint32_t x, bool *accepted);
+
+ /**
+ * Sample according to 1/cosh(x/sigma^2)
+ *
+ * @param x Value to be sampled
+ * @param accepted TRUE if value is accepted, FALSE if rejected
+ * @result TRUE if sampling was successful
+ */
+ bool (*bernoulli_cosh)(bliss_sampler_t *this, int32_t x, bool *accepted);
+
+ /**
+ * Sample according to 2^(-x^2) for positive x
+ *
+ * @param x Generated value
+ * @result TRUE if sampling was successful
+ */
+ bool (*pos_binary)(bliss_sampler_t *this, uint32_t *x);
+
+ /**
+ * Sample according to the Gaussian distribution exp(-x^2/(2*sigma^2))
+ *
+ * @param z Generated value with Gaussian distribution
+ * @result TRUE if sampling was successful
+ */
+ bool (*gaussian)(bliss_sampler_t *this, int32_t *z);
+
+ /**
+ * Sample the sign according to the binary distribution
+ *
+ * @param positive TRUE if positive
+ * @result TRUE if sampling was successful
+ */
+ bool (*sign)(bliss_sampler_t *this, bool *positive);
+
+ /**
+ * Destroy bliss_sampler_t object
+ */
+ void (*destroy)(bliss_sampler_t *this);
+};
+
+/**
+ * Create a bliss_sampler_t object.
+ *
+ * @param alg Hash algorithm to be used for the internal bitspender
+ * @param seed Seed used to initialize the internal bitspender
+ * @param set BLISS parameter set to be used
+ */
+bliss_sampler_t *bliss_sampler_create(hash_algorithm_t alg, chunk_t seed,
+ bliss_param_set_t *set);
+
+#endif /** BLISS_SAMPLER_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_signature.c b/src/libstrongswan/plugins/bliss/bliss_signature.c
new file mode 100644
index 000000000..e603da399
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_signature.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_signature.h"
+#include "bliss_bitpacker.h"
+#include "bliss_huffman_coder.h"
+
+
+typedef struct private_bliss_signature_t private_bliss_signature_t;
+
+/**
+ * Private data of a bliss_signature_t object.
+ */
+struct private_bliss_signature_t {
+ /**
+ * Public interface for this signer.
+ */
+ bliss_signature_t public;
+
+ /**
+ * BLISS signature parameter set
+ */
+ bliss_param_set_t *set;
+
+ /**
+ * BLISS signature vector z1 of size n
+ */
+ int32_t *z1;
+
+ /**
+ * BLISS signature vector z2d of size n
+ */
+ int16_t *z2d;
+
+ /**
+ * Indices of sparse BLISS challenge vector c of size kappa
+ */
+ uint16_t *c_indices;
+
+};
+
+METHOD(bliss_signature_t, get_encoding, chunk_t,
+ private_bliss_signature_t *this)
+{
+ bliss_bitpacker_t *packer;
+ bliss_huffman_coder_t *coder;
+ bliss_huffman_code_t *code;
+ int32_t z1;
+ uint32_t z1_sign;
+ uint16_t z2d_bits;
+ chunk_t encoding = chunk_empty;
+ int i;
+
+ z2d_bits = this->set->z1_bits - this->set->d;
+
+ /* Get Huffman code for this BLISS parameter set */
+ code = bliss_huffman_code_get_by_id(this->set->id);
+ if (!code)
+ {
+ DBG1(DBG_LIB, "no Huffman code found for parameter set %N",
+ bliss_param_set_id_names, this->set->id);
+ return chunk_empty;
+ }
+
+ packer = bliss_bitpacker_create(this->set->n * this->set->z1_bits +
+ this->set->n * z2d_bits +
+ this->set->kappa * this->set->n_bits);
+ coder = bliss_huffman_coder_create(code, packer);
+
+ for (i = 0; i < this->set->n; i++)
+ {
+ /* determine and remove the sign of z1[i]*/
+ z1_sign = this->z1[i] < 0;
+ z1 = z1_sign ? -this->z1[i] : this->z1[i];
+
+ if (!packer->write_bits(packer, z1_sign, 1) ||
+ !packer->write_bits(packer, z1 & 0xff, 8) ||
+ !coder->encode(coder, z1 >> 8, this->z2d[i]))
+ {
+ goto end;
+ }
+ }
+ for (i = 0; i < this->set->kappa; i++)
+ {
+ if (!packer->write_bits(packer, this->c_indices[i], this->set->n_bits))
+ {
+ goto end;
+ }
+ }
+ encoding = packer->extract_buf(packer);
+
+ DBG2(DBG_LIB, "efficiency of Huffman coder is %6.4f bits/tuple (%u bits)",
+ coder->get_bits(coder)/(double)(this->set->n),
+ coder->get_bits(coder));
+ DBG2(DBG_LIB, "generated BLISS signature (%u bits encoded in %u bytes)",
+ packer->get_bits(packer), encoding.len);
+
+ end:
+ coder->destroy(coder);
+ packer->destroy(packer);
+ return encoding;
+}
+
+METHOD(bliss_signature_t, get_parameters, void,
+ private_bliss_signature_t *this, int32_t **z1, int16_t **z2d,
+ uint16_t **c_indices)
+{
+ *z1 = this->z1;
+ *z2d = this->z2d;
+ *c_indices = this->c_indices;
+}
+
+METHOD(bliss_signature_t, destroy, void,
+ private_bliss_signature_t *this)
+{
+ free(this->z1);
+ free(this->z2d);
+ free(this->c_indices);
+ free(this);
+}
+
+/**
+ * See header.
+ */
+bliss_signature_t *bliss_signature_create(bliss_param_set_t *set)
+{
+ private_bliss_signature_t *this;
+
+ INIT(this,
+ .public = {
+ .get_encoding = _get_encoding,
+ .get_parameters = _get_parameters,
+ .destroy = _destroy,
+ },
+ .set = set,
+ .z1 = malloc(set->n * sizeof(int32_t)),
+ .z2d = malloc(set->n * sizeof(int16_t)),
+ .c_indices = malloc(set->n * sizeof(uint16_t)),
+ );
+
+ return &this->public;
+}
+
+/**
+ * See header.
+ */
+bliss_signature_t *bliss_signature_create_from_data(bliss_param_set_t *set,
+ chunk_t encoding)
+{
+ private_bliss_signature_t *this;
+ bliss_bitpacker_t *packer;
+ bliss_huffman_coder_t *coder;
+ bliss_huffman_code_t *code;
+ uint32_t z1_sign, z1_low, value;
+ int32_t z1;
+ int16_t z2;
+ int i;
+
+ /* Get Huffman code for this BLISS parameter set */
+ code = bliss_huffman_code_get_by_id(set->id);
+ if (!code)
+ {
+ DBG1(DBG_LIB, "no Huffman code found for parameter set %N",
+ bliss_param_set_id_names, set->id);
+ return NULL;
+ }
+
+ if (encoding.len == 0)
+ {
+ DBG1(DBG_LIB, "zero length BLISS signature");
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .get_encoding = _get_encoding,
+ .get_parameters = _get_parameters,
+ .destroy = _destroy,
+ },
+ .set = set,
+ .z1 = malloc(set->n * sizeof(int32_t)),
+ .z2d = malloc(set->n * sizeof(int16_t)),
+ .c_indices = malloc(set->n * sizeof(uint16_t)),
+ );
+
+ packer = bliss_bitpacker_create_from_data(encoding);
+ coder = bliss_huffman_coder_create(code, packer);
+
+ for (i = 0; i < set->n; i++)
+ {
+ if (!packer->read_bits(packer, &z1_sign, 1) ||
+ !packer->read_bits(packer, &z1_low, 8) ||
+ !coder->decode(coder, &z1, &z2))
+ {
+ DBG1(DBG_LIB, "truncated BLISS signature encoding of z1/z2");
+ coder->destroy(coder);
+ packer->destroy(packer);
+ destroy(this);
+ return NULL;
+ }
+ z1 = (z1 << 8) + z1_low;
+ this->z1[i] = z1_sign ? -z1 : z1;
+ this->z2d[i] = z2;
+ }
+ coder->destroy(coder);
+
+ for (i = 0; i < set->kappa; i++)
+ {
+ if (!packer->read_bits(packer, &value, set->n_bits))
+ {
+ DBG1(DBG_LIB, "truncated BLISS signature encoding of c_indices");
+ packer->destroy(packer);
+ destroy(this);
+ return NULL;
+ }
+ this->c_indices[i] = value;
+ }
+ packer->destroy(packer);
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_signature.h b/src/libstrongswan/plugins/bliss/bliss_signature.h
new file mode 100644
index 000000000..d37f5398b
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_signature.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_signature bliss_signature
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_SIGNATURE_H_
+#define BLISS_SIGNATURE_H_
+
+typedef struct bliss_signature_t bliss_signature_t;
+
+#include "bliss_param_set.h"
+
+#include <library.h>
+
+/**
+ * Public interface of BLISS signature object
+ */
+struct bliss_signature_t {
+
+ /**
+ * Get compressed binary encoding of BLISS signature
+ *
+ * @result binary encoding of BLISS signature
+ */
+ chunk_t (*get_encoding)(bliss_signature_t *this);
+
+ /**
+ * Get signature parameters extracted from compressd binary encoding
+ *
+ * @param z1 signature vector z1 of size n
+ * @param z2d signature vector z2d of size n
+ * @param c_indices indices of sparse binary challenge vector of size kappa
+ */
+ void (*get_parameters)(bliss_signature_t *this, int32_t **z1, int16_t **z2d,
+ uint16_t **c_indices);
+
+ /**
+ * Destroy bliss_signature_t object
+ */
+ void (*destroy)(bliss_signature_t *this);
+
+};
+
+/**
+ * Create a BLISS signature object.
+ *
+ * @param set BLISS parameter set
+ */
+bliss_signature_t *bliss_signature_create(bliss_param_set_t *set);
+
+/**
+ * Create a BLISS signature object from encoding.
+ *
+ * @param set BLISS parameter set
+ * @param encoding binary signature encoding
+ */
+bliss_signature_t *bliss_signature_create_from_data(bliss_param_set_t *set,
+ chunk_t encoding);
+
+#endif /** BLISS_SIGNATURE_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/bliss_utils.c b/src/libstrongswan/plugins/bliss/bliss_utils.c
new file mode 100644
index 000000000..5a069989c
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_utils.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "bliss_utils.h"
+
+#include <asn1/asn1.h>
+#include <crypto/hashers/hasher.h>
+#include <utils/debug.h>
+
+/**
+ * See header.
+ */
+int32_t bliss_utils_scalar_product(int32_t *x, int32_t *y, int n)
+{
+ int32_t product = 0;
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ product += x[i] * y[i];
+ }
+
+ return product;
+}
+
+/**
+ * See header.
+ */
+void bliss_utils_round_and_drop(bliss_param_set_t *set, int32_t *x, int16_t *xd)
+{
+ int32_t factor;
+ int i;
+
+ factor = 1 << set->d;
+
+ for (i = 0; i < set->n; i++)
+ {
+ xd[i] = ((x[i] + (factor >> 1)) / factor) % set->p;
+ }
+}
+
+/**
+ * See header.
+ */
+bool bliss_utils_generate_c(hasher_t *hasher, chunk_t data_hash, uint16_t *ud,
+ int n, uint16_t kappa, uint16_t *c_indices)
+{
+ int i, j;
+ uint64_t extra_bits;
+ uint16_t index, rounds = 0;
+ uint8_t hash[HASH_SIZE_SHA512], un16_buf[2];
+ chunk_t un16 = { un16_buf, 2 };
+ bool index_taken[n];
+
+ while (TRUE)
+ {
+ if (!hasher->get_hash(hasher, data_hash, NULL))
+ {
+ return FALSE;
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ htoun16(un16_buf, ud[i]);
+ if (!hasher->get_hash(hasher, un16, NULL))
+ {
+ return FALSE;
+ }
+ index_taken[i] = FALSE;
+ }
+
+ htoun16(un16_buf, rounds++);
+ if (!hasher->get_hash(hasher, un16, hash))
+ {
+ return FALSE;
+ }
+
+ extra_bits = untoh64(hash + sizeof(hash) - sizeof(uint64_t));
+
+ for (i = 0, j = 0; j < sizeof(hash); j++)
+ {
+ index = 2 * (uint16_t)hash[i] + (extra_bits & 1);
+ if (!index_taken[index])
+ {
+ c_indices[i++] = index;
+ index_taken[index] = TRUE;
+ }
+ if (i == kappa)
+ {
+ return TRUE;
+ }
+ }
+ }
+}
+
+/**
+ * See header.
+ */
+bool bliss_utils_check_norms(bliss_param_set_t *set, int32_t *z1, int16_t *z2d)
+{
+ int32_t z2ds[set->n];
+ int32_t z1_min, z1_max, norm;
+ int16_t z2d_min, z2d_max;
+ int i;
+
+ /* some statistics on the values of z1 and z2d */
+ z1_min = z1_max = z1[0];
+ z2d_min = z2d_max = z2d[0];
+
+ for (i = 1; i < set->n; i++)
+ {
+ if (z1[i] < z1_min)
+ {
+ z1_min = z1[i];
+ }
+ else if (z1[i] > z1_max)
+ {
+ z1_max = z1[i];
+ }
+ if (z2d[i] < z2d_min)
+ {
+ z2d_min = z2d[i];
+ }
+ else if (z2d[i] > z2d_max)
+ {
+ z2d_max = z2d[i];
+ }
+ }
+ DBG2(DBG_LIB, "z1 = %d..%d, z2d = %d..%d", z1_min, z1_max, z2d_min, z2d_max);
+
+ /* Restriction on infinite norm */
+ for (i = 0; i < set->n; i++)
+ {
+ z2ds[i] = (1 << set->d) * z2d[i];
+
+ if (z1[i] >= set->B_inf || z2ds[i] >= set->B_inf ||
+ z1[i] <= -set->B_inf || z2ds[i] <= -set->B_inf)
+ {
+ DBG2(DBG_LIB, "signature rejected due to excessive infinite norm");
+ return FALSE;
+ }
+ }
+
+ /* Restriction on l2-norm */
+ norm = bliss_utils_scalar_product(z1, z1, set->n) +
+ bliss_utils_scalar_product(z2ds, z2ds, set->n);
+
+ if (norm >= set->B_l2)
+ {
+ DBG2(DBG_LIB, "signature rejected due to excessive l2-norm");
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/src/libstrongswan/plugins/bliss/bliss_utils.h b/src/libstrongswan/plugins/bliss/bliss_utils.h
new file mode 100644
index 000000000..063fd91c8
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/bliss_utils.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_utils bliss_utils
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_UTILS_H_
+#define BLISS_UTILS_H_
+
+#include "bliss_param_set.h"
+
+#include <library.h>
+
+/**
+ * Compute the scalar product of two vectors of size n
+ *
+ * @param x input vector of size n
+ * @param y input vector of size n
+ * @param n size of input vectors x and y
+ * @result scalar product of x and y
+ */
+int32_t bliss_utils_scalar_product(int32_t *x, int32_t *y, int n);
+
+/**
+ * Drop d bits but round first
+ *
+ * @param set BLISS parameter set
+ * @param x input vector x of size n
+ * @param xd rounded vector x with d bits dropped
+ */
+void bliss_utils_round_and_drop(bliss_param_set_t *set, int32_t *x, int16_t *xd);
+
+/**
+ * Generate the binary challenge vector c as an array of kappa indices
+ *
+ * @param hasher hasher used as an oracle
+ * @param data_hash hash of the data to be signed
+ * @param ud input vector ud of size n
+ * @param n size of input vector ud
+ * @param kappa parameter kappa
+ * @param c_indices indexes of non-zero challenge coefficients
+ */
+bool bliss_utils_generate_c(hasher_t *hasher, chunk_t data_hash, uint16_t *ud,
+ int n, uint16_t kappa, uint16_t *c_indices);
+
+/**
+ * Check the infinity and l2 norms of the vectors z1 and z2d << d
+ *
+ * @param set BLISS parameter set
+ * @param z1 input vector
+ * @param z2d input vector
+ * @result TRUE if infinite and l2 norms do not exceed boundaries
+ */
+bool bliss_utils_check_norms(bliss_param_set_t *set, int32_t *z1, int16_t *z2d);
+
+#endif /** BLISS_UTILS_H_ @}*/
diff --git a/src/libstrongswan/plugins/bliss/tests/Makefile.am b/src/libstrongswan/plugins/bliss/tests/Makefile.am
new file mode 100644
index 000000000..bd87753f5
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/Makefile.am
@@ -0,0 +1,27 @@
+TESTS = bliss_tests
+
+check_PROGRAMS = $(TESTS)
+
+bliss_tests_SOURCES = \
+ suites/test_bliss_fft.c \
+ suites/test_bliss_bitpacker.c \
+ suites/test_bliss_huffman.c \
+ suites/test_bliss_keys.c \
+ suites/test_bliss_sampler.c \
+ suites/test_bliss_signature.c \
+ suites/test_bliss_sign.c \
+ bliss_tests.h bliss_tests.c
+
+bliss_tests_CFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libstrongswan/tests \
+ -I$(top_srcdir)/src/libstrongswan/plugins/bliss \
+ -DPLUGINDIR=\""$(abs_top_builddir)/src/libstrongswan/plugins\"" \
+ -DPLUGINS=\""${s_plugins}\"" \
+ @COVERAGE_CFLAGS@
+
+bliss_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+bliss_tests_LDADD = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la \
+ ../libbliss.la
diff --git a/src/libstrongswan/plugins/bliss/tests/Makefile.in b/src/libstrongswan/plugins/bliss/tests/Makefile.in
new file mode 100644
index 000000000..5a1ce3d50
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/Makefile.in
@@ -0,0 +1,985 @@
+# 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 = bliss_tests$(EXEEXT)
+check_PROGRAMS = $(am__EXEEXT_1)
+subdir = src/libstrongswan/plugins/bliss/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 = bliss_tests$(EXEEXT)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_bliss_tests_OBJECTS = suites/bliss_tests-test_bliss_fft.$(OBJEXT) \
+ suites/bliss_tests-test_bliss_bitpacker.$(OBJEXT) \
+ suites/bliss_tests-test_bliss_huffman.$(OBJEXT) \
+ suites/bliss_tests-test_bliss_keys.$(OBJEXT) \
+ suites/bliss_tests-test_bliss_sampler.$(OBJEXT) \
+ suites/bliss_tests-test_bliss_signature.$(OBJEXT) \
+ suites/bliss_tests-test_bliss_sign.$(OBJEXT) \
+ bliss_tests-bliss_tests.$(OBJEXT)
+bliss_tests_OBJECTS = $(am_bliss_tests_OBJECTS)
+bliss_tests_DEPENDENCIES = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la \
+ ../libbliss.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 =
+bliss_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(bliss_tests_CFLAGS) \
+ $(CFLAGS) $(bliss_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 = $(bliss_tests_SOURCES)
+DIST_SOURCES = $(bliss_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@
+bliss_tests_SOURCES = \
+ suites/test_bliss_fft.c \
+ suites/test_bliss_bitpacker.c \
+ suites/test_bliss_huffman.c \
+ suites/test_bliss_keys.c \
+ suites/test_bliss_sampler.c \
+ suites/test_bliss_signature.c \
+ suites/test_bliss_sign.c \
+ bliss_tests.h bliss_tests.c
+
+bliss_tests_CFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libstrongswan/tests \
+ -I$(top_srcdir)/src/libstrongswan/plugins/bliss \
+ -DPLUGINDIR=\""$(abs_top_builddir)/src/libstrongswan/plugins\"" \
+ -DPLUGINS=\""${s_plugins}\"" \
+ @COVERAGE_CFLAGS@
+
+bliss_tests_LDFLAGS = @COVERAGE_LDFLAGS@
+bliss_tests_LDADD = \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/tests/libtest.la \
+ ../libbliss.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/libstrongswan/plugins/bliss/tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/bliss/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/bliss_tests-test_bliss_fft.$(OBJEXT): suites/$(am__dirstamp) \
+ suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_bitpacker.$(OBJEXT): \
+ suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_huffman.$(OBJEXT): \
+ suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_keys.$(OBJEXT): suites/$(am__dirstamp) \
+ suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_sampler.$(OBJEXT): \
+ suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_signature.$(OBJEXT): \
+ suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp)
+suites/bliss_tests-test_bliss_sign.$(OBJEXT): suites/$(am__dirstamp) \
+ suites/$(DEPDIR)/$(am__dirstamp)
+
+bliss_tests$(EXEEXT): $(bliss_tests_OBJECTS) $(bliss_tests_DEPENDENCIES) $(EXTRA_bliss_tests_DEPENDENCIES)
+ @rm -f bliss_tests$(EXEEXT)
+ $(AM_V_CCLD)$(bliss_tests_LINK) $(bliss_tests_OBJECTS) $(bliss_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)/bliss_tests-bliss_tests.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_signature.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/bliss_tests-test_bliss_fft.o: suites/test_bliss_fft.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_fft.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo -c -o suites/bliss_tests-test_bliss_fft.o `test -f 'suites/test_bliss_fft.c' || echo '$(srcdir)/'`suites/test_bliss_fft.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_fft.c' object='suites/bliss_tests-test_bliss_fft.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_fft.o `test -f 'suites/test_bliss_fft.c' || echo '$(srcdir)/'`suites/test_bliss_fft.c
+
+suites/bliss_tests-test_bliss_fft.obj: suites/test_bliss_fft.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_fft.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo -c -o suites/bliss_tests-test_bliss_fft.obj `if test -f 'suites/test_bliss_fft.c'; then $(CYGPATH_W) 'suites/test_bliss_fft.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_fft.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_fft.c' object='suites/bliss_tests-test_bliss_fft.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_fft.obj `if test -f 'suites/test_bliss_fft.c'; then $(CYGPATH_W) 'suites/test_bliss_fft.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_fft.c'; fi`
+
+suites/bliss_tests-test_bliss_bitpacker.o: suites/test_bliss_bitpacker.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_bitpacker.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo -c -o suites/bliss_tests-test_bliss_bitpacker.o `test -f 'suites/test_bliss_bitpacker.c' || echo '$(srcdir)/'`suites/test_bliss_bitpacker.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_bitpacker.c' object='suites/bliss_tests-test_bliss_bitpacker.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_bitpacker.o `test -f 'suites/test_bliss_bitpacker.c' || echo '$(srcdir)/'`suites/test_bliss_bitpacker.c
+
+suites/bliss_tests-test_bliss_bitpacker.obj: suites/test_bliss_bitpacker.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_bitpacker.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo -c -o suites/bliss_tests-test_bliss_bitpacker.obj `if test -f 'suites/test_bliss_bitpacker.c'; then $(CYGPATH_W) 'suites/test_bliss_bitpacker.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_bitpacker.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_bitpacker.c' object='suites/bliss_tests-test_bliss_bitpacker.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_bitpacker.obj `if test -f 'suites/test_bliss_bitpacker.c'; then $(CYGPATH_W) 'suites/test_bliss_bitpacker.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_bitpacker.c'; fi`
+
+suites/bliss_tests-test_bliss_huffman.o: suites/test_bliss_huffman.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_huffman.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo -c -o suites/bliss_tests-test_bliss_huffman.o `test -f 'suites/test_bliss_huffman.c' || echo '$(srcdir)/'`suites/test_bliss_huffman.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_huffman.c' object='suites/bliss_tests-test_bliss_huffman.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_huffman.o `test -f 'suites/test_bliss_huffman.c' || echo '$(srcdir)/'`suites/test_bliss_huffman.c
+
+suites/bliss_tests-test_bliss_huffman.obj: suites/test_bliss_huffman.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_huffman.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo -c -o suites/bliss_tests-test_bliss_huffman.obj `if test -f 'suites/test_bliss_huffman.c'; then $(CYGPATH_W) 'suites/test_bliss_huffman.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_huffman.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_huffman.c' object='suites/bliss_tests-test_bliss_huffman.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_huffman.obj `if test -f 'suites/test_bliss_huffman.c'; then $(CYGPATH_W) 'suites/test_bliss_huffman.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_huffman.c'; fi`
+
+suites/bliss_tests-test_bliss_keys.o: suites/test_bliss_keys.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_keys.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo -c -o suites/bliss_tests-test_bliss_keys.o `test -f 'suites/test_bliss_keys.c' || echo '$(srcdir)/'`suites/test_bliss_keys.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_keys.c' object='suites/bliss_tests-test_bliss_keys.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_keys.o `test -f 'suites/test_bliss_keys.c' || echo '$(srcdir)/'`suites/test_bliss_keys.c
+
+suites/bliss_tests-test_bliss_keys.obj: suites/test_bliss_keys.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_keys.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo -c -o suites/bliss_tests-test_bliss_keys.obj `if test -f 'suites/test_bliss_keys.c'; then $(CYGPATH_W) 'suites/test_bliss_keys.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_keys.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_keys.c' object='suites/bliss_tests-test_bliss_keys.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_keys.obj `if test -f 'suites/test_bliss_keys.c'; then $(CYGPATH_W) 'suites/test_bliss_keys.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_keys.c'; fi`
+
+suites/bliss_tests-test_bliss_sampler.o: suites/test_bliss_sampler.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sampler.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo -c -o suites/bliss_tests-test_bliss_sampler.o `test -f 'suites/test_bliss_sampler.c' || echo '$(srcdir)/'`suites/test_bliss_sampler.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_sampler.c' object='suites/bliss_tests-test_bliss_sampler.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sampler.o `test -f 'suites/test_bliss_sampler.c' || echo '$(srcdir)/'`suites/test_bliss_sampler.c
+
+suites/bliss_tests-test_bliss_sampler.obj: suites/test_bliss_sampler.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sampler.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo -c -o suites/bliss_tests-test_bliss_sampler.obj `if test -f 'suites/test_bliss_sampler.c'; then $(CYGPATH_W) 'suites/test_bliss_sampler.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sampler.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_sampler.c' object='suites/bliss_tests-test_bliss_sampler.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sampler.obj `if test -f 'suites/test_bliss_sampler.c'; then $(CYGPATH_W) 'suites/test_bliss_sampler.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sampler.c'; fi`
+
+suites/bliss_tests-test_bliss_signature.o: suites/test_bliss_signature.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_signature.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo -c -o suites/bliss_tests-test_bliss_signature.o `test -f 'suites/test_bliss_signature.c' || echo '$(srcdir)/'`suites/test_bliss_signature.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_signature.c' object='suites/bliss_tests-test_bliss_signature.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_signature.o `test -f 'suites/test_bliss_signature.c' || echo '$(srcdir)/'`suites/test_bliss_signature.c
+
+suites/bliss_tests-test_bliss_signature.obj: suites/test_bliss_signature.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_signature.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo -c -o suites/bliss_tests-test_bliss_signature.obj `if test -f 'suites/test_bliss_signature.c'; then $(CYGPATH_W) 'suites/test_bliss_signature.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_signature.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_signature.c' object='suites/bliss_tests-test_bliss_signature.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_signature.obj `if test -f 'suites/test_bliss_signature.c'; then $(CYGPATH_W) 'suites/test_bliss_signature.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_signature.c'; fi`
+
+suites/bliss_tests-test_bliss_sign.o: suites/test_bliss_sign.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sign.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo -c -o suites/bliss_tests-test_bliss_sign.o `test -f 'suites/test_bliss_sign.c' || echo '$(srcdir)/'`suites/test_bliss_sign.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_sign.c' object='suites/bliss_tests-test_bliss_sign.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sign.o `test -f 'suites/test_bliss_sign.c' || echo '$(srcdir)/'`suites/test_bliss_sign.c
+
+suites/bliss_tests-test_bliss_sign.obj: suites/test_bliss_sign.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sign.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo -c -o suites/bliss_tests-test_bliss_sign.obj `if test -f 'suites/test_bliss_sign.c'; then $(CYGPATH_W) 'suites/test_bliss_sign.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sign.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_sign.c' object='suites/bliss_tests-test_bliss_sign.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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sign.obj `if test -f 'suites/test_bliss_sign.c'; then $(CYGPATH_W) 'suites/test_bliss_sign.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sign.c'; fi`
+
+bliss_tests-bliss_tests.o: bliss_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT bliss_tests-bliss_tests.o -MD -MP -MF $(DEPDIR)/bliss_tests-bliss_tests.Tpo -c -o bliss_tests-bliss_tests.o `test -f 'bliss_tests.c' || echo '$(srcdir)/'`bliss_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bliss_tests-bliss_tests.Tpo $(DEPDIR)/bliss_tests-bliss_tests.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bliss_tests.c' object='bliss_tests-bliss_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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o bliss_tests-bliss_tests.o `test -f 'bliss_tests.c' || echo '$(srcdir)/'`bliss_tests.c
+
+bliss_tests-bliss_tests.obj: bliss_tests.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT bliss_tests-bliss_tests.obj -MD -MP -MF $(DEPDIR)/bliss_tests-bliss_tests.Tpo -c -o bliss_tests-bliss_tests.obj `if test -f 'bliss_tests.c'; then $(CYGPATH_W) 'bliss_tests.c'; else $(CYGPATH_W) '$(srcdir)/bliss_tests.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bliss_tests-bliss_tests.Tpo $(DEPDIR)/bliss_tests-bliss_tests.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bliss_tests.c' object='bliss_tests-bliss_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) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o bliss_tests-bliss_tests.obj `if test -f 'bliss_tests.c'; then $(CYGPATH_W) 'bliss_tests.c'; else $(CYGPATH_W) '$(srcdir)/bliss_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/libstrongswan/plugins/bliss/tests/bliss_tests.c b/src/libstrongswan/plugins/bliss/tests/bliss_tests.c
new file mode 100644
index 000000000..de21e77b7
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/bliss_tests.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <test_runner.h>
+
+#include <library.h>
+
+/* declare test suite constructors */
+#define TEST_SUITE(x) test_suite_t* x();
+#include "bliss_tests.h"
+#undef TEST_SUITE
+
+static test_configuration_t tests[] = {
+#define TEST_SUITE(x) \
+ { .suite = x, },
+#include "bliss_tests.h"
+ { .suite = NULL, }
+};
+
+static bool test_runner_init(bool init)
+{
+ if (init)
+ {
+ char *plugins, *plugindir;
+
+ plugins = lib->settings->get_str(lib->settings,
+ "tests.load", PLUGINS);
+ plugindir = lib->settings->get_str(lib->settings,
+ "tests.plugindir", PLUGINDIR);
+ plugin_loader_add_plugindirs(plugindir, plugins);
+ if (!lib->plugins->load(lib->plugins, plugins))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ lib->processor->set_threads(lib->processor, 0);
+ lib->processor->cancel(lib->processor);
+ lib->plugins->unload(lib->plugins);
+ }
+ return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_runner_run("bliss", tests, test_runner_init);
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/bliss_tests.h b/src/libstrongswan/plugins/bliss/tests/bliss_tests.h
new file mode 100644
index 000000000..f0959cc08
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/bliss_tests.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2014-2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * 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(bliss_fft_suite_create)
+TEST_SUITE(bliss_bitpacker_suite_create)
+TEST_SUITE(bliss_huffman_suite_create)
+TEST_SUITE(bliss_keys_suite_create)
+TEST_SUITE(bliss_sampler_suite_create)
+TEST_SUITE(bliss_signature_suite_create)
+TEST_SUITE(bliss_sign_suite_create)
+
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_bitpacker.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_bitpacker.c
new file mode 100644
index 000000000..6a728e280
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_bitpacker.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <bliss_bitpacker.h>
+
+static uint32_t bits[] = { 0, 1, 2, 3, 4, 7, 1, 14, 2, 29, 3, 28, 67, 0x2fe3a9c1};
+
+static chunk_t packed_bits = chunk_from_chars(0x6e, 0x71, 0xe1, 0x74,
+ 0x37, 0x21, 0x97, 0xf1,
+ 0xd4, 0xe0, 0x80);
+
+START_TEST(test_bliss_sign_bitpacker_write)
+{
+ chunk_t buf;
+ bliss_bitpacker_t *packer;
+ int i;
+
+ packer = bliss_bitpacker_create(81);
+
+ for (i = 0; i < 13; i++)
+ {
+ ck_assert(packer->write_bits(packer, bits[i], 1 + i/2));
+ }
+ ck_assert(packer->write_bits(packer, bits[13], 32));
+
+ buf = packer->extract_buf(packer);
+ ck_assert_int_eq(packer->get_bits(packer), 81);
+ ck_assert_chunk_eq(buf, packed_bits);
+
+ packer->destroy(packer);
+ free(buf.ptr);
+}
+END_TEST
+
+START_TEST(test_bliss_sign_bitpacker_read)
+{
+ uint32_t value;
+ bliss_bitpacker_t *packer;
+ int i;
+
+ packer = bliss_bitpacker_create_from_data(packed_bits);
+
+ ck_assert(!packer->read_bits(packer, &value, 33));
+
+ for (i = 0; i < 13; i++)
+ {
+ ck_assert(packer->read_bits(packer, &value, 1 + i/2));
+ ck_assert_int_eq(value, bits[i]);
+ }
+ ck_assert(packer->read_bits(packer, &value, 32));
+ ck_assert_int_eq(value, bits[13]);
+
+ packer->destroy(packer);
+}
+END_TEST
+
+START_TEST(test_bliss_sign_bitpacker_fail)
+{
+ bliss_bitpacker_t *packer;
+ uint32_t value;
+
+ packer = bliss_bitpacker_create(32);
+ ck_assert( packer->write_bits(packer, 0xff, 0));
+ ck_assert(!packer->write_bits(packer, 0, 33));
+ ck_assert( packer->write_bits(packer, 0x7f2a3b01, 31));
+ ck_assert(!packer->write_bits(packer, 3, 2));
+ packer->destroy(packer);
+
+ packer = bliss_bitpacker_create_from_data(
+ chunk_from_chars(0x7f, 0x2a, 0x3b, 0x01));
+ ck_assert(!packer->read_bits(packer, &value, 33));
+ ck_assert( packer->read_bits(packer, &value, 31));
+ ck_assert(!packer->read_bits(packer, &value, 2));
+ packer->destroy(packer);
+}
+END_TEST
+
+Suite *bliss_bitpacker_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("bliss_bitpacker");
+
+ tc = tcase_create("bitpacker_write");
+ tcase_add_test(tc, test_bliss_sign_bitpacker_write);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("bitpacker_read");
+ tcase_add_test(tc, test_bliss_sign_bitpacker_read);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("bitpacker_fail");
+ tcase_add_test(tc, test_bliss_sign_bitpacker_fail);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_fft.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_fft.c
new file mode 100644
index 000000000..009aaf802
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_fft.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <bliss_fft.h>
+
+static bliss_fft_params_t *fft_params[] = {
+ &bliss_fft_17_8,
+ &bliss_fft_12289_512
+};
+
+START_TEST(test_bliss_fft_impulse)
+{
+ bliss_fft_t *fft;
+ uint16_t n = fft_params[_i]->n;
+ uint32_t x[n], X[n];
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ x[i] = 0;
+ }
+ x[0] = 1;
+
+ fft = bliss_fft_create(fft_params[_i]);
+ fft->transform(fft, x, X, FALSE);
+
+ for (i = 0; i < n; i++)
+ {
+ ck_assert(X[i] == 1);
+ }
+ fft->transform(fft, X, x, TRUE);
+
+ for (i = 0; i < n; i++)
+ {
+ ck_assert(x[i] == (i == 0));
+ }
+ fft->destroy(fft);
+}
+END_TEST
+
+START_TEST(test_bliss_fft_wrap)
+{
+ bliss_fft_t *fft;
+ uint16_t n = fft_params[_i]->n;
+ uint16_t q = fft_params[_i]->q;
+ uint32_t x[n],y[n], X[n], Y[n];
+ int i, j;
+
+ for (i = 0; i < n; i++)
+ {
+ x[i] = i;
+ y[i] = 0;
+ }
+ fft = bliss_fft_create(fft_params[_i]);
+ ck_assert(fft->get_size(fft) == n);
+ ck_assert(fft->get_modulus(fft) == q);
+ fft->transform(fft, x, X, FALSE);
+
+ for (j = 0; j < n; j++)
+ {
+ y[j] = 1;
+ fft->transform(fft, y, Y, FALSE);
+
+ for (i = 0; i < n; i++)
+ {
+ Y[i] = (X[i] * Y[i]) % q;
+ }
+ fft->transform(fft, Y, Y, TRUE);
+
+ for (i = 0; i < n; i++)
+ {
+ ck_assert(Y[i] == ( i < j ? q - n - i + j : i - j));
+ }
+ y[j] = 0;
+ }
+ fft->destroy(fft);
+}
+END_TEST
+
+Suite *bliss_fft_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("bliss_fft");
+
+ tc = tcase_create("impulse");
+ tcase_add_loop_test(tc, test_bliss_fft_impulse, 0, countof(fft_params));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("negative_wrap");
+ tcase_add_loop_test(tc, test_bliss_fft_wrap, 0, countof(fft_params));
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_huffman.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_huffman.c
new file mode 100644
index 000000000..5447d0741
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_huffman.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * 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 <bliss_huffman_coder.h>
+
+static chunk_t data = chunk_from_chars(0x5f, 0x71, 0x9e, 0x4c);
+
+START_TEST(test_bliss_huffman_encode)
+{
+ bliss_bitpacker_t *packer;
+ bliss_huffman_code_t *code;
+ bliss_huffman_coder_t *coder;
+ chunk_t encoding;
+
+ packer = bliss_bitpacker_create(32);
+ ck_assert(packer);
+
+ code = bliss_huffman_code_get_by_id(BLISS_B_I);
+ ck_assert(code);
+
+ coder = bliss_huffman_coder_create(code, packer);
+ ck_assert(coder);
+
+ ck_assert( coder->encode(coder, 0, 0)); /* 0 */
+ ck_assert( coder->encode(coder, 1, 0)); /* 10 */
+ ck_assert( coder->encode(coder, 2, 0)); /* 111 */
+ ck_assert( coder->encode(coder, 0, 1)); /* 1101 */
+ ck_assert( coder->encode(coder, 0, -1)); /* 11000 */
+ ck_assert( coder->encode(coder, 1, 1)); /* 110011 */
+ ck_assert( coder->encode(coder, 1, -1)); /* 1100100 */
+ ck_assert(!coder->encode(coder, 3, 0)); /* 11001010 */
+ ck_assert(!coder->encode(coder, 8, 0)); /* - */
+
+ encoding = packer->extract_buf(packer);
+ ck_assert(chunk_equals(encoding, data));
+
+ chunk_free(&encoding);
+ coder->destroy(coder);
+ packer->destroy(packer);
+}
+END_TEST
+
+START_TEST(test_bliss_huffman_decode)
+{
+ bliss_bitpacker_t *packer;
+ bliss_huffman_code_t *code;
+ bliss_huffman_coder_t *coder;
+ int32_t z1;
+ int16_t z2;
+
+ packer = bliss_bitpacker_create_from_data(data);
+ ck_assert(packer);
+
+ code = bliss_huffman_code_get_by_id(BLISS_II);
+ ck_assert(!code);
+ code = bliss_huffman_code_get_by_id(BLISS_B_II);
+ ck_assert(!code);
+ code = bliss_huffman_code_get_by_id(BLISS_B_I);
+ ck_assert(code);
+
+ coder = bliss_huffman_coder_create(code, packer);
+ ck_assert(coder);
+
+ ck_assert(coder->decode(coder, &z1, &z2)); /* 0 */
+ ck_assert(z1 == 0 && z2 == 0);
+
+ ck_assert(coder->decode(coder, &z1, &z2)); /* 10 */
+ ck_assert(z1 == 1 && z2 == 0);
+
+ ck_assert(coder->decode(coder, &z1, &z2)); /* 111 */
+ ck_assert(z1 == 2 && z2 == 0);
+
+ ck_assert(coder->decode(coder, &z1, &z2)); /* 1101 */
+ ck_assert(z1 == 0 && z2 == 1);
+
+ ck_assert(coder->decode(coder, &z1, &z2)); /* 11000 */
+ ck_assert(z1 == 0 && z2 == -1);
+
+ ck_assert(coder->decode(coder, &z1, &z2)); /* 110011 */
+ ck_assert(z1 == 1 && z2 == 1);
+
+ ck_assert(coder->decode(coder, &z1, &z2)); /* 1100100 */
+ ck_assert(z1 == 1 && z2 == -1);
+
+ ck_assert(!coder->decode(coder, &z1, &z2)); /* 11001010 */
+
+ coder->destroy(coder);
+ packer->destroy(packer);
+}
+END_TEST
+
+Suite *bliss_huffman_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("bliss_huffman");
+
+ tc = tcase_create("huffman_encode");
+ tcase_add_test(tc, test_bliss_huffman_encode);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("huffman_decode");
+ tcase_add_test(tc, test_bliss_huffman_decode);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_keys.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_keys.c
new file mode 100644
index 000000000..f48bc1d79
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_keys.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * 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 <bliss_private_key.h>
+#include <bliss_public_key.h>
+
+static chunk_t privkey_chunk[] = {
+ {NULL, 0},
+ chunk_from_chars(0x30, 0x00),
+ chunk_from_chars(0x30, 0x01),
+ chunk_from_chars(0x30, 0x03, 0x06, 0x01, 0x01),
+ chunk_from_chars(0x30, 0x0d, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
+ 0xa0, 0x2a, 0x05, 0x02, 0x06),
+ chunk_from_chars(0x30, 0x0f, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82,
+ 0xa0, 0x2a, 0x05, 0x02, 0x05, 0x03, 0x00),
+ chunk_from_chars(0x30, 0x82, 0x04, 0x9a, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04,
+ 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x02, 0x05, 0x03, 0x82, 0x03,
+ 0x81, 0x00, 0x81, 0xe5, 0xd2, 0x71, 0xeb, 0x98, 0xe5, 0x24,
+ 0x34, 0xe4, 0x8a, 0x27, 0x23, 0x7d, 0x7d, 0x2c, 0xa3, 0xa7,
+ 0x3f, 0x87, 0xad, 0xae, 0xfa, 0xe4, 0x66, 0x1c, 0xef, 0x69,
+ 0x63, 0x5e, 0x91, 0xda, 0x41, 0x45, 0xd5, 0x8a, 0xb5, 0x26,
+ 0x33, 0x32, 0xe0, 0xa2, 0x9b, 0x52, 0x5e, 0x49, 0x5d, 0x0d,
+ 0x62, 0x72, 0x68, 0xa5, 0x94, 0x24, 0x03, 0x98, 0x48, 0x60,
+ 0x4a, 0x98, 0x97, 0x0d, 0x60, 0x7d, 0x00, 0x4f, 0xb9, 0xaf,
+ 0xcb, 0x6b, 0x41, 0x3d, 0x5b, 0xe4, 0x3e, 0x9a, 0xee, 0x06,
+ /* 100 */ 0xa1, 0xd0, 0x93, 0x53, 0x88, 0x58, 0x83, 0xb2, 0x44, 0xa1,
+ 0x16, 0x58, 0x3d, 0x32, 0xa1, 0x29, 0x85, 0x1a, 0x24, 0xc8,
+ 0xb8, 0x8c, 0x1f, 0x43, 0xbb, 0x4b, 0xdd, 0x8e, 0x72, 0xd3,
+ 0xf4, 0xfc, 0x02, 0x69, 0x47, 0xa5, 0x9d, 0xd0, 0xfc, 0xa6,
+ 0x94, 0x2e, 0x02, 0x6d, 0x85, 0x2c, 0x6d, 0xe3, 0x91, 0xd5,
+ 0xf1, 0x54, 0xbd, 0x1e, 0x63, 0x6b, 0xee, 0x28, 0xf9, 0xc6,
+ 0xec, 0x05, 0x99, 0xd5, 0xdd, 0xe5, 0x72, 0x9b, 0xbc, 0xa7,
+ 0x5a, 0x4a, 0x46, 0x3e, 0xec, 0xd7, 0x0b, 0xc5, 0x23, 0x00,
+ 0xdc, 0x08, 0x09, 0x57, 0x44, 0x2e, 0x43, 0x0f, 0xea, 0xca,
+ 0x2a, 0x31, 0xbe, 0xf3, 0x04, 0x8f, 0x8b, 0xa6, 0x3c, 0x35,
+ /* 200 */ 0x80, 0x2b, 0xe2, 0x18, 0x22, 0xfd, 0xe9, 0x39, 0x57, 0xed,
+ 0x77, 0x1d, 0x32, 0x02, 0x48, 0x2c, 0x85, 0x53, 0x9f, 0x4a,
+ 0xd8, 0x86, 0x4d, 0xd2, 0x26, 0x19, 0x12, 0x19, 0xa2, 0xb5,
+ 0xdf, 0x02, 0x50, 0xe4, 0x32, 0x9a, 0x27, 0xd0, 0x9e, 0x49,
+ 0x4a, 0x13, 0x9a, 0xfc, 0x07, 0x98, 0x60, 0x65, 0xf4, 0xc1,
+ 0x6c, 0x9a, 0x15, 0x28, 0x74, 0x5c, 0xd0, 0xa8, 0xe6, 0x2e,
+ 0x1f, 0xe9, 0xe6, 0x2b, 0xc8, 0x46, 0xe9, 0x26, 0xb0, 0xf0,
+ 0x8a, 0xe6, 0x8c, 0x9b, 0xbf, 0x64, 0xa0, 0x59, 0x33, 0x4f,
+ 0xc0, 0x0c, 0x16, 0x72, 0x89, 0x79, 0x2a, 0x3a, 0x5e, 0x3d,
+ 0x40, 0xbb, 0x73, 0xa9, 0xc0, 0x52, 0x70, 0x57, 0x06, 0xc1,
+ /* 300 */ 0xe7, 0x70, 0xb8, 0x6d, 0x1b, 0x50, 0x61, 0x85, 0xee, 0x3e,
+ 0xe5, 0x5a, 0x8a, 0x75, 0x9f, 0x1e, 0xb7, 0xea, 0x54, 0x5a,
+ 0x8f, 0x52, 0xc2, 0xae, 0x2c, 0x7a, 0x58, 0xe6, 0xcb, 0xa6,
+ 0x9b, 0x68, 0x84, 0x79, 0xf2, 0x82, 0x05, 0x57, 0xaa, 0xd5,
+ 0x51, 0x82, 0xec, 0x84, 0x63, 0xce, 0xf4, 0xa7, 0xdf, 0x4e,
+ 0xac, 0x7d, 0xdd, 0xc3, 0x02, 0x68, 0xe0, 0x35, 0xa1, 0x92,
+ 0x29, 0x02, 0x2c, 0xa0, 0xe4, 0x29, 0x66, 0xd3, 0xe8, 0xd9,
+ 0x52, 0x0f, 0x3b, 0xec, 0x53, 0x63, 0x57, 0xc3, 0xd2, 0x59,
+ 0x38, 0xe7, 0x74, 0xf4, 0x1d, 0x03, 0x88, 0x3c, 0xe9, 0x97,
+ 0x37, 0xd7, 0x12, 0x66, 0x2a, 0xb5, 0xf8, 0xcd, 0x10, 0x87,
+ /* 400 */ 0x5d, 0x6a, 0x69, 0xbb, 0x9b, 0xc5, 0x55, 0x3c, 0x09, 0x46,
+ 0x04, 0x57, 0xc0, 0x2f, 0x77, 0x89, 0xe2, 0x88, 0x15, 0x6b,
+ 0x71, 0x56, 0xe1, 0xa2, 0x30, 0x71, 0x5f, 0x1d, 0x27, 0x12,
+ 0xbf, 0xc3, 0x55, 0xde, 0xe5, 0x9c, 0x4e, 0xb8, 0xc6, 0xec,
+ 0x96, 0x3a, 0x5d, 0x6d, 0xe9, 0xd3, 0xf8, 0x28, 0xda, 0x3f,
+ 0x75, 0x24, 0xd0, 0x34, 0x50, 0xa6, 0x28, 0x65, 0x6a, 0xe9,
+ 0xa6, 0x89, 0xe5, 0x5d, 0x45, 0xaf, 0x63, 0x34, 0xaf, 0x31,
+ 0x29, 0x82, 0xe6, 0x03, 0x80, 0x5c, 0x34, 0x28, 0xd1, 0x9f,
+ 0xca, 0xd3, 0x96, 0xcb, 0x31, 0xde, 0xdb, 0xf0, 0x07, 0x2b,
+ 0xc5, 0xbc, 0x29, 0xd1, 0x11, 0xf4, 0x23, 0x3b, 0x14, 0xb5,
+ /* 500 */ 0xa6, 0xf1, 0x02, 0x9e, 0x66, 0xbe, 0xdc, 0xc4, 0xca, 0xf7,
+ 0xc0, 0x81, 0x92, 0x7c, 0xea, 0xe3, 0x42, 0x54, 0x8a, 0x6f,
+ 0x0a, 0x2a, 0xa7, 0x2a, 0x92, 0xab, 0x09, 0xb1, 0x61, 0x91,
+ 0xaa, 0x90, 0x54, 0xa3, 0x76, 0x64, 0xe2, 0xfd, 0x81, 0x9a,
+ 0x4c, 0x35, 0x11, 0x28, 0xf3, 0x14, 0x97, 0x1b, 0x61, 0xa4,
+ 0x67, 0x43, 0xae, 0x90, 0x6b, 0xe4, 0x29, 0x34, 0xec, 0x08,
+ 0xbc, 0x6a, 0x82, 0x45, 0xc7, 0x7d, 0xdc, 0xd0, 0x03, 0x98,
+ 0x29, 0x63, 0x05, 0x94, 0xb2, 0xb9, 0x04, 0xce, 0x34, 0x9a,
+ 0x64, 0xae, 0x9a, 0xa9, 0x11, 0xa5, 0x13, 0x07, 0xcc, 0x92,
+ 0xe9, 0xe5, 0x98, 0x13, 0x13, 0x8f, 0x8b, 0xb2, 0x77, 0x75,
+ /* 600 */ 0x2a, 0x6f, 0xb1, 0xa6, 0x98, 0xbf, 0x50, 0xaf, 0xa7, 0x15,
+ 0x2a, 0xe6, 0xdf, 0x41, 0xb6, 0x5e, 0x72, 0xb2, 0x74, 0xf2,
+ 0x38, 0x88, 0x41, 0x56, 0x53, 0xea, 0x83, 0x23, 0x8a, 0x6d,
+ 0x6c, 0x64, 0x6c, 0xa6, 0x04, 0x79, 0x51, 0x92, 0x89, 0xbe,
+ 0x2a, 0x54, 0xd8, 0x5a, 0x8d, 0x5b, 0x9c, 0xfc, 0x62, 0x05,
+ 0x0f, 0xbd, 0x85, 0x12, 0x57, 0x45, 0x96, 0x2e, 0x8f, 0x76,
+ 0xd4, 0x33, 0xfb, 0x4a, 0xc2, 0x9f, 0x57, 0x96, 0xb3, 0xa2,
+ 0xc6, 0xa6, 0x95, 0x3c, 0x9e, 0x7e, 0x15, 0x12, 0xd7, 0xe4,
+ 0x65, 0x05, 0x5d, 0x72, 0xc2, 0x28, 0x10, 0xa9, 0x68, 0xa9,
+ 0x01, 0xfe, 0x9e, 0x36, 0x07, 0x80, 0x41, 0xc8, 0xa3, 0x5f,
+ /* 700 */ 0x18, 0x3b, 0x38, 0x09, 0x95, 0xe2, 0x87, 0xad, 0x03, 0xfd,
+ 0xdd, 0xa6, 0xe9, 0x8e, 0xa8, 0x3a, 0xc9, 0x45, 0x7b, 0xdc,
+ 0xc2, 0x6a, 0x30, 0x78, 0xaa, 0xba, 0x32, 0xe9, 0x8a, 0x65,
+ 0x48, 0x13, 0x5b, 0x29, 0x18, 0x2e, 0x5c, 0x68, 0x8d, 0x71,
+ 0x01, 0x09, 0xab, 0x7d, 0x1a, 0xe9, 0x09, 0x74, 0x1b, 0xe1,
+ 0x90, 0x00, 0xb9, 0xda, 0xa3, 0x03, 0xb7, 0x6c, 0xdd, 0x40,
+ 0xb6, 0xe3, 0xde, 0xa6, 0x7b, 0xe9, 0x3d, 0x41, 0x4d, 0xc7,
+ 0xad, 0xa5, 0xf9, 0x8b, 0x88, 0xd4, 0x1a, 0x75, 0xb5, 0xb6,
+ 0x9f, 0x51, 0x9b, 0x8b, 0xd7, 0xa4, 0x02, 0xb0, 0x62, 0x45,
+ 0xdd, 0x6c, 0x11, 0x35, 0x03, 0x77, 0x1c, 0xdb, 0xc5, 0xac,
+ /* 800 */ 0x60, 0x37, 0x20, 0x15, 0xaf, 0xbd, 0xae, 0x76, 0x51, 0xd2,
+ 0xfb, 0x63, 0x23, 0x19, 0x81, 0xa6, 0x59, 0x7b, 0x68, 0x00,
+ 0x3d, 0x68, 0x89, 0x6b, 0x5a, 0x29, 0xbd, 0x4f, 0xc1, 0x50,
+ 0xe4, 0x98, 0x85, 0xe6, 0x1a, 0xdd, 0xc8, 0xe4, 0xa1, 0x2b,
+ 0x99, 0x42, 0x81, 0x4d, 0x07, 0xf4, 0x24, 0x93, 0x88, 0xfe,
+ 0x40, 0x90, 0x5a, 0x56, 0x0b, 0x7f, 0x8d, 0x14, 0x82, 0x6d,
+ 0xaf, 0xf6, 0x0a, 0x3d, 0xe6, 0x64, 0xb5, 0x48, 0x01, 0x37,
+ 0xfe, 0xf3, 0xba, 0x67, 0xcc, 0xd2, 0xba, 0x32, 0x76, 0xe8,
+ 0xa7, 0x41, 0x1f, 0x2a, 0xfc, 0xa9, 0x72, 0x66, 0xc7, 0xd5,
+ 0x76, 0x02, 0x6b, 0x77, 0xba, 0x6c, 0xd4, 0x84, 0x68, 0x0e,
+ /* 900 */ 0x62, 0xc8, 0x43, 0xb0, 0x81, 0xd5, 0x8f, 0xdb, 0x42, 0xc9,
+ 0xf4, 0xaf, 0x71, 0xbd, 0xb9, 0x6c, 0xd6, 0xdc, 0x03, 0x81,
+ 0x81, 0x00, 0xc5, 0x10, 0x40, 0x33, 0x0f, 0xc0, 0x14, 0x01,
+ 0x00, 0x03, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x0f, 0x10,
+ 0x03, 0x10, 0x00, 0x00, 0x01, 0xc0, 0x43, 0x40, 0x03, 0x5c,
+ 0x00, 0x07, 0xc0, 0x51, 0x34, 0x01, 0x30, 0x0c, 0x00, 0x00,
+ 0x04, 0xc0, 0x3d, 0x40, 0x03, 0x07, 0x40, 0xd3, 0x50, 0x0c,
+ 0x04, 0x03, 0x00, 0x11, 0x41, 0x30, 0x00, 0xc1, 0xc0, 0xc3,
+ 0x03, 0x5f, 0x04, 0x30, 0x01, 0x40, 0x40, 0x00, 0x40, 0x40,
+ 0x10, 0x40, 0x05, 0x05, 0x00, 0x53, 0x00, 0x04, 0x50, 0x00,
+ /* 1000 */ 0x00, 0x00, 0x0c, 0x00, 0x51, 0x00, 0x00, 0x00, 0x04, 0xc7,
+ 0x01, 0x50, 0xc0, 0x11, 0x00, 0x04, 0x03, 0xc0, 0x04, 0x00,
+ 0x70, 0x4c, 0x31, 0x03, 0xc0, 0x40, 0xc4, 0x40, 0x40, 0xc0,
+ 0x0c, 0x0c, 0xf1, 0x40, 0xc1, 0x31, 0x70, 0x17, 0xc0, 0x30,
+ 0xc1, 0x04, 0x0c, 0x04, 0x00, 0xc4, 0x01, 0x00, 0x34, 0x00,
+ 0x03, 0x81, 0x81, 0x00, 0xcc, 0x00, 0x50, 0x30, 0xc4, 0x13,
+ 0x0f, 0xf0, 0x43, 0x01, 0x33, 0x40, 0x30, 0x01, 0x40, 0x10,
+ 0x57, 0x04, 0x03, 0x04, 0x10, 0x00, 0xf0, 0x03, 0x04, 0x01,
+ 0x00, 0x10, 0x34, 0x03, 0xf0, 0x1c, 0x01, 0x40, 0x30, 0xf4,
+ 0x00, 0x40, 0x34, 0xc3, 0x00, 0x00, 0x01, 0x00, 0x01, 0x10,
+ /* 1100 */ 0x3f, 0x03, 0x40, 0x00, 0x10, 0x10, 0x00, 0x40, 0x03, 0x00,
+ 0x03, 0x04, 0x40, 0x03, 0x00, 0x13, 0x03, 0x00, 0xc0, 0x01,
+ 0x34, 0x01, 0x00, 0x00, 0x10, 0xf4, 0x00, 0xf0, 0x30, 0x00,
+ 0x00, 0xc3, 0x1c, 0x41, 0x00, 0x40, 0x30, 0x04, 0x10, 0xc4,
+ 0x11, 0x03, 0x00, 0x10, 0x04, 0x4f, 0x17, 0xc0, 0x00, 0x30,
+ 0xcd, 0x3c, 0x40, 0xc4, 0x00, 0xf0, 0x00, 0x00, 0x04, 0x30,
+ 0x0f, 0x31, 0x34, 0xf0, 0x00, 0x07, 0x0c, 0x34, 0x00, 0x50,
+ 0x05, 0x03, 0x10, 0x70, 0x00, 0x33, 0x0c, 0x00, 0xc4, 0x54,
+ 0x07, 0x00)
+};
+
+START_TEST(test_bliss_keys_priv)
+{
+ private_key_t *privkey;
+
+ privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+ BUILD_BLOB, privkey_chunk[_i], BUILD_END);
+ if (_i == countof(privkey_chunk) - 1)
+ {
+ ck_assert(privkey);
+ privkey->destroy(privkey);
+ }
+ else
+ {
+ ck_assert(!privkey);
+ }
+}
+END_TEST
+
+typedef struct privkey_mod_t privkey_mod_t;
+
+struct privkey_mod_t {
+ int offset;
+ char byte;
+};
+
+static privkey_mod_t privkey_mod[] = {
+ { 20, 0x80 },
+ { 22, 0xc1 },
+ { 920, 0x80 },
+ { 922, 0x85 },
+ { 1052, 0x80 },
+ { 1054, 0x8c }
+};
+
+START_TEST(test_bliss_keys_priv_mod)
+{
+ private_key_t *privkey;
+ chunk_t data;
+
+ data = chunk_clone(privkey_chunk[countof(privkey_chunk) - 1]);
+ data.ptr[privkey_mod[_i].offset] = privkey_mod[_i].byte;
+
+ privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+ BUILD_BLOB, data, BUILD_END);
+ ck_assert(!privkey);
+ chunk_free(&data);
+}
+END_TEST
+
+static chunk_t pubkey_chunk[] = {
+ {NULL, 0},
+ chunk_from_chars(0x30, 0x00),
+ chunk_from_chars(0x30, 0x01),
+ chunk_from_chars(0x30, 0x02, 0x30, 0x00),
+ chunk_from_chars(0x30, 0x05, 0x30, 0x03, 0x06, 0x01, 0x01),
+ chunk_from_chars(0x30, 0x11, 0x30, 0x0F, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04,
+ 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x04, 0x00),
+ chunk_from_chars(0x30, 0x12, 0x30, 0x10, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04,
+ 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x06, 0x01, 0x01),
+ chunk_from_chars(0x30, 0x1c, 0x30, 0x1a, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04,
+ 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x06, 0x0b, 0x2b,
+ 0x06, 0x01, 0x04, 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x02, 0x06),
+ chunk_from_chars(0x30, 0x1e, 0x30, 0x1a, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04,
+ 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x06, 0x0b, 0x2b,
+ 0x06, 0x01, 0x04, 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x02, 0x05,
+ 0x03, 0x00)
+};
+
+START_TEST(test_bliss_keys_pub)
+{
+ public_key_t *pubkey;
+
+ pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+ BUILD_BLOB, pubkey_chunk[_i], BUILD_END);
+ ck_assert(!pubkey);
+}
+END_TEST
+
+Suite *bliss_keys_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("bliss_keys");
+
+ tc = tcase_create("keys_priv");
+ tcase_add_loop_test(tc, test_bliss_keys_priv, 0, countof(privkey_chunk));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("keys_priv_mod");
+ tcase_add_loop_test(tc, test_bliss_keys_priv_mod, 0, countof(privkey_mod));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("keys_pub");
+ tcase_add_loop_test(tc, test_bliss_keys_pub, 0, countof(pubkey_chunk));
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sampler.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sampler.c
new file mode 100644
index 000000000..1bd1266ad
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sampler.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <bliss_sampler.h>
+
+static u_int key_size[] = { 1, 3, 4};
+
+START_TEST(test_bliss_sampler_gaussian)
+{
+ bliss_sampler_t *sampler;
+ bliss_param_set_t *set;
+ int i, k, count;
+ uint32_t hist[8], sign[3];
+ int32_t z;
+ hash_algorithm_t alg;
+ size_t seed_len;
+ chunk_t seed;
+
+ set = bliss_param_set_get_by_id(key_size[_i]);
+ alg = HASH_SHA256;
+ seed_len = 32;
+ count = 10000000;
+
+ seed = chunk_alloc(seed_len);
+ memset(seed.ptr, 0xcc, seed_len);
+
+ for (k = 0; k < 3; k++)
+ {
+ sign[k] = 0;
+ }
+ for (k = 0; k < 8; k++)
+ {
+ hist[k] = 0;
+ }
+
+ sampler = bliss_sampler_create(alg, seed, set);
+ for (i = 0; i < count; i++)
+ {
+ ck_assert(sampler->gaussian(sampler, &z));
+ if (z == 0)
+ {
+ sign[1]++;
+ hist[0]++;
+ }
+ else if (z > 0)
+ {
+ sign[2]++;
+ hist[z/256]++;
+ }
+ else
+ {
+ sign[0]++;
+ hist[(-z)/256]++;
+ }
+ }
+ sampler->destroy(sampler);
+ free(seed.ptr);
+
+ DBG1(DBG_LIB, "histogram");
+ for (k = 0; k < 8; k++)
+ {
+ DBG1(DBG_LIB, "%d %7d", k, hist[k]);
+ }
+ DBG1(DBG_LIB, "- %7d", sign[0]);
+ DBG1(DBG_LIB, "0 %7d", sign[1]);
+ DBG1(DBG_LIB, "+ %7d", sign[2]);
+}
+END_TEST
+
+Suite *bliss_sampler_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("bliss_sampler");
+
+ tc = tcase_create("sampler_gaussian");
+ tcase_set_timeout(tc, 10);
+ tcase_add_loop_test(tc, test_bliss_sampler_gaussian, 0, countof(key_size));
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c
new file mode 100644
index 000000000..8b4e9cbf0
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2014-2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * 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 <bliss_private_key.h>
+#include <bliss_public_key.h>
+
+static u_int key_type[] = { 1, 3, 4 };
+static u_int key_strength[] = { 128, 160, 192 };
+
+START_TEST(test_bliss_sign_all)
+{
+ signature_scheme_t signature_scheme;
+ private_key_t *privkey, *privkey1;
+ public_key_t *pubkey, *pubkey1;
+ chunk_t msg, signature, privkey_blob, pubkey_blob, pubkey_fp, privkey_fp;
+ int k;
+
+ for (k = 0; k < 4; k++)
+ {
+ int verify_count = 1000;
+
+ switch (k)
+ {
+ case 1:
+ signature_scheme = SIGN_BLISS_WITH_SHA256;
+ break;
+ case 2:
+ signature_scheme = SIGN_BLISS_WITH_SHA384;
+ break;
+ default:
+ signature_scheme = SIGN_BLISS_WITH_SHA512;
+ }
+
+ /* enforce BLISS-B key for k = 2, 3 */
+ lib->settings->set_bool(lib->settings,
+ "%s.plugins.bliss.use_bliss_b", k >= 2, lib->ns);
+
+ msg = chunk_from_str("Hello Dolly!");
+
+ /* generate private key */
+ privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+ BUILD_KEY_SIZE, key_type[_i], BUILD_END);
+ ck_assert(privkey);
+
+ /* generate ASN.1 DER and PEM encoding of private key */
+ ck_assert(privkey->get_encoding(privkey, (k % 2) ?
+ PRIVKEY_ASN1_DER : PRIVKEY_PEM, &privkey_blob));
+
+ /* extract public key from private key */
+ pubkey = privkey->get_public_key(privkey);
+ ck_assert(pubkey);
+
+ /* generate ASN.1 DER and PEM encodings of public key */
+ ck_assert(pubkey->get_encoding(pubkey, (k % 2) ?
+ PUBKEY_SPKI_ASN1_DER : PUBKEY_PEM, &pubkey_blob));
+
+ /* compare fingerprints of public and private key */
+ ck_assert(pubkey->get_fingerprint(pubkey, (k % 2) ?
+ KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &pubkey_fp));
+ ck_assert(privkey->get_fingerprint(privkey, (k % 2) ?
+ KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &privkey_fp));
+ ck_assert(chunk_equals(pubkey_fp, privkey_fp));
+
+ /* retrieve fingerprints of public and private key from cache */
+ ck_assert(pubkey->get_fingerprint(pubkey, (k % 2) ?
+ KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &pubkey_fp));
+ ck_assert(privkey->get_fingerprint(privkey, (k % 2) ?
+ KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &privkey_fp));
+
+ /* get a reference of the private key and destroy both instances */
+ privkey1 = privkey->get_ref(privkey);
+ ck_assert(privkey1);
+ ck_assert(privkey1 == privkey);
+ privkey->destroy(privkey);
+ privkey1->destroy(privkey1);
+
+ /* get a reference of the public key and destroy both instances */
+ pubkey1 = pubkey->get_ref(pubkey);
+ ck_assert(pubkey1);
+ ck_assert(pubkey1 == pubkey);
+ pubkey->destroy(pubkey);
+ pubkey1->destroy(pubkey1);
+
+ /* enforce BLISS-B key for k = 1, 3 */
+ lib->settings->set_bool(lib->settings,
+ "%s.plugins.bliss.use_bliss_b", k % 2, lib->ns);
+
+ /* load private key from ASN.1 blob */
+ privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+ BUILD_BLOB, privkey_blob, BUILD_END);
+ ck_assert(privkey);
+ ck_assert(privkey->get_type(privkey) == KEY_BLISS);
+ ck_assert(privkey->get_keysize(privkey) == key_strength[_i]);
+ chunk_free(&privkey_blob);
+
+ /* load public key from ASN.1 blob */
+ pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
+ BUILD_BLOB, pubkey_blob, BUILD_END);
+ ck_assert(pubkey);
+ ck_assert(pubkey->get_type(pubkey) == KEY_BLISS);
+ ck_assert(pubkey->get_keysize(pubkey) == key_strength[_i]);
+ chunk_free(&pubkey_blob);
+
+ /* generate and verify 1000 BLISS signatures */
+ while (verify_count--)
+ {
+ ck_assert(privkey->sign(privkey, signature_scheme, msg,
+ &signature));
+ ck_assert(pubkey->verify(pubkey, signature_scheme, msg,
+ signature));
+ free(signature.ptr);
+ }
+ privkey->destroy(privkey);
+ pubkey->destroy(pubkey);
+ }
+}
+END_TEST
+
+START_TEST(test_bliss_sign_fail)
+{
+ private_key_t *privkey;
+ public_key_t *pubkey;
+ chunk_t msg, signature, encoding, fp;
+
+ /* generate non-supported BLISS-II private key */
+ privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+ BUILD_KEY_SIZE, BLISS_II, BUILD_END);
+ ck_assert(!privkey);
+
+ /* generate non-supported BLISS-B-II private key */
+ privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+ BUILD_KEY_SIZE, BLISS_B_II, BUILD_END);
+ ck_assert(!privkey);
+
+ /* generate supported BLISS-B-I private key */
+ privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS,
+ BUILD_KEY_SIZE, BLISS_B_I, BUILD_END);
+ ck_assert(privkey);
+
+ /* wrong private key encoding format */
+ ck_assert(!privkey->get_encoding(privkey, PUBKEY_PEM, &encoding));
+
+ /* wrong fingerprint encoding format */
+ ck_assert(!privkey->get_fingerprint(privkey, KEYID_PGPV4, &fp));
+
+ /* extract public key */
+ pubkey = privkey->get_public_key(privkey);
+ ck_assert(pubkey);
+
+ /* wrong private key encoding format */
+ ck_assert(!pubkey->get_encoding(pubkey, PRIVKEY_PEM, &encoding));
+
+ /* wrong fingerprint encoding format */
+ ck_assert(!pubkey->get_fingerprint(pubkey, KEYID_PGPV4, &fp));
+
+ /* encryption / decryption operation is not defined for BLISS */
+ ck_assert(!pubkey->encrypt(pubkey, ENCRYPT_UNKNOWN, chunk_empty, NULL));
+ ck_assert(!privkey->decrypt(privkey, ENCRYPT_UNKNOWN, chunk_empty, NULL));
+
+ /* sign with invalid signature scheme */
+ ck_assert(!privkey->sign(privkey, SIGN_UNKNOWN, msg, &signature));
+
+ /* generate valid signature */
+ msg = chunk_from_str("Hello Dolly!");
+ ck_assert(privkey->sign(privkey, SIGN_BLISS_WITH_SHA512, msg, &signature));
+
+ /* verify with invalid signature scheme */
+ ck_assert(!pubkey->verify(pubkey, SIGN_UNKNOWN, msg, signature));
+
+ /* corrupt signature */
+ signature.ptr[signature.len - 1] ^= 0x80;
+ ck_assert(!pubkey->verify(pubkey, SIGN_BLISS_WITH_SHA512, msg, signature));
+
+ free(signature.ptr);
+ privkey->destroy(privkey);
+ pubkey->destroy(pubkey);
+}
+END_TEST
+
+Suite *bliss_sign_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("bliss_sign");
+
+ tc = tcase_create("sign_all");
+ test_case_set_timeout(tc, 30);
+ tcase_add_loop_test(tc, test_bliss_sign_all, 0, countof(key_type));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("sign_fail");
+ tcase_add_test(tc, test_bliss_sign_fail);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_signature.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_signature.c
new file mode 100644
index 000000000..2a2f48c53
--- /dev/null
+++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_signature.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * 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 <bliss_signature.h>
+
+static chunk_t data = chunk_from_chars(
+ 0xC1, 0xA1, 0x96, 0x98, 0x4F, 0x60, 0xF5, 0xCA, 0x89, 0x9E,
+ 0x78, 0xAF, 0x64, 0xDD, 0x01, 0x76, 0x04, 0x29, 0x11, 0xD0,
+ 0x21, 0x9E, 0xE4, 0x2D, 0xC5, 0x82, 0x69, 0x19, 0x82, 0x75,
+ 0x30, 0xAC, 0xB0, 0x64, 0xCB, 0x65, 0x19, 0x22, 0x4A, 0x03,
+ 0x03, 0x61, 0x4A, 0x37, 0x8E, 0xA3, 0xB6, 0xB3, 0x58, 0x44,
+ 0xFD, 0x68, 0x38, 0xF1, 0x4B, 0xCF, 0xE8, 0xA2, 0x05, 0x39,
+ 0x87, 0xE0, 0x5E, 0x7C, 0x45, 0x33, 0x4A, 0xEB, 0x2E, 0xCF,
+ 0x98, 0x01, 0x3D, 0x28, 0x60, 0xCE, 0x90, 0x45, 0xF0, 0x8E,
+ 0x36, 0x25, 0x50, 0x8B, 0xA2, 0xC0, 0x6E, 0xDF, 0xC2, 0xA1,
+ 0x35, 0xC1, 0x16, 0x14, 0xE8, 0x6A, 0xE3, 0x9C, 0x0B, 0x32,
+ 0x53, 0x55, 0x60, 0x52, 0x43, 0x93, 0xBB, 0x9F, 0x1D, 0x17,
+ 0xDC, 0x6E, 0x26, 0x99, 0x60, 0x83, 0x12, 0x53, 0xB0, 0x2B,
+ 0x36, 0xE2, 0x95, 0xA7, 0xBF, 0x9B, 0xC0, 0x0A, 0x63, 0xD6,
+ 0x32, 0xA9, 0xE2, 0xAD, 0x02, 0x53, 0x10, 0x81, 0x00, 0xD4,
+ 0x9A, 0xC2, 0x04, 0x1B, 0x48, 0x53, 0x37, 0xF0, 0x95, 0x39,
+ 0x4B, 0x2E, 0x37, 0x28, 0xE2, 0x70, 0xAD, 0xB5, 0xF1, 0x63,
+ 0x48, 0x17, 0xEF, 0x45, 0xC0, 0x30, 0xA6, 0xAA, 0x37, 0x9A,
+ 0x00, 0x8F, 0x8D, 0xAC, 0x66, 0x2C, 0x96, 0x8C, 0xC2, 0x74,
+ 0x9D, 0x66, 0x16, 0x5D, 0x70, 0x70, 0x1D, 0x2F, 0x11, 0xBD,
+ 0x11, 0x62, 0x58, 0xC6, 0xB2, 0xA6, 0xFA, 0xB7, 0x8C, 0x10,
+ 0x6A, 0x13, 0x34, 0x25, 0xB8, 0xF2, 0x46, 0xE3, 0x08, 0xAD,
+ 0x8D, 0x49, 0x33, 0x24, 0x37, 0xA5, 0x0A, 0xF9, 0x5E, 0x95,
+ 0xF9, 0x50, 0xDA, 0x2B, 0x80, 0x4F, 0x10, 0x4F, 0xAB, 0xE4,
+ 0x96, 0xB1, 0xA1, 0x28, 0xCE, 0x6D, 0xB6, 0x17, 0x33, 0x2A,
+ 0xE0, 0xC3, 0x80, 0xAA, 0x3D, 0x1A, 0x5C, 0x48, 0xA0, 0x48,
+ 0x60, 0xCC, 0xC7, 0x29, 0x4F, 0xB8, 0x96, 0xDF, 0xC6, 0x6A,
+ 0xC2, 0x83, 0x5E, 0xFC, 0xD7, 0x4E, 0xCA, 0x14, 0xB4, 0xC6,
+ 0x30, 0x29, 0xC7, 0xCE, 0x79, 0x42, 0x2D, 0x22, 0x28, 0x99,
+ 0x59, 0x14, 0xFB, 0x04, 0xAD, 0x79, 0x3C, 0x74, 0x34, 0xC6,
+ 0x7A, 0x1C, 0x13, 0x07, 0x17, 0xB1, 0x8A, 0x02, 0xA7, 0x70,
+ 0x3C, 0x5B, 0xBA, 0x88, 0xA2, 0xE6, 0x4B, 0x2A, 0xC1, 0x1E,
+ 0x42, 0xDD, 0x83, 0x2B, 0x00, 0xCC, 0xF8, 0x80, 0x03, 0x7E,
+ 0x97, 0xA4, 0x04, 0xE1, 0xB2, 0x0B, 0xE2, 0xF3, 0x91, 0x91,
+ 0x80, 0xA0, 0xC5, 0x44, 0x67, 0xB1, 0x56, 0xD0, 0x13, 0x58,
+ 0x7B, 0x6E, 0x12, 0xE7, 0x3A, 0x90, 0xE4, 0x2C, 0x44, 0x17,
+ 0xA3, 0xBD, 0x21, 0x68, 0x45, 0x61, 0x20, 0x57, 0x8D, 0x4A,
+ 0xF1, 0xE6, 0xD3, 0x17, 0xC9, 0xB0, 0xF8, 0x3A, 0x87, 0x6A,
+ 0x7E, 0x25, 0x45, 0xDC, 0x9A, 0x1D, 0xAC, 0x10, 0xB6, 0xF6,
+ 0x07, 0x4C, 0x50, 0x92, 0xF9, 0xE1, 0x3E, 0xAD, 0x3B, 0x80,
+ 0x20, 0xA8, 0x34, 0x04, 0xD6, 0x0D, 0x2D, 0x46, 0x69, 0x5E,
+ 0x8C, 0x4B, 0xB0, 0x1C, 0x37, 0xD8, 0x0D, 0x72, 0x7B, 0xE6,
+ 0xEE, 0x04, 0x81, 0x98, 0x78, 0x69, 0x88, 0xD8, 0xDF, 0x04,
+ 0xF0, 0x80, 0xE2, 0x0A, 0xD3, 0x60, 0x94, 0xDF, 0x49, 0xF7,
+ 0x52, 0x95, 0xA6, 0xAF, 0x8C, 0x13, 0x10, 0x09, 0xAA, 0x03,
+ 0xAC, 0x2C, 0x89, 0x2D, 0x2C, 0x61, 0x0F, 0xBE, 0x5C, 0x29,
+ 0x01, 0x7C, 0x9E, 0xD2, 0xFF, 0x34, 0xA1, 0x9E, 0xEE, 0xBF,
+ 0x28, 0x18, 0x3A, 0x17, 0xA6, 0x40, 0x94, 0xD5, 0xC4, 0xEC,
+ 0x27, 0x0A, 0x40, 0x1C, 0xC4, 0x16, 0x80, 0x4E, 0x6F, 0xDD,
+ 0xA5, 0x6A, 0x03, 0xE8, 0xBA, 0xB2, 0xAA, 0x7A, 0x7F, 0x4B,
+ 0x30, 0x11, 0x11, 0x12, 0x4A, 0xFE, 0xB2, 0x99, 0xC6, 0x12,
+ 0x1A, 0x98, 0xC0, 0x15, 0x41, 0xE1, 0x55, 0x35, 0x54, 0xF2,
+ 0x1C, 0xE2, 0x78, 0x85, 0x66, 0xD3, 0x9C, 0x8A, 0x88, 0x7C,
+ 0x86, 0x7F, 0x48, 0xBE, 0xB7, 0x1C, 0xE4, 0xCF, 0x35, 0xEE,
+ 0x24, 0xA6, 0x62, 0xD6, 0x36, 0x1F, 0x66, 0x10, 0x5D, 0xEF,
+ 0x07, 0x64, 0xA8, 0xD0, 0xAD, 0x2F, 0x47, 0x02, 0xA2, 0x0F,
+ 0x73, 0x96, 0x2A, 0x21, 0x20, 0x36, 0x01, 0xA3, 0x2F, 0x5E,
+ 0xC8, 0x80, 0x3A, 0x54, 0xA6, 0xB5, 0xD0, 0x19, 0xBF, 0xC4,
+ 0x35, 0x01, 0x0B, 0x2A, 0x8E, 0x61, 0x4A, 0xDD, 0xB2, 0x4A,
+ 0xE1, 0x0C, 0x15, 0x94, 0x9C, 0xD2, 0x54, 0x93, 0x85, 0x16,
+ 0x49, 0x69, 0xA0, 0x41, 0x34, 0x16, 0x69, 0x28, 0x74, 0x11,
+ 0x88, 0x44, 0xC8, 0x46, 0x5E, 0x62, 0xFF, 0x6E, 0xC5, 0xA8,
+ 0xE8, 0x8A, 0x8A, 0xFA, 0x2D, 0x94, 0x14, 0xD4, 0x51, 0x16,
+ 0xB0, 0x40, 0xDC, 0xF3, 0xAA, 0x97, 0x39, 0x1A, 0xDA, 0x7F,
+ 0x41, 0x61, 0x25, 0x1E, 0xDF, 0x46, 0x29, 0x44, 0x80, 0xEA,
+ 0x10, 0xE4, 0x0F, 0x94, 0xA6, 0x52, 0x20, 0x06, 0x9C, 0x69,
+ 0x48, 0x1F, 0x45, 0x30, 0x4B, 0x21, 0x02, 0xE6, 0xF3, 0x44,
+ 0x35, 0xC1, 0xC8, 0xC9, 0x68, 0x6C, 0x43, 0xA4, 0x56, 0x07,
+ 0x36, 0x11, 0xFB, 0x6D, 0x8E, 0xF0, 0x62, 0x5A, 0x3C, 0x8B,
+ 0x23, 0xF1, 0x46, 0xE2, 0x76, 0x2A, 0x6F, 0xBB, 0x09, 0x24,
+ 0x18, 0x64, 0xE6, 0x5C, 0xD0, 0x85, 0x69, 0xF0, 0x4F, 0x66,
+ 0x97, 0x40, 0x01, 0x27, 0xD1, 0x41, 0xCC, 0xEB, 0x4D, 0xB7,
+ 0x04, 0xC4, 0x91, 0xE0, 0x95, 0x8A, 0x43, 0x26, 0x2D, 0x1F,
+ 0x88, 0xA0, 0xD8
+);
+
+START_TEST(test_bliss_signature_fail)
+{
+ bliss_param_set_t set2 = { .id = BLISS_B_II };
+ bliss_param_set_t *set;
+ bliss_signature_t *signature;
+ chunk_t encoding;
+ int k;
+
+ signature = bliss_signature_create(&set2);
+ ck_assert(signature);
+ encoding = signature->get_encoding(signature);
+ ck_assert(encoding.len == 0);
+ signature->destroy(signature);
+
+ signature = bliss_signature_create_from_data(&set2, data);
+ ck_assert(!signature);
+
+ set = bliss_param_set_get_by_id(BLISS_B_I);
+ ck_assert(set);
+
+ for (k = 0; k < data.len - 2; k++)
+ {
+ chunk_t fragment = { data.ptr, k };
+
+ signature = bliss_signature_create_from_data(set, fragment);
+ ck_assert(!signature);
+ }
+ signature = bliss_signature_create_from_data(set, data);
+ ck_assert(signature);
+ signature->destroy(signature);
+}
+END_TEST
+
+Suite *bliss_signature_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("bliss_signature");
+
+ tc = tcase_create("signature_fail");
+ tcase_add_test(tc, test_bliss_signature_fail);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/plugins/blowfish/Makefile.in b/src/libstrongswan/plugins/blowfish/Makefile.in
index 33e5958ed..f19616552 100644
--- a/src/libstrongswan/plugins/blowfish/Makefile.in
+++ b/src/libstrongswan/plugins/blowfish/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/libstrongswan/plugins/ccm/Makefile.in b/src/libstrongswan/plugins/ccm/Makefile.in
index 43bdf1fc5..ca7cadbe4 100644
--- a/src/libstrongswan/plugins/ccm/Makefile.in
+++ b/src/libstrongswan/plugins/ccm/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/libstrongswan/plugins/cmac/Makefile.in b/src/libstrongswan/plugins/cmac/Makefile.in
index 7c5674045..9e249399b 100644
--- a/src/libstrongswan/plugins/cmac/Makefile.in
+++ b/src/libstrongswan/plugins/cmac/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/libstrongswan/plugins/cmac/cmac.c b/src/libstrongswan/plugins/cmac/cmac.c
index c8cb7fbf2..4f222ff4e 100644
--- a/src/libstrongswan/plugins/cmac/cmac.c
+++ b/src/libstrongswan/plugins/cmac/cmac.c
@@ -247,6 +247,9 @@ METHOD(mac_t, set_key, bool,
{
chunk_t resized, iv, l;
+ memset(this->t, 0, this->b);
+ this->remaining_bytes = 0;
+
/* we support variable keys as defined in RFC 4615 */
if (key.len == this->b)
{
diff --git a/src/libstrongswan/plugins/constraints/Makefile.in b/src/libstrongswan/plugins/constraints/Makefile.in
index 39469368c..2e623ad3b 100644
--- a/src/libstrongswan/plugins/constraints/Makefile.in
+++ b/src/libstrongswan/plugins/constraints/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/libstrongswan/plugins/constraints/constraints_validator.c b/src/libstrongswan/plugins/constraints/constraints_validator.c
index 62ccc7108..a0f4a7465 100644
--- a/src/libstrongswan/plugins/constraints/constraints_validator.c
+++ b/src/libstrongswan/plugins/constraints/constraints_validator.c
@@ -52,16 +52,67 @@ static bool check_pathlen(x509_t *issuer, int pathlen)
}
/**
- * Check if a FQDN/RFC822 constraint matches (suffix match)
+ * Check if a FQDN constraint matches
*/
-static bool suffix_matches(identification_t *constraint, identification_t *id)
+static bool fqdn_matches(identification_t *constraint, identification_t *id)
{
- chunk_t c, i;
+ chunk_t c, i, diff;
c = constraint->get_encoding(constraint);
i = id->get_encoding(id);
- return i.len >= c.len && chunk_equals(c, chunk_skip(i, i.len - c.len));
+ if (!c.len || i.len < c.len)
+ {
+ return FALSE;
+ }
+ diff = chunk_create(i.ptr, i.len - c.len);
+ if (!chunk_equals(c, chunk_skip(i, diff.len)))
+ {
+ return FALSE;
+ }
+ if (!diff.len)
+ {
+ return TRUE;
+ }
+ if (c.ptr[0] == '.' || diff.ptr[diff.len - 1] == '.')
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * Check if a RFC822 constraint matches
+ */
+static bool email_matches(identification_t *constraint, identification_t *id)
+{
+ chunk_t c, i, diff;
+
+ c = constraint->get_encoding(constraint);
+ i = id->get_encoding(id);
+
+ if (!c.len || i.len < c.len)
+ {
+ return FALSE;
+ }
+ if (memchr(c.ptr, '@', c.len))
+ { /* constraint is a full email address */
+ return chunk_equals(c, i);
+ }
+ diff = chunk_create(i.ptr, i.len - c.len);
+ if (!diff.len || !chunk_equals(c, chunk_skip(i, diff.len)))
+ {
+ return FALSE;
+ }
+ if (c.ptr[0] == '.')
+ { /* constraint is domain, suffix match */
+ return TRUE;
+ }
+ if (diff.ptr[diff.len - 1] == '@')
+ { /* constraint is host specific, only username can be appended */
+ return TRUE;
+ }
+ return FALSE;
}
/**
@@ -121,8 +172,10 @@ static bool name_constraint_matches(identification_t *constraint,
switch (type)
{
case ID_FQDN:
+ matches = fqdn_matches(constraint, id);
+ break;
case ID_RFC822_ADDR:
- matches = suffix_matches(constraint, id);
+ matches = email_matches(constraint, id);
break;
case ID_DER_ASN1_DN:
matches = dn_matches(constraint, id);
@@ -151,7 +204,7 @@ static bool name_constraint_inherited(identification_t *constraint,
x509_t *x509, bool permitted)
{
enumerator_t *enumerator;
- identification_t *id;
+ identification_t *id, *a, *b;
bool inherited = FALSE;
id_type_t type;
@@ -166,28 +219,26 @@ static bool name_constraint_inherited(identification_t *constraint,
{
if (id->get_type(id) == type)
{
+ if (permitted)
+ { /* permitted constraint can be narrowed */
+ a = constraint;
+ b = id;
+ }
+ else
+ { /* excluded constraint can be widened */
+ a = id;
+ b = constraint;
+ }
switch (type)
{
case ID_FQDN:
+ inherited = fqdn_matches(a, b);
+ break;
case ID_RFC822_ADDR:
- if (permitted)
- { /* permitted constraint can be narrowed */
- inherited = suffix_matches(constraint, id);
- }
- else
- { /* excluded constraint can be widened */
- inherited = suffix_matches(id, constraint);
- }
+ inherited = email_matches(a, b);
break;
case ID_DER_ASN1_DN:
- if (permitted)
- {
- inherited = dn_matches(constraint, id);
- }
- else
- {
- inherited = dn_matches(id, constraint);
- }
+ inherited = dn_matches(a, b);
break;
default:
DBG1(DBG_CFG, "%N NameConstraint matching not implemented",
@@ -298,8 +349,7 @@ static bool has_policy(x509_t *issuer, chunk_t oid)
/**
* Check certificatePolicies.
*/
-static bool check_policy(x509_t *subject, x509_t *issuer, bool check,
- auth_cfg_t *auth)
+static bool check_policy(x509_t *subject, x509_t *issuer)
{
certificate_t *cert = (certificate_t*)subject;
x509_policy_mapping_t *mapping;
@@ -323,33 +373,85 @@ static bool check_policy(x509_t *subject, x509_t *issuer, bool check,
}
enumerator->destroy(enumerator);
- if (check)
+ enumerator = subject->create_cert_policy_enumerator(subject);
+ while (enumerator->enumerate(enumerator, &policy))
+ {
+ if (!has_policy(issuer, policy->oid))
+ {
+ oid = asn1_oid_to_string(policy->oid);
+ DBG1(DBG_CFG, "policy %s missing in issuing certificate '%Y'",
+ oid, cert->get_issuer(cert));
+ free(oid);
+ enumerator->destroy(enumerator);
+ return FALSE;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return TRUE;
+}
+
+/**
+ * Check if a given policy is valid under a trustchain
+ */
+static bool is_policy_valid(linked_list_t *chain, chunk_t oid)
+{
+ x509_policy_mapping_t *mapping;
+ x509_cert_policy_t *policy;
+ x509_t *issuer;
+ enumerator_t *issuers, *policies, *mappings;
+ bool found = TRUE;
+
+ issuers = chain->create_enumerator(chain);
+ while (issuers->enumerate(issuers, &issuer))
{
- enumerator = subject->create_cert_policy_enumerator(subject);
- while (enumerator->enumerate(enumerator, &policy))
+ int maxmap = 8;
+
+ while (found)
{
- if (!has_policy(issuer, policy->oid))
+ found = FALSE;
+
+ policies = issuer->create_cert_policy_enumerator(issuer);
+ while (policies->enumerate(policies, &policy))
{
- oid = asn1_oid_to_string(policy->oid);
- DBG1(DBG_CFG, "policy %s missing in issuing certificate '%Y'",
- oid, cert->get_issuer(cert));
- free(oid);
- enumerator->destroy(enumerator);
- return FALSE;
+ if (chunk_equals(oid, policy->oid) ||
+ chunk_equals(any_policy, policy->oid))
+ {
+ found = TRUE;
+ break;
+ }
}
- if (auth)
+ policies->destroy(policies);
+ if (found)
{
- oid = asn1_oid_to_string(policy->oid);
- if (oid)
+ break;
+ }
+ /* fall back to a mapped policy */
+ mappings = issuer->create_policy_mapping_enumerator(issuer);
+ while (mappings->enumerate(mappings, &mapping))
+ {
+ if (chunk_equals(mapping->subject, oid))
{
- auth->add(auth, AUTH_RULE_CERT_POLICY, oid);
+ oid = mapping->issuer;
+ found = TRUE;
+ break;
}
}
+ mappings->destroy(mappings);
+ if (--maxmap == 0)
+ {
+ found = FALSE;
+ break;
+ }
+ }
+ if (!found)
+ {
+ break;
}
- enumerator->destroy(enumerator);
}
+ issuers->destroy(issuers);
- return TRUE;
+ return found;
}
/**
@@ -364,7 +466,7 @@ static bool has_policy_chain(linked_list_t *chain, x509_t *subject, int len)
enumerator = chain->create_enumerator(chain);
while (len-- > 0 && enumerator->enumerate(enumerator, &issuer))
{
- if (!check_policy(subject, issuer, TRUE, NULL))
+ if (!check_policy(subject, issuer))
{
valid = FALSE;
break;
@@ -450,6 +552,7 @@ static bool check_policy_constraints(x509_t *issuer, u_int pathlen,
{
if (subject->get_type(subject) == CERT_X509)
{
+ x509_cert_policy_t *policy;
enumerator_t *enumerator;
linked_list_t *chain;
certificate_t *cert;
@@ -457,6 +560,7 @@ static bool check_policy_constraints(x509_t *issuer, u_int pathlen,
x509_t *x509;
int len = 0;
u_int expl, inh;
+ char *oid;
/* prepare trustchain to validate */
chain = linked_list_create();
@@ -517,6 +621,31 @@ static bool check_policy_constraints(x509_t *issuer, u_int pathlen,
}
enumerator->destroy(enumerator);
+ if (valid)
+ {
+ x509 = (x509_t*)subject;
+
+ enumerator = x509->create_cert_policy_enumerator(x509);
+ while (enumerator->enumerate(enumerator, &policy))
+ {
+ oid = asn1_oid_to_string(policy->oid);
+ if (oid)
+ {
+ if (is_policy_valid(chain, policy->oid))
+ {
+ auth->add(auth, AUTH_RULE_CERT_POLICY, oid);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "certificate policy %s for '%Y' "
+ "not allowed by trustchain, ignored",
+ oid, subject->get_subject(subject));
+ free(oid);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
chain->destroy(chain);
}
}
@@ -543,12 +672,6 @@ METHOD(cert_validator_t, validate, bool,
subject);
return FALSE;
}
- if (!check_policy((x509_t*)subject, (x509_t*)issuer, !pathlen, auth))
- {
- lib->credmgr->call_hook(lib->credmgr, CRED_HOOK_POLICY_VIOLATION,
- subject);
- return FALSE;
- }
if (anchor)
{
if (!check_policy_constraints((x509_t*)issuer, pathlen, auth))
diff --git a/src/libstrongswan/plugins/ctr/Makefile.in b/src/libstrongswan/plugins/ctr/Makefile.in
index 4b397e85d..7b7231b85 100644
--- a/src/libstrongswan/plugins/ctr/Makefile.in
+++ b/src/libstrongswan/plugins/ctr/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/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in
index 2e221c8b4..d525eac02 100644
--- a/src/libstrongswan/plugins/curl/Makefile.in
+++ b/src/libstrongswan/plugins/curl/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/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in
index 0025a2b20..96b2f6055 100644
--- a/src/libstrongswan/plugins/des/Makefile.in
+++ b/src/libstrongswan/plugins/des/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/libstrongswan/plugins/dnskey/Makefile.in b/src/libstrongswan/plugins/dnskey/Makefile.in
index 0b30923a5..910289906 100644
--- a/src/libstrongswan/plugins/dnskey/Makefile.in
+++ b/src/libstrongswan/plugins/dnskey/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/libstrongswan/plugins/files/Makefile.am b/src/libstrongswan/plugins/files/Makefile.am
new file mode 100644
index 000000000..67767495c
--- /dev/null
+++ b/src/libstrongswan/plugins/files/Makefile.am
@@ -0,0 +1,16 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = \
+ $(PLUGIN_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-files.la
+else
+plugin_LTLIBRARIES = libstrongswan-files.la
+endif
+
+libstrongswan_files_la_SOURCES = \
+ files_plugin.h files_plugin.c files_fetcher.c files_fetcher.h
+
+libstrongswan_files_la_LDFLAGS = -module -avoid-version
diff --git a/src/libstrongswan/plugins/files/Makefile.in b/src/libstrongswan/plugins/files/Makefile.in
new file mode 100644
index 000000000..31dc4a3ac
--- /dev/null
+++ b/src/libstrongswan/plugins/files/Makefile.in
@@ -0,0 +1,775 @@
+# 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/libstrongswan/plugins/files
+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_files_la_LIBADD =
+am_libstrongswan_files_la_OBJECTS = files_plugin.lo files_fetcher.lo
+libstrongswan_files_la_OBJECTS = $(am_libstrongswan_files_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_files_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_files_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_files_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_files_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_files_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_files_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
+
+AM_CFLAGS = \
+ $(PLUGIN_CFLAGS)
+
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-files.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-files.la
+libstrongswan_files_la_SOURCES = \
+ files_plugin.h files_plugin.c files_fetcher.c files_fetcher.h
+
+libstrongswan_files_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/libstrongswan/plugins/files/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/files/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-files.la: $(libstrongswan_files_la_OBJECTS) $(libstrongswan_files_la_DEPENDENCIES) $(EXTRA_libstrongswan_files_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libstrongswan_files_la_LINK) $(am_libstrongswan_files_la_rpath) $(libstrongswan_files_la_OBJECTS) $(libstrongswan_files_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_fetcher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_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/libstrongswan/plugins/files/files_fetcher.c b/src/libstrongswan/plugins/files/files_fetcher.c
new file mode 100644
index 000000000..e0b7cbdb6
--- /dev/null
+++ b/src/libstrongswan/plugins/files/files_fetcher.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 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 <errno.h>
+
+#include <library.h>
+#include <utils/debug.h>
+
+#include "files_fetcher.h"
+
+typedef struct private_files_fetcher_t private_files_fetcher_t;
+
+/**
+ * private data of a files_fetcher_t object.
+ */
+struct private_files_fetcher_t {
+
+ /**
+ * Public data
+ */
+ files_fetcher_t public;
+
+ /**
+ * Callback function
+ */
+ fetcher_callback_t cb;
+};
+
+METHOD(fetcher_t, fetch, status_t,
+ private_files_fetcher_t *this, char *uri, void *userdata)
+{
+ chunk_t *data;
+ status_t status = FAILED;
+
+ if (this->cb == fetcher_default_callback)
+ {
+ *(chunk_t*)userdata = chunk_empty;
+ }
+ if (!strpfx(uri, "file://"))
+ {
+ return NOT_SUPPORTED;
+ }
+ uri = uri + strlen("file://");
+ data = chunk_map(uri, FALSE);
+ if (!data)
+ {
+ DBG1(DBG_LIB, " opening '%s' failed: %s", uri, strerror(errno));
+ return FAILED;
+ }
+ if (this->cb(userdata, *data))
+ {
+ status = SUCCESS;
+ }
+ chunk_unmap(data);
+ return status;
+}
+
+METHOD(fetcher_t, set_option, bool,
+ private_files_fetcher_t *this, fetcher_option_t option, ...)
+{
+ bool supported = TRUE;
+ va_list args;
+
+ va_start(args, option);
+ switch (option)
+ {
+ case FETCH_CALLBACK:
+ {
+ this->cb = va_arg(args, fetcher_callback_t);
+ break;
+ }
+ default:
+ supported = FALSE;
+ break;
+ }
+ va_end(args);
+ return supported;
+}
+
+METHOD(fetcher_t, destroy, void,
+ private_files_fetcher_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+files_fetcher_t *files_fetcher_create()
+{
+ private_files_fetcher_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .fetch = _fetch,
+ .set_option = _set_option,
+ .destroy = _destroy,
+ },
+ },
+ .cb = fetcher_default_callback,
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/unit_tester/tests.h b/src/libstrongswan/plugins/files/files_fetcher.h
index 169292e9b..7fc4ec98e 100644
--- a/src/libcharon/plugins/unit_tester/tests.h
+++ b/src/libstrongswan/plugins/files/files_fetcher.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2015 Tobias Brunner
* 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 files_fetcher files_fetcher
+ * @{ @ingroup files_p
*/
-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)
+#ifndef FILES_FETCHER_H_
+#define FILES_FETCHER_H_
-/** @}*/
+typedef struct files_fetcher_t files_fetcher_t;
+
+/**
+ * Fetcher implementation loading local files
+ */
+struct files_fetcher_t {
+
+ /**
+ * Implements fetcher interface
+ */
+ fetcher_t interface;
+};
+
+/**
+ * Create a files_fetcher instance.
+ */
+files_fetcher_t *files_fetcher_create();
+
+#endif /** FILES_FETCHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/files/files_plugin.c b/src/libstrongswan/plugins/files/files_plugin.c
new file mode 100644
index 000000000..6ab735dab
--- /dev/null
+++ b/src/libstrongswan/plugins/files/files_plugin.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 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 "files_plugin.h"
+#include "files_fetcher.h"
+
+#include <library.h>
+#include <utils/debug.h>
+
+typedef struct private_files_plugin_t private_files_plugin_t;
+
+/**
+ * private data of files_plugin
+ */
+struct private_files_plugin_t {
+
+ /**
+ * public functions
+ */
+ files_plugin_t public;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_files_plugin_t *this)
+{
+ return "files";
+}
+
+METHOD(plugin_t, get_features, int,
+ private_files_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(FETCHER, files_fetcher_create),
+ PLUGIN_PROVIDE(FETCHER, "file://"),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_files_plugin_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *files_plugin_create()
+{
+ private_files_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ );
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/unit_tester/unit_tester.h b/src/libstrongswan/plugins/files/files_plugin.h
index 08784f6f4..c121b9652 100644
--- a/src/libcharon/plugins/unit_tester/unit_tester.h
+++ b/src/libstrongswan/plugins/files/files_plugin.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2015 Tobias Brunner
* 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 files_p files
+ * @ingroup plugins
+ *
+ * @defgroup files_plugin files_plugin
+ * @{ @ingroup files_p
*/
-#ifndef UNIT_TESTER_H_
-#define UNIT_TESTER_H_
+#ifndef FILES_PLUGIN_H_
+#define FILES_PLUGIN_H_
#include <plugins/plugin.h>
-typedef struct unit_tester_t unit_tester_t;
+typedef struct files_plugin_t files_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.
+ * Plugin implementing fetcher interface loading local files directly.
*/
-struct unit_tester_t {
+struct files_plugin_t {
/**
- * Implements the plugin interface.
+ * implements plugin interface
*/
plugin_t plugin;
};
-#endif /** UNIT_TESTER_H_ @}*/
+#endif /** FILES_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in
index 64ae66559..b7ca1ce97 100644
--- a/src/libstrongswan/plugins/fips_prf/Makefile.in
+++ b/src/libstrongswan/plugins/fips_prf/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/libstrongswan/plugins/fips_prf/fips_prf.c b/src/libstrongswan/plugins/fips_prf/fips_prf.c
index 23825078e..25accf996 100644
--- a/src/libstrongswan/plugins/fips_prf/fips_prf.c
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf.c
@@ -116,6 +116,12 @@ METHOD(prf_t, get_bytes, bool,
u_int8_t *xkey = this->key;
u_int8_t one[this->b];
+ if (!w)
+ {
+ /* append mode is not supported */
+ return FALSE;
+ }
+
memset(one, 0, this->b);
one[this->b - 1] = 0x01;
@@ -250,4 +256,3 @@ fips_prf_t *fips_prf_create(pseudo_random_function_t algo)
return &this->public;
}
-
diff --git a/src/libstrongswan/plugins/gcm/Makefile.in b/src/libstrongswan/plugins/gcm/Makefile.in
index 511bfc365..e125ab884 100644
--- a/src/libstrongswan/plugins/gcm/Makefile.in
+++ b/src/libstrongswan/plugins/gcm/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/libstrongswan/plugins/gcrypt/Makefile.in b/src/libstrongswan/plugins/gcrypt/Makefile.in
index 0c7d22d71..4ce7438fc 100644
--- a/src/libstrongswan/plugins/gcrypt/Makefile.in
+++ b/src/libstrongswan/plugins/gcrypt/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/libstrongswan/plugins/gcrypt/gcrypt_dh.c b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c
index f418b941d..744ec0bbf 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c
@@ -35,7 +35,7 @@ struct private_gcrypt_dh_t {
/**
* Diffie Hellman group number
*/
- u_int16_t group;
+ diffie_hellman_group_t group;
/*
* Generator value
@@ -73,12 +73,17 @@ struct private_gcrypt_dh_t {
size_t p_len;
};
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_gcrypt_dh_t *this, chunk_t value)
{
gcry_mpi_t p_min_1;
gcry_error_t err;
+ if (!diffie_hellman_verify_value(this->group, value))
+ {
+ return FALSE;
+ }
+
if (this->yb)
{
gcry_mpi_release(this->yb);
@@ -88,7 +93,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
if (err)
{
DBG1(DBG_LIB, "importing mpi yb failed: %s", gpg_strerror(err));
- return;
+ return FALSE;
}
p_min_1 = gcry_mpi_new(this->p_len * 8);
@@ -112,6 +117,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
" y < 2 || y > p - 1 ");
}
gcry_mpi_release(p_min_1);
+ return this->zz != NULL;
}
/**
@@ -132,21 +138,22 @@ static chunk_t export_mpi(gcry_mpi_t value, size_t len)
return chunk;
}
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
private_gcrypt_dh_t *this, chunk_t *value)
{
*value = export_mpi(this->ya, this->p_len);
+ return TRUE;
}
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
private_gcrypt_dh_t *this, chunk_t *secret)
{
if (!this->zz)
{
- return FAILED;
+ return FALSE;
}
*secret = export_mpi(this->zz, this->p_len);
- return SUCCESS;
+ return TRUE;
}
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in
index eab4a0047..788cb931e 100644
--- a/src/libstrongswan/plugins/gmp/Makefile.in
+++ b/src/libstrongswan/plugins/gmp/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/libstrongswan/plugins/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
index b74d35169..4fcb168fa 100644
--- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
+++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c
@@ -42,7 +42,7 @@ struct private_gmp_diffie_hellman_t {
/**
* Diffie Hellman group number.
*/
- u_int16_t group;
+ diffie_hellman_group_t group;
/*
* Generator value.
@@ -85,11 +85,16 @@ struct private_gmp_diffie_hellman_t {
bool computed;
};
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_gmp_diffie_hellman_t *this, chunk_t value)
{
mpz_t p_min_1;
+ if (!diffie_hellman_verify_value(this->group, value))
+ {
+ return FALSE;
+ }
+
mpz_init(p_min_1);
mpz_sub_ui(p_min_1, this->p, 1);
@@ -142,9 +147,10 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
" y < 2 || y > p - 1 ");
}
mpz_clear(p_min_1);
+ return this->computed;
}
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
private_gmp_diffie_hellman_t *this,chunk_t *value)
{
value->len = this->p_len;
@@ -153,22 +159,23 @@ METHOD(diffie_hellman_t, get_my_public_value, void,
{
value->len = 0;
}
+ return TRUE;
}
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
private_gmp_diffie_hellman_t *this, chunk_t *secret)
{
if (!this->computed)
{
- return FAILED;
+ return FALSE;
}
secret->len = this->p_len;
secret->ptr = mpz_export(NULL, NULL, 1, secret->len, 1, 0, this->zz);
if (secret->ptr == NULL)
{
- return FAILED;
+ return FALSE;
}
- return SUCCESS;
+ return TRUE;
}
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
@@ -245,7 +252,7 @@ static gmp_diffie_hellman_t *create_generic(diffie_hellman_group_t group,
*random.ptr &= 0x7F;
}
mpz_import(this->xa, random.len, 1, 1, 1, 0, random.ptr);
- chunk_free(&random);
+ chunk_clear(&random);
DBG2(DBG_LIB, "size of DH secret exponent: %u bits",
mpz_sizeinbase(this->xa, 2));
diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in
index bf34e4c9f..a8c39cbab 100644
--- a/src/libstrongswan/plugins/hmac/Makefile.in
+++ b/src/libstrongswan/plugins/hmac/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/libstrongswan/plugins/hmac/hmac.c b/src/libstrongswan/plugins/hmac/hmac.c
index 44cb46b4d..96a14aed9 100644
--- a/src/libstrongswan/plugins/hmac/hmac.c
+++ b/src/libstrongswan/plugins/hmac/hmac.c
@@ -103,7 +103,8 @@ METHOD(mac_t, set_key, bool,
if (key.len > this->b)
{
/* if key is too long, it will be hashed */
- if (!this->h->get_hash(this->h, key, buffer))
+ if (!this->h->reset(this->h) ||
+ !this->h->get_hash(this->h, key, buffer))
{
return FALSE;
}
diff --git a/src/libstrongswan/plugins/keychain/Makefile.in b/src/libstrongswan/plugins/keychain/Makefile.in
index 17faa569d..8f6a6f54d 100644
--- a/src/libstrongswan/plugins/keychain/Makefile.in
+++ b/src/libstrongswan/plugins/keychain/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/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in
index 332a587c9..5316323a4 100644
--- a/src/libstrongswan/plugins/ldap/Makefile.in
+++ b/src/libstrongswan/plugins/ldap/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/libstrongswan/plugins/md4/Makefile.in b/src/libstrongswan/plugins/md4/Makefile.in
index 91fe8c45f..d5f9c6c81 100644
--- a/src/libstrongswan/plugins/md4/Makefile.in
+++ b/src/libstrongswan/plugins/md4/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/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in
index ba6cb0cf6..1dd3892cd 100644
--- a/src/libstrongswan/plugins/md5/Makefile.in
+++ b/src/libstrongswan/plugins/md5/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/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in
index bca4562d6..e2fb7e720 100644
--- a/src/libstrongswan/plugins/mysql/Makefile.in
+++ b/src/libstrongswan/plugins/mysql/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/libstrongswan/plugins/nonce/Makefile.in b/src/libstrongswan/plugins/nonce/Makefile.in
index 0d15d7c2e..0b51ba5d8 100644
--- a/src/libstrongswan/plugins/nonce/Makefile.in
+++ b/src/libstrongswan/plugins/nonce/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/libstrongswan/plugins/ntru/Makefile.am b/src/libstrongswan/plugins/ntru/Makefile.am
index b959afa8e..c9fcee982 100644
--- a/src/libstrongswan/plugins/ntru/Makefile.am
+++ b/src/libstrongswan/plugins/ntru/Makefile.am
@@ -16,7 +16,6 @@ libstrongswan_ntru_la_SOURCES = \
ntru_convert.h ntru_convert.c \
ntru_drbg.h ntru_drbg.c \
ntru_ke.h ntru_ke.c \
- ntru_mgf1.h ntru_mgf1.c \
ntru_param_set.h ntru_param_set.c \
ntru_poly.h ntru_poly.c \
ntru_public_key.h ntru_public_key.c \
diff --git a/src/libstrongswan/plugins/ntru/Makefile.in b/src/libstrongswan/plugins/ntru/Makefile.in
index e57a3673e..5636692ab 100644
--- a/src/libstrongswan/plugins/ntru/Makefile.in
+++ b/src/libstrongswan/plugins/ntru/Makefile.in
@@ -129,9 +129,8 @@ am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
libstrongswan_ntru_la_LIBADD =
am_libstrongswan_ntru_la_OBJECTS = ntru_plugin.lo ntru_convert.lo \
- ntru_drbg.lo ntru_ke.lo ntru_mgf1.lo ntru_param_set.lo \
- ntru_poly.lo ntru_public_key.lo ntru_private_key.lo \
- ntru_trits.lo
+ ntru_drbg.lo ntru_ke.lo ntru_param_set.lo ntru_poly.lo \
+ ntru_public_key.lo ntru_private_key.lo ntru_trits.lo
libstrongswan_ntru_la_OBJECTS = $(am_libstrongswan_ntru_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -229,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@
@@ -289,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@
@@ -366,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@
@@ -438,7 +442,6 @@ libstrongswan_ntru_la_SOURCES = \
ntru_convert.h ntru_convert.c \
ntru_drbg.h ntru_drbg.c \
ntru_ke.h ntru_ke.c \
- ntru_mgf1.h ntru_mgf1.c \
ntru_param_set.h ntru_param_set.c \
ntru_poly.h ntru_poly.c \
ntru_public_key.h ntru_public_key.c \
@@ -539,7 +542,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_convert.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_drbg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_ke.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_mgf1.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_param_set.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_plugin.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_poly.Plo@am__quote@
diff --git a/src/libstrongswan/plugins/ntru/ntru_ke.c b/src/libstrongswan/plugins/ntru/ntru_ke.c
index abaa22336..3b5df81d9 100644
--- a/src/libstrongswan/plugins/ntru/ntru_ke.c
+++ b/src/libstrongswan/plugins/ntru/ntru_ke.c
@@ -56,7 +56,7 @@ struct private_ntru_ke_t {
/**
* Diffie Hellman group number.
*/
- u_int16_t group;
+ diffie_hellman_group_t group;
/**
* NTRU Parameter Set
@@ -106,10 +106,10 @@ struct private_ntru_ke_t {
/**
* Deterministic Random Bit Generator
*/
- ntru_drbg_t *drbg;
+ ntru_drbg_t *drbg;
};
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
private_ntru_ke_t *this, chunk_t *value)
{
*value = chunk_empty;
@@ -130,30 +130,30 @@ METHOD(diffie_hellman_t, get_my_public_value, void,
if (!this->privkey)
{
DBG1(DBG_LIB, "NTRU keypair generation failed");
- return;
+ return FALSE;
}
this->pubkey = this->privkey->get_public_key(this->privkey);
}
*value = chunk_clone(this->pubkey->get_encoding(this->pubkey));
DBG3(DBG_LIB, "NTRU public key: %B", value);
}
+ return TRUE;
}
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
private_ntru_ke_t *this, chunk_t *secret)
{
if (!this->computed || !this->shared_secret.len)
{
*secret = chunk_empty;
- return FAILED;
+ return FALSE;
}
*secret = chunk_clone(this->shared_secret);
- return SUCCESS;
+ return TRUE;
}
-
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_ntru_ke_t *this, chunk_t value)
{
if (this->privkey)
@@ -162,15 +162,15 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
if (value.len == 0)
{
DBG1(DBG_LIB, "empty NTRU ciphertext");
- return;
+ return FALSE;
}
DBG3(DBG_LIB, "NTRU ciphertext: %B", &value);
/* decrypt the shared secret */
- if (!this->privkey->decrypt(this->privkey, value, &this->shared_secret))
+ if (!this->privkey->decrypt(this->privkey, value, &this->shared_secret))
{
DBG1(DBG_LIB, "NTRU decryption of shared secret failed");
- return;
+ return FALSE;
}
this->computed = TRUE;
}
@@ -185,13 +185,13 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
pubkey = ntru_public_key_create_from_data(this->drbg, value);
if (!pubkey)
{
- return;
+ return FALSE;
}
if (pubkey->get_id(pubkey) != this->param_set->id)
{
DBG1(DBG_LIB, "received NTRU public key with wrong OUI");
pubkey->destroy(pubkey);
- return;
+ return FALSE;
}
this->pubkey = pubkey;
@@ -204,7 +204,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
{
DBG1(DBG_LIB, "generation of shared secret failed");
chunk_free(&this->shared_secret);
- return;
+ return FALSE;
}
this->computed = TRUE;
@@ -212,10 +212,11 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
if (!pubkey->encrypt(pubkey, this->shared_secret, &this->ciphertext))
{
DBG1(DBG_LIB, "NTRU encryption of shared secret failed");
- return;
+ return FALSE;
}
DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext);
}
+ return this->computed;
}
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
@@ -301,10 +302,10 @@ ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p)
drbg = ntru_drbg_create(strength, chunk_from_str("IKE NTRU-KE"), entropy);
if (!drbg)
- {
+ {
DBG1(DBG_LIB, "could not instantiate DRBG at %u bit security", strength);
entropy->destroy(entropy);
- return NULL;
+ return NULL;
}
INIT(this,
@@ -326,4 +327,3 @@ ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p)
return &this->public;
}
-
diff --git a/src/libstrongswan/plugins/ntru/ntru_poly.c b/src/libstrongswan/plugins/ntru/ntru_poly.c
index 77ab54a5c..cb11601cd 100644
--- a/src/libstrongswan/plugins/ntru/ntru_poly.c
+++ b/src/libstrongswan/plugins/ntru/ntru_poly.c
@@ -16,8 +16,8 @@
*/
#include "ntru_poly.h"
-#include "ntru_mgf1.h"
+#include <crypto/mgf1/mgf1_bitspender.h>
#include <utils/debug.h>
#include <utils/test.h>
@@ -297,22 +297,17 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed,
bool is_product_form)
{
private_ntru_poly_t *this;
- size_t hash_len, octet_count = 0, i;
- uint8_t octets[HASH_SIZE_SHA512], *used, num_left = 0, num_needed;
- uint16_t index, limit, left = 0;
int n, num_indices, index_i = 0;
- ntru_mgf1_t *mgf1;
+ uint32_t index, limit;
+ uint8_t *used;
+ mgf1_bitspender_t *bitspender;
- DBG2(DBG_LIB, "MGF1 is seeded with %u bytes", seed.len);
- mgf1 = ntru_mgf1_create(alg, seed, TRUE);
- if (!mgf1)
+ bitspender = mgf1_bitspender_create(alg, seed, TRUE);
+ if (!bitspender)
{
return NULL;
}
- i = hash_len = mgf1->get_hash_size(mgf1);
-
this = ntru_poly_create(N, q, indices_len_p, indices_len_m, is_product_form);
-
used = malloc(N);
limit = N * ((1 << c_bits) / N);
@@ -328,43 +323,12 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed,
/* generate a random candidate index with a size of c_bits */
do
{
- /* use any leftover bits first */
- index = num_left ? left << (c_bits - num_left) : 0;
-
- /* get the rest of the bits needed from new octets */
- num_needed = c_bits - num_left;
-
- while (num_needed)
+ if (!bitspender->get_bits(bitspender, c_bits, &index))
{
- if (i == hash_len)
- {
- /* get another block from MGF1 */
- if (!mgf1->get_mask(mgf1, hash_len, octets))
- {
- mgf1->destroy(mgf1);
- destroy(this);
- free(used);
- return NULL;
- }
- octet_count += hash_len;
- i = 0;
- }
- left = octets[i++];
-
- if (num_needed <= 8)
- {
- /* all bits needed to fill the index are in this octet */
- index |= left >> (8 - num_needed);
- num_left = 8 - num_needed;
- num_needed = 0;
- left &= 0xff >> (8 - num_left);
- }
- else
- {
- /* more than one octet will be needed */
- index |= left << (num_needed - 8);
- num_needed -= 8;
- }
+ bitspender->destroy(bitspender);
+ destroy(this);
+ free(used);
+ return NULL;
}
}
while (index >= limit);
@@ -380,9 +344,7 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed,
}
}
- DBG2(DBG_LIB, "MGF1 generates %u octets to derive %u indices",
- octet_count, this->num_indices);
- mgf1->destroy(mgf1);
+ bitspender->destroy(bitspender);
free(used);
return &this->public;
diff --git a/src/libstrongswan/plugins/ntru/ntru_trits.c b/src/libstrongswan/plugins/ntru/ntru_trits.c
index 1abb7671c..57b3532ef 100644
--- a/src/libstrongswan/plugins/ntru/ntru_trits.c
+++ b/src/libstrongswan/plugins/ntru/ntru_trits.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -14,9 +14,9 @@
*/
#include "ntru_trits.h"
-#include "ntru_mgf1.h"
#include "ntru_convert.h"
+#include <crypto/mgf1/mgf1_bitspender.h>
#include <utils/debug.h>
#include <utils/test.h>
@@ -70,17 +70,15 @@ METHOD(ntru_trits_t, destroy, void,
ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed)
{
private_ntru_trits_t *this;
- uint8_t octets[HASH_SIZE_SHA512], buf[5], *trits;
- size_t hash_len, octet_count = 0, trits_needed, i;
- ntru_mgf1_t *mgf1;
+ uint8_t octet, buf[5], *trits;
+ size_t trits_needed;
+ mgf1_bitspender_t *bitspender;
- DBG2(DBG_LIB, "MGF1 is seeded with %u bytes", seed.len);
- mgf1 = ntru_mgf1_create(alg, seed, TRUE);
- if (!mgf1)
+ bitspender = mgf1_bitspender_create(alg, seed, TRUE);
+ if (!bitspender)
{
return NULL;
}
- i = hash_len = mgf1->get_hash_size(mgf1);
INIT(this,
.public = {
@@ -97,21 +95,15 @@ ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed)
while (trits_needed > 0)
{
- if (i == hash_len)
+ if (!bitspender->get_byte(bitspender, &octet))
{
- /* get another block from MGF1 */
- if (!mgf1->get_mask(mgf1, hash_len, octets))
- {
- mgf1->destroy(mgf1);
- destroy(this);
- return NULL;
- }
- octet_count += hash_len;
- i = 0;
+ bitspender->destroy(bitspender);
+ destroy(this);
+ return NULL;
}
- if (octets[i] < 243) /* 243 = 3^5 */
+ if (octet < 243) /* 243 = 3^5 */
{
- ntru_octet_2_trits(octets[i], (trits_needed < 5) ? buf : trits);
+ ntru_octet_2_trits(octet, (trits_needed < 5) ? buf : trits);
if (trits_needed < 5)
{
memcpy(trits, buf, trits_needed);
@@ -120,11 +112,8 @@ ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed)
trits += 5;
trits_needed -= 5;
}
- i++;
}
- DBG2(DBG_LIB, "MGF1 generates %u octets to extract %u trits",
- octet_count, len);
- mgf1->destroy(mgf1);
+ bitspender->destroy(bitspender);
return &this->public;
}
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
index ac0db0150..a667ca47e 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.in
+++ b/src/libstrongswan/plugins/openssl/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/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c
index 07b96b320..c2478a4ed 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crypter.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c
@@ -135,7 +135,7 @@ METHOD(crypter_t, get_block_size, size_t,
METHOD(crypter_t, get_iv_size, size_t,
private_openssl_crypter_t *this)
{
- return this->cipher->block_size;
+ return this->cipher->iv_len;
}
METHOD(crypter_t, get_key_size, size_t,
diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
index ff3382473..2615d60a2 100644
--- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c
@@ -38,7 +38,7 @@ struct private_openssl_diffie_hellman_t {
/**
* Diffie Hellman group number.
*/
- u_int16_t group;
+ diffie_hellman_group_t group;
/**
* Diffie Hellman object
@@ -61,36 +61,42 @@ struct private_openssl_diffie_hellman_t {
bool computed;
};
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
private_openssl_diffie_hellman_t *this, chunk_t *value)
{
*value = chunk_alloc(DH_size(this->dh));
memset(value->ptr, 0, value->len);
BN_bn2bin(this->dh->pub_key,
value->ptr + value->len - BN_num_bytes(this->dh->pub_key));
+ return TRUE;
}
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
private_openssl_diffie_hellman_t *this, chunk_t *secret)
{
if (!this->computed)
{
- return FAILED;
+ return FALSE;
}
/* shared secret should requires a len according the DH group */
*secret = chunk_alloc(DH_size(this->dh));
memset(secret->ptr, 0, secret->len);
memcpy(secret->ptr + secret->len - this->shared_secret.len,
this->shared_secret.ptr, this->shared_secret.len);
- return SUCCESS;
+ return TRUE;
}
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_openssl_diffie_hellman_t *this, chunk_t value)
{
int len;
+ if (!diffie_hellman_verify_value(this->group, value))
+ {
+ return FALSE;
+ }
+
BN_bin2bn(value.ptr, value.len, this->pub_key);
chunk_clear(&this->shared_secret);
this->shared_secret.ptr = malloc(DH_size(this->dh));
@@ -99,10 +105,11 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
if (len < 0)
{
DBG1(DBG_LIB, "DH shared secret computation failed");
- return;
+ return FALSE;
}
this->shared_secret.len = len;
this->computed = TRUE;
+ return TRUE;
}
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
index b487d59a5..550a5432f 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
@@ -40,7 +40,7 @@ struct private_openssl_ec_diffie_hellman_t {
/**
* Diffie Hellman group number.
*/
- u_int16_t group;
+ diffie_hellman_group_t group;
/**
* EC private (public) key
@@ -216,40 +216,47 @@ error:
return ret;
}
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_openssl_ec_diffie_hellman_t *this, chunk_t value)
{
+ if (!diffie_hellman_verify_value(this->group, value))
+ {
+ return FALSE;
+ }
+
if (!chunk2ecp(this->ec_group, value, this->pub_key))
{
DBG1(DBG_LIB, "ECDH public value is malformed");
- return;
+ return FALSE;
}
chunk_clear(&this->shared_secret);
if (!compute_shared_key(this, &this->shared_secret)) {
DBG1(DBG_LIB, "ECDH shared secret computation failed");
- return;
+ return FALSE;
}
this->computed = TRUE;
+ return TRUE;
}
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
private_openssl_ec_diffie_hellman_t *this,chunk_t *value)
{
ecp2chunk(this->ec_group, EC_KEY_get0_public_key(this->key), value, FALSE);
+ return TRUE;
}
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
private_openssl_ec_diffie_hellman_t *this, chunk_t *secret)
{
if (!this->computed)
{
- return FAILED;
+ return FALSE;
}
*secret = chunk_clone(this->shared_secret);
- return SUCCESS;
+ return TRUE;
}
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in
index 4bd958784..44603afb1 100644
--- a/src/libstrongswan/plugins/padlock/Makefile.in
+++ b/src/libstrongswan/plugins/padlock/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/libstrongswan/plugins/pem/Makefile.in b/src/libstrongswan/plugins/pem/Makefile.in
index f9c5b9b52..4c982fdf5 100644
--- a/src/libstrongswan/plugins/pem/Makefile.in
+++ b/src/libstrongswan/plugins/pem/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/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c
index 62780c384..f0e508abf 100644
--- a/src/libstrongswan/plugins/pem/pem_builder.c
+++ b/src/libstrongswan/plugins/pem/pem_builder.c
@@ -365,6 +365,29 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp)
}
/**
+ * Check if a blob looks like an ASN1 SEQUENCE or SET with BER indefinite length
+ */
+static bool is_ber_indefinite_length(chunk_t blob)
+{
+ if (blob.len >= 4)
+ {
+ switch (blob.ptr[0])
+ {
+ case ASN1_SEQUENCE:
+ case ASN1_SET:
+ /* BER indefinite length uses 0x80, and is terminated with
+ * end-of-content using 0x00,0x00 */
+ return blob.ptr[1] == 0x80 &&
+ blob.ptr[blob.len - 2] == 0 &&
+ blob.ptr[blob.len - 1] == 0;
+ default:
+ break;
+ }
+ }
+ return FALSE;
+}
+
+/**
* load the credential from a blob
*/
static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
@@ -374,7 +397,7 @@ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
bool pgp = FALSE;
blob = chunk_clone(blob);
- if (!is_asn1(blob))
+ if (!is_ber_indefinite_length(blob) && !is_asn1(blob))
{
if (pem_to_bin(&blob, &pgp) != SUCCESS)
{
diff --git a/src/libstrongswan/plugins/pem/pem_encoder.c b/src/libstrongswan/plugins/pem/pem_encoder.c
index df4b77cc3..35ea3e885 100644
--- a/src/libstrongswan/plugins/pem/pem_encoder.c
+++ b/src/libstrongswan/plugins/pem/pem_encoder.c
@@ -53,6 +53,11 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding,
break;
}
}
+ if (cred_encoding_args(args, CRED_PART_BLISS_PUB_ASN1_DER,
+ &asn1, CRED_PART_END))
+ {
+ break;
+ }
return FALSE;
case PRIVKEY_PEM:
label ="RSA PRIVATE KEY";
@@ -86,6 +91,12 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding,
label ="EC PRIVATE KEY";
break;
}
+ if (cred_encoding_args(args, CRED_PART_BLISS_PRIV_ASN1_DER,
+ &asn1, CRED_PART_END))
+ {
+ label ="BLISS PRIVATE KEY";
+ break;
+ }
return FALSE;
case CERT_PEM:
if (cred_encoding_args(args, CRED_PART_X509_ASN1_DER,
diff --git a/src/libstrongswan/plugins/pem/pem_plugin.c b/src/libstrongswan/plugins/pem/pem_plugin.c
index e7edd7b89..d5bcbb617 100644
--- a/src/libstrongswan/plugins/pem/pem_plugin.c
+++ b/src/libstrongswan/plugins/pem/pem_plugin.c
@@ -60,6 +60,9 @@ METHOD(plugin_t, get_features, int,
PLUGIN_PROVIDE(PRIVKEY, KEY_DSA),
PLUGIN_DEPENDS(PRIVKEY, KEY_DSA),
PLUGIN_SDEPEND(HASHER, HASH_MD5),
+ PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_BLISS),
+ PLUGIN_DEPENDS(PRIVKEY, KEY_BLISS),
/* public key PEM decoding */
PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE),
@@ -74,6 +77,8 @@ METHOD(plugin_t, get_features, int,
PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE),
PLUGIN_PROVIDE(PUBKEY, KEY_DSA),
PLUGIN_DEPENDS(PUBKEY, KEY_DSA),
+ PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_BLISS),
/* certificate PEM decoding */
PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
diff --git a/src/libstrongswan/plugins/pgp/Makefile.in b/src/libstrongswan/plugins/pgp/Makefile.in
index 8e351c273..4d4215bfe 100644
--- a/src/libstrongswan/plugins/pgp/Makefile.in
+++ b/src/libstrongswan/plugins/pgp/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/libstrongswan/plugins/pkcs1/Makefile.in b/src/libstrongswan/plugins/pkcs1/Makefile.in
index 445bc2d24..2a708364a 100644
--- a/src/libstrongswan/plugins/pkcs1/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs1/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/libstrongswan/plugins/pkcs1/pkcs1_builder.c b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
index c6661fcda..767b3acf2 100644
--- a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
+++ b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
@@ -63,11 +63,18 @@ static public_key_t *parse_public_key(chunk_t blob)
}
else if (oid == OID_EC_PUBLICKEY)
{
- /* we need the whole subjectPublicKeyInfo for EC public keys */
+ /* Need the whole subjectPublicKeyInfo for EC public keys */
key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
KEY_ECDSA, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
goto end;
}
+ else if (oid == OID_BLISS_PUBLICKEY)
+ {
+ /* Need the whole subjectPublicKeyInfo for BLISS public keys */
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
+ KEY_BLISS, BUILD_BLOB_ASN1_DER, blob, BUILD_END);
+ goto end;
+ }
else
{
/* key type not supported */
diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.in b/src/libstrongswan/plugins/pkcs11/Makefile.in
index 34e8d0caa..de033a3fb 100644
--- a/src/libstrongswan/plugins/pkcs11/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs11/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/libstrongswan/plugins/pkcs11/pkcs11_dh.c b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c
index 36cc284bf..c0033bd8e 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c
@@ -47,7 +47,7 @@ struct private_pkcs11_dh_t {
/**
* Diffie Hellman group number.
*/
- u_int16_t group;
+ diffie_hellman_group_t group;
/**
* Handle for own private value
@@ -81,7 +81,7 @@ struct private_pkcs11_dh_t {
*
* If this succeeds the shared secret is stored in this->secret.
*/
-static void derive_secret(private_pkcs11_dh_t *this, chunk_t other)
+static bool derive_secret(private_pkcs11_dh_t *this, chunk_t other)
{
CK_OBJECT_CLASS klass = CKO_SECRET_KEY;
CK_KEY_TYPE type = CKK_GENERIC_SECRET;
@@ -102,19 +102,25 @@ static void derive_secret(private_pkcs11_dh_t *this, chunk_t other)
if (rv != CKR_OK)
{
DBG1(DBG_CFG, "C_DeriveKey() error: %N", ck_rv_names, rv);
- return;
+ return FALSE;
}
if (!this->lib->get_ck_attribute(this->lib, this->session, secret,
CKA_VALUE, &this->secret))
{
chunk_free(&this->secret);
- return;
+ return FALSE;
}
+ return TRUE;
}
-METHOD(diffie_hellman_t, set_other_public_value, void,
+METHOD(diffie_hellman_t, set_other_public_value, bool,
private_pkcs11_dh_t *this, chunk_t value)
{
+ if (!diffie_hellman_verify_value(this->group, value))
+ {
+ return FALSE;
+ }
+
switch (this->group)
{
case ECP_192_BIT:
@@ -137,7 +143,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
if (!lib->settings->get_bool(lib->settings,
"%s.ecp_x_coordinate_only", TRUE, lib->ns))
{ /* we only get the x coordinate back */
- return;
+ return FALSE;
}
value = chunk_from_thing(params);
break;
@@ -145,24 +151,25 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
default:
break;
}
- derive_secret(this, value);
+ return derive_secret(this, value);
}
-METHOD(diffie_hellman_t, get_my_public_value, void,
+METHOD(diffie_hellman_t, get_my_public_value, bool,
private_pkcs11_dh_t *this, chunk_t *value)
{
*value = chunk_clone(this->pub_key);
+ return TRUE;
}
-METHOD(diffie_hellman_t, get_shared_secret, status_t,
+METHOD(diffie_hellman_t, get_shared_secret, bool,
private_pkcs11_dh_t *this, chunk_t *secret)
{
if (!this->secret.ptr)
{
- return FAILED;
+ return FALSE;
}
*secret = chunk_clone(this->secret);
- return SUCCESS;
+ return TRUE;
}
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
@@ -443,4 +450,3 @@ pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group,
}
return NULL;
}
-
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
index 7661473b1..dc8a1f17a 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Tobias Brunner
+ * Copyright (C) 2011-2015 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2010 Martin Willi
@@ -21,6 +21,7 @@
#include <dlfcn.h>
#include <library.h>
+#include <asn1/asn1.h>
#include <utils/debug.h>
#include <threading/mutex.h>
#include <collections/linked_list.h>
@@ -641,10 +642,37 @@ static void free_attrs(object_enumerator_t *this)
}
/**
+ * CKA_EC_POINT is encodeed as ASN.1 octet string, we can't handle that and
+ * some tokens actually return them even unwrapped.
+ *
+ * Because ASN1_OCTET_STRING is 0x04 and uncompressed EC_POINTs also begin with
+ * 0x04 (compressed ones with 0x02 or 0x03) there will be an attempt to parse
+ * unwrapped uncompressed EC_POINTs. This will fail in most cases as the length
+ * will not be correct, however, there is a small chance that the key's first
+ * byte denotes the correct length. Checking the first byte of the key should
+ * further reduce the risk of false positives, though.
+ *
+ * The original memory is freed if the value is unwrapped.
+ */
+static void unwrap_ec_point(chunk_t *data)
+{
+ chunk_t wrapped, unwrapped;
+
+ wrapped = unwrapped = *data;
+ if (asn1_unwrap(&unwrapped, &unwrapped) == ASN1_OCTET_STRING &&
+ unwrapped.len && unwrapped.ptr[0] >= 0x02 && unwrapped.ptr[0] <= 0x04)
+ {
+ *data = chunk_clone(unwrapped);
+ free(wrapped.ptr);
+ }
+}
+
+/**
* Get attributes for a given object during enumeration
*/
static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
{
+ chunk_t data;
CK_RV rv;
int i;
@@ -677,6 +705,16 @@ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
DBG1(DBG_CFG, "C_GetAttributeValue() error: %N", ck_rv_names, rv);
return FALSE;
}
+ for (i = 0; i < this->count; i++)
+ {
+ if (this->attr[i].type == CKA_EC_POINT)
+ {
+ data = chunk_create(this->attr[i].pValue, this->attr[i].ulValueLen);
+ unwrap_ec_point(&data);
+ this->attr[i].pValue = data.ptr;
+ this->attr[i].ulValueLen = data.len;
+ }
+ }
return TRUE;
}
@@ -887,6 +925,10 @@ METHOD(pkcs11_library_t, get_ck_attribute, bool,
chunk_free(data);
return FALSE;
}
+ if (attr.type == CKA_EC_POINT)
+ {
+ unwrap_ec_point(data);
+ }
return TRUE;
}
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
index bb9cc7a21..bfc545972 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Tobias Brunner
+ * Copyright (C) 2011-2015 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2010 Martin Willi
@@ -23,6 +23,7 @@
#include "pkcs11_public_key.h"
#include <utils/debug.h>
+#include <asn1/asn1.h>
typedef struct private_pkcs11_private_key_t private_pkcs11_private_key_t;
@@ -288,7 +289,23 @@ METHOD(private_key_t, sign, bool,
free(buf);
return FALSE;
}
- *signature = chunk_create(buf, len);
+ switch (scheme)
+ {
+ case SIGN_ECDSA_WITH_SHA1_DER:
+ case SIGN_ECDSA_WITH_SHA256_DER:
+ case SIGN_ECDSA_WITH_SHA384_DER:
+ case SIGN_ECDSA_WITH_SHA512_DER:
+ /* return an ASN.1 encoded sequence of integers r and s */
+ len /= 2;
+ *signature = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_integer("c", chunk_create(buf, len)),
+ asn1_integer("c", chunk_create(buf+len, len)));
+ free(buf);
+ break;
+ default:
+ *signature = chunk_create(buf, len);
+ break;
+ }
return TRUE;
}
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
index 0302c0edd..6d5211657 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Tobias Brunner
+ * Copyright (C) 2011-2015 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2010 Martin Willi
@@ -135,6 +135,7 @@ static const asn1Object_t pkinfoObjects[] = {
/**
* Extract the DER encoded Parameters and ECPoint from the given DER encoded
* subjectPublicKeyInfo.
+ * Memory for ecpoint is allocated.
*/
static bool parse_ecdsa_public_key(chunk_t blob, chunk_t *ecparams,
chunk_t *ecpoint, size_t *keylen)
@@ -173,7 +174,9 @@ static bool parse_ecdsa_public_key(chunk_t blob, chunk_t *ecparams,
{ /* skip initial bit string octet defining 0 unused bits */
object = chunk_skip(object, 1);
}
- *ecpoint = object;
+ /* the correct way to encode an EC_POINT in PKCS#11 is as
+ * ASN.1 octet string */
+ *ecpoint = asn1_wrap(ASN1_OCTET_STRING, "c", object);
break;
}
}
@@ -205,7 +208,8 @@ METHOD(public_key_t, verify, bool,
CK_SESSION_HANDLE session;
CK_RV rv;
hash_algorithm_t hash_alg;
- chunk_t hash = chunk_empty;
+ chunk_t hash = chunk_empty, parse, r, s;
+ size_t len;
mechanism = pkcs11_signature_scheme_to_mech(scheme, this->type, this->k,
&hash_alg);
@@ -215,9 +219,37 @@ METHOD(public_key_t, verify, bool,
signature_scheme_names, scheme);
return FALSE;
}
- if (sig.len && sig.ptr[0] == 0)
- { /* trim leading zero byte in sig */
- sig = chunk_skip(sig, 1);
+ switch (scheme)
+ {
+ case SIGN_ECDSA_WITH_SHA1_DER:
+ case SIGN_ECDSA_WITH_SHA256_DER:
+ case SIGN_ECDSA_WITH_SHA384_DER:
+ case SIGN_ECDSA_WITH_SHA512_DER:
+ /* PKCS#11 expects the ECDSA signatures as simple concatenation of
+ * r and s, so unwrap the ASN.1 encoded sequence */
+ parse = sig;
+ if (asn1_unwrap(&parse, &parse) != ASN1_SEQUENCE ||
+ asn1_unwrap(&parse, &r) != ASN1_INTEGER ||
+ asn1_unwrap(&parse, &s) != ASN1_INTEGER)
+ {
+ return FALSE;
+ }
+ r = chunk_skip_zero(r);
+ s = chunk_skip_zero(s);
+ len = (get_keysize(this) + 7) / 8;
+ if (r.len > len || s.len > len)
+ {
+ return FALSE;
+ }
+ /* concatenate r and s (forced to the defined length) */
+ sig = chunk_alloca(2*len);
+ memset(sig.ptr, 0, sig.len);
+ memcpy(sig.ptr + (len - r.len), r.ptr, r.len);
+ memcpy(sig.ptr + len + (len - s.len), s.ptr, s.len);
+ break;
+ default:
+ sig = chunk_skip_zero(sig);
+ break;
}
rv = this->lib->f->C_OpenSession(this->slot, CKF_SERIAL_SESSION, NULL, NULL,
&session);
@@ -776,11 +808,11 @@ pkcs11_public_key_t *pkcs11_public_key_load(key_type_t type, va_list args)
if (parse_ecdsa_public_key(blob, &ecparams, &ecpoint, &keylen))
{
this = find_ecdsa_key(ecparams, ecpoint, keylen);
- if (this)
+ if (!this)
{
- return &this->public;
+ this = create_ecdsa_key(ecparams, ecpoint, keylen);
}
- this = create_ecdsa_key(ecparams, ecpoint, keylen);
+ chunk_free(&ecpoint);
if (this)
{
return &this->public;
diff --git a/src/libstrongswan/plugins/pkcs12/Makefile.in b/src/libstrongswan/plugins/pkcs12/Makefile.in
index d90cd3532..3fa0a3890 100644
--- a/src/libstrongswan/plugins/pkcs12/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs12/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/libstrongswan/plugins/pkcs7/Makefile.in b/src/libstrongswan/plugins/pkcs7/Makefile.in
index f6534f087..3266e5d5f 100644
--- a/src/libstrongswan/plugins/pkcs7/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs7/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/libstrongswan/plugins/pkcs8/Makefile.in b/src/libstrongswan/plugins/pkcs8/Makefile.in
index 0756db856..2130c9c93 100644
--- a/src/libstrongswan/plugins/pkcs8/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs8/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/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c
index 1fec1b3ea..f7ac347d2 100644
--- a/src/libstrongswan/plugins/plugin_loader.c
+++ b/src/libstrongswan/plugins/plugin_loader.c
@@ -380,7 +380,15 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name,
return NULL;
}
}
- handle = dlopen(file, RTLD_LAZY);
+ handle = dlopen(file, RTLD_LAZY
+#ifdef RTLD_NODELETE
+ /* if supported, do not unload library when unloading a plugin. It really
+ * doesn't matter in productive systems, but causes many (dependency)
+ * library reloads during unit tests. Some libraries can't handle that,
+ * GnuTLS leaks file descriptors in its library load/unload functions. */
+ | RTLD_NODELETE
+#endif
+ );
if (handle == NULL)
{
DBG1(DBG_LIB, "plugin '%s' failed to load: %s", name, dlerror());
@@ -1283,9 +1291,9 @@ METHOD(plugin_loader_t, status, void,
if (this->stats.failed)
{
- dbg(DBG_LIB, level, "unable to load %d plugin feature%s (%d due to "
- "unmet dependencies)", this->stats.failed,
- this->stats.failed == 1 ? "" : "s", this->stats.depends);
+ DBG2(DBG_LIB, "unable to load %d plugin feature%s (%d due to unmet "
+ "dependencies)", this->stats.failed,
+ this->stats.failed == 1 ? "" : "s", this->stats.depends);
}
}
}
diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in
index fcdbe9450..a9f3dd14c 100644
--- a/src/libstrongswan/plugins/pubkey/Makefile.in
+++ b/src/libstrongswan/plugins/pubkey/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/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in
index fb6c9ae43..11a13463b 100644
--- a/src/libstrongswan/plugins/random/Makefile.in
+++ b/src/libstrongswan/plugins/random/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/libstrongswan/plugins/rc2/Makefile.in b/src/libstrongswan/plugins/rc2/Makefile.in
index d84b1ba17..b81acef55 100644
--- a/src/libstrongswan/plugins/rc2/Makefile.in
+++ b/src/libstrongswan/plugins/rc2/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/libstrongswan/plugins/rdrand/Makefile.in b/src/libstrongswan/plugins/rdrand/Makefile.in
index 967e8625d..028464bf3 100644
--- a/src/libstrongswan/plugins/rdrand/Makefile.in
+++ b/src/libstrongswan/plugins/rdrand/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/libstrongswan/plugins/revocation/Makefile.in b/src/libstrongswan/plugins/revocation/Makefile.in
index 127482635..342c544d9 100644
--- a/src/libstrongswan/plugins/revocation/Makefile.in
+++ b/src/libstrongswan/plugins/revocation/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/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in
index 70a98b006..18771e4f9 100644
--- a/src/libstrongswan/plugins/sha1/Makefile.in
+++ b/src/libstrongswan/plugins/sha1/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/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in
index f7d11beb1..6aaa06b20 100644
--- a/src/libstrongswan/plugins/sha2/Makefile.in
+++ b/src/libstrongswan/plugins/sha2/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/libstrongswan/plugins/soup/Makefile.in b/src/libstrongswan/plugins/soup/Makefile.in
index ee96f08c2..02290b4a2 100644
--- a/src/libstrongswan/plugins/soup/Makefile.in
+++ b/src/libstrongswan/plugins/soup/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/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in
index b9f949bcf..3e234f1ca 100644
--- a/src/libstrongswan/plugins/sqlite/Makefile.in
+++ b/src/libstrongswan/plugins/sqlite/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/libstrongswan/plugins/sshkey/Makefile.in b/src/libstrongswan/plugins/sshkey/Makefile.in
index b66302e1a..a8d5a1020 100644
--- a/src/libstrongswan/plugins/sshkey/Makefile.in
+++ b/src/libstrongswan/plugins/sshkey/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/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in
index 8d7c667d8..8980ec46c 100644
--- a/src/libstrongswan/plugins/test_vectors/Makefile.in
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.in
@@ -243,6 +243,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@
@@ -303,10 +304,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@
@@ -380,6 +383,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/libstrongswan/plugins/unbound/Makefile.in b/src/libstrongswan/plugins/unbound/Makefile.in
index 02f4ccd8a..c84717bdc 100644
--- a/src/libstrongswan/plugins/unbound/Makefile.in
+++ b/src/libstrongswan/plugins/unbound/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/libstrongswan/plugins/winhttp/Makefile.in b/src/libstrongswan/plugins/winhttp/Makefile.in
index fb87917a2..f8db1ffac 100644
--- a/src/libstrongswan/plugins/winhttp/Makefile.in
+++ b/src/libstrongswan/plugins/winhttp/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/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in
index 23a6b3ba3..b31bfbed1 100644
--- a/src/libstrongswan/plugins/x509/Makefile.in
+++ b/src/libstrongswan/plugins/x509/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/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c
index ed58377a6..bfc200421 100644
--- a/src/libstrongswan/plugins/x509/x509_ac.c
+++ b/src/libstrongswan/plugins/x509/x509_ac.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
* Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2002-2009 Andreas Steffen
+ * Copyright (C) 2002-2014 Andreas Steffen
* Copyright (C) 2009 Martin Willi
*
* HSR Hochschule fuer Technik Rapperswil
@@ -557,7 +557,7 @@ static bool parse_certificate(private_x509_ac_t *this)
}
break;
case AC_OBJ_SIGNATURE:
- this->signature = object;
+ this->signature = chunk_skip(object, 1);
break;
default:
break;
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
index bdc8234c9..96280a033 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.c
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -1465,7 +1465,7 @@ static bool parse_certificate(private_x509_cert_t *this)
}
break;
case X509_OBJ_SIGNATURE:
- this->signature = object;
+ this->signature = chunk_skip(object, 1);
break;
default:
break;
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
index d6057c30f..4d7e7bd10 100644
--- a/src/libstrongswan/plugins/x509/x509_crl.c
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -347,7 +347,7 @@ static bool parse(private_x509_crl_t *this)
break;
}
case CRL_OBJ_SIGNATURE:
- this->signature = object;
+ this->signature = chunk_skip(object, 1);
break;
default:
break;
@@ -451,6 +451,7 @@ METHOD(certificate_t, issued_by, bool,
signature_scheme_t scheme;
bool valid;
x509_t *x509 = (x509_t*)issuer;
+ chunk_t keyid = chunk_empty;
/* check if issuer is an X.509 CA certificate */
if (issuer->get_type(issuer) != CERT_X509)
@@ -462,21 +463,16 @@ METHOD(certificate_t, issued_by, bool,
return FALSE;
}
- /* get the public key of the issuer */
- key = issuer->get_public_key(issuer);
-
/* compare keyIdentifiers if available, otherwise use DNs */
- if (this->authKeyIdentifier.ptr && key)
+ if (this->authKeyIdentifier.ptr)
{
- chunk_t fingerprint;
-
- if (!key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) ||
- !chunk_equals(fingerprint, this->authKeyIdentifier))
+ keyid = x509->get_subjectKeyIdentifier(x509);
+ if (keyid.len && !chunk_equals(keyid, this->authKeyIdentifier))
{
return FALSE;
}
}
- else
+ if (!keyid.len)
{
if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
{
@@ -484,10 +480,13 @@ METHOD(certificate_t, issued_by, bool,
}
}
- /* determine signature scheme */
scheme = signature_scheme_from_oid(this->algorithm);
-
- if (scheme == SIGN_UNKNOWN || key == NULL)
+ if (scheme == SIGN_UNKNOWN)
+ {
+ return FALSE;
+ }
+ key = issuer->get_public_key(issuer);
+ if (!key)
{
return FALSE;
}
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
index ff0f0231f..eb5b01986 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008-2009 Martin Willi
- * Copyright (C) 2007 Andreas Steffen
+ * Copyright (C) 2007-2014 Andreas Steffen
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
*
@@ -265,6 +265,10 @@ static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this,
oid = OID_ECDSA_WITH_SHA1;
scheme = SIGN_ECDSA_WITH_SHA1_DER;
break;
+ case KEY_BLISS:
+ oid = OID_BLISS_WITH_SHA512;
+ scheme = SIGN_BLISS_WITH_SHA512;
+ break;
default:
DBG1(DBG_LIB, "unable to sign OCSP request, %N signature not "
"supported", key_type_names, this->key->get_type(this->key));
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
index ad04c7dea..60133fc7f 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
@@ -1,6 +1,6 @@
/**
* Copyright (C) 2008-2009 Martin Willi
- * Copyright (C) 2007 Andreas Steffen
+ * Copyright (C) 2007-2014 Andreas Steffen
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
*
@@ -537,7 +537,7 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
parser->get_level(parser)+1, NULL);
break;
case BASIC_RESPONSE_SIGNATURE:
- this->signature = object;
+ this->signature = chunk_skip(object, 1);
break;
case BASIC_RESPONSE_CERTIFICATE:
{
diff --git a/src/libstrongswan/plugins/x509/x509_pkcs10.c b/src/libstrongswan/plugins/x509/x509_pkcs10.c
index 024b4dba5..20561f7e2 100644
--- a/src/libstrongswan/plugins/x509/x509_pkcs10.c
+++ b/src/libstrongswan/plugins/x509/x509_pkcs10.c
@@ -435,7 +435,7 @@ static bool parse_certificate_request(private_x509_pkcs10_t *this)
this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
break;
case PKCS10_SIGNATURE:
- this->signature = object;
+ this->signature = chunk_skip(object, 1);
break;
default:
break;
diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in
index ffcee547c..6c9901e6c 100644
--- a/src/libstrongswan/plugins/xcbc/Makefile.in
+++ b/src/libstrongswan/plugins/xcbc/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/libstrongswan/plugins/xcbc/xcbc.c b/src/libstrongswan/plugins/xcbc/xcbc.c
index 802c8a39f..d852a2932 100644
--- a/src/libstrongswan/plugins/xcbc/xcbc.c
+++ b/src/libstrongswan/plugins/xcbc/xcbc.c
@@ -219,6 +219,10 @@ METHOD(mac_t, set_key, bool,
{
chunk_t iv, k1, lengthened;
+ memset(this->e, 0, this->b);
+ this->remaining_bytes = 0;
+ this->zero = TRUE;
+
/* we support variable keys from RFC4434 */
if (key.len == this->b)
{
diff --git a/src/libstrongswan/processing/processor.h b/src/libstrongswan/processing/processor.h
index f96530e54..ee08870fb 100644
--- a/src/libstrongswan/processing/processor.h
+++ b/src/libstrongswan/processing/processor.h
@@ -23,6 +23,8 @@
#ifndef PROCESSOR_H_
#define PROCESSOR_H_
+#include <utils/utils.h>
+
typedef struct processor_t processor_t;
#include <stdlib.h>
diff --git a/src/libstrongswan/processing/scheduler.c b/src/libstrongswan/processing/scheduler.c
index 3f1598fc4..d90852561 100644
--- a/src/libstrongswan/processing/scheduler.c
+++ b/src/libstrongswan/processing/scheduler.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -300,16 +300,26 @@ METHOD(scheduler_t, schedule_job_ms, void,
schedule_job_tv(this, job, tv);
}
-METHOD(scheduler_t, destroy, void,
+METHOD(scheduler_t, flush, void,
private_scheduler_t *this)
{
event_t *event;
- this->condvar->destroy(this->condvar);
- this->mutex->destroy(this->mutex);
+
+ this->mutex->lock(this->mutex);
while ((event = remove_event(this)) != NULL)
{
event_destroy(event);
}
+ this->condvar->signal(this->condvar);
+ this->mutex->unlock(this->mutex);
+}
+
+METHOD(scheduler_t, destroy, void,
+ private_scheduler_t *this)
+{
+ flush(this);
+ this->condvar->destroy(this->condvar);
+ this->mutex->destroy(this->mutex);
free(this->heap);
free(this);
}
@@ -328,6 +338,7 @@ scheduler_t * scheduler_create()
.schedule_job = _schedule_job,
.schedule_job_ms = _schedule_job_ms,
.schedule_job_tv = _schedule_job_tv,
+ .flush = _flush,
.destroy = _destroy,
},
.heap_size = HEAP_SIZE_DEFAULT,
diff --git a/src/libstrongswan/processing/scheduler.h b/src/libstrongswan/processing/scheduler.h
index abbf74e2c..7f91fcc59 100644
--- a/src/libstrongswan/processing/scheduler.h
+++ b/src/libstrongswan/processing/scheduler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Tobias Brunner
+ * Copyright (C) 2009-2015 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -115,6 +115,11 @@ struct scheduler_t {
u_int (*get_job_load) (scheduler_t *this);
/**
+ * Remove all scheduled jobs.
+ */
+ void (*flush)(scheduler_t *this);
+
+ /**
* Destroys a scheduler object.
*/
void (*destroy) (scheduler_t *this);
diff --git a/src/libstrongswan/processing/watcher.c b/src/libstrongswan/processing/watcher.c
index d4de2a907..5b94208bf 100644
--- a/src/libstrongswan/processing/watcher.c
+++ b/src/libstrongswan/processing/watcher.c
@@ -24,9 +24,6 @@
#include <unistd.h>
#include <errno.h>
-#ifndef WIN32
-#include <sys/select.h>
-#endif
#include <fcntl.h>
typedef struct private_watcher_t private_watcher_t;
@@ -121,11 +118,7 @@ static void update(private_watcher_t *this)
this->pending = TRUE;
if (this->notify[1] != -1)
{
-#ifdef WIN32
- if (send(this->notify[1], buf, sizeof(buf), 0) == -1)
-#else
if (write(this->notify[1], buf, sizeof(buf)) == -1)
-#endif
{
DBG1(DBG_JOB, "notifying watcher failed: %s", strerror(errno));
}
@@ -245,23 +238,57 @@ static void activate_all(private_watcher_t *this)
}
/**
+ * Find flagged revents in a pollfd set by fd
+ */
+static int find_revents(struct pollfd *pfd, int count, int fd)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (pfd[i].fd == fd)
+ {
+ return pfd[i].revents;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Check if entry is waiting for a specific event, and if it got signaled
+ */
+static bool entry_ready(entry_t *entry, watcher_event_t event, int revents)
+{
+ if (entry->events & event)
+ {
+ switch (event)
+ {
+ case WATCHER_READ:
+ return (revents & (POLLIN | POLLHUP | POLLNVAL)) != 0;
+ case WATCHER_WRITE:
+ return (revents & (POLLOUT | POLLHUP | POLLNVAL)) != 0;
+ case WATCHER_EXCEPT:
+ return (revents & (POLLERR | POLLHUP | POLLNVAL)) != 0;
+ }
+ }
+ return FALSE;
+}
+
+/**
* Dispatching function
*/
static job_requeue_t watch(private_watcher_t *this)
{
enumerator_t *enumerator;
entry_t *entry;
- fd_set rd, wr, ex;
- int maxfd = 0, res;
+ struct pollfd *pfd;
+ int count = 0, res;
bool rebuild = FALSE;
- FD_ZERO(&rd);
- FD_ZERO(&wr);
- FD_ZERO(&ex);
-
this->mutex->lock(this->mutex);
- if (this->fds->get_count(this->fds) == 0)
+ count = this->fds->get_count(this->fds);
+ if (count == 0)
{
this->state = WATCHER_STOPPED;
this->mutex->unlock(this->mutex);
@@ -272,33 +299,34 @@ static job_requeue_t watch(private_watcher_t *this)
this->state = WATCHER_RUNNING;
}
- if (this->notify[0] != -1)
- {
- FD_SET(this->notify[0], &rd);
- maxfd = this->notify[0];
- }
+ pfd = alloca(sizeof(*pfd) * (count + 1));
+ pfd[0].fd = this->notify[0];
+ pfd[0].events = POLLIN;
+ count = 1;
enumerator = this->fds->create_enumerator(this->fds);
while (enumerator->enumerate(enumerator, &entry))
{
if (!entry->in_callback)
{
+ pfd[count].fd = entry->fd;
+ pfd[count].events = 0;
if (entry->events & WATCHER_READ)
{
DBG3(DBG_JOB, " watching %d for reading", entry->fd);
- FD_SET(entry->fd, &rd);
+ pfd[count].events |= POLLIN;
}
if (entry->events & WATCHER_WRITE)
{
DBG3(DBG_JOB, " watching %d for writing", entry->fd);
- FD_SET(entry->fd, &wr);
+ pfd[count].events |= POLLOUT;
}
if (entry->events & WATCHER_EXCEPT)
{
DBG3(DBG_JOB, " watching %d for exceptions", entry->fd);
- FD_SET(entry->fd, &ex);
+ pfd[count].events |= POLLERR;
}
- maxfd = max(maxfd, entry->fd);
+ count++;
}
}
enumerator->destroy(enumerator);
@@ -306,30 +334,27 @@ static job_requeue_t watch(private_watcher_t *this)
while (!rebuild)
{
+ int revents;
char buf[1];
bool old;
ssize_t len;
job_t *job;
- DBG2(DBG_JOB, "watcher going to select()");
+ DBG2(DBG_JOB, "watcher going to poll() %d fds", count);
thread_cleanup_push((void*)activate_all, this);
old = thread_cancelability(TRUE);
- res = select(maxfd + 1, &rd, &wr, &ex, NULL);
+ res = poll(pfd, count, -1);
thread_cancelability(old);
thread_cleanup_pop(FALSE);
if (res > 0)
{
- if (this->notify[0] != -1 && FD_ISSET(this->notify[0], &rd))
+ if (pfd[0].revents & POLLIN)
{
while (TRUE)
{
-#ifdef WIN32
- len = recv(this->notify[0], buf, sizeof(buf), 0);
-#else
len = read(this->notify[0], buf, sizeof(buf));
-#endif
if (len == -1)
{
if (errno != EAGAIN && errno != EWOULDBLOCK)
@@ -354,21 +379,25 @@ static job_requeue_t watch(private_watcher_t *this)
rebuild = TRUE;
break;
}
- if (FD_ISSET(entry->fd, &rd) && (entry->events & WATCHER_READ))
- {
- DBG2(DBG_JOB, "watched FD %d ready to read", entry->fd);
- notify(this, entry, WATCHER_READ);
- }
- if (FD_ISSET(entry->fd, &wr) && (entry->events & WATCHER_WRITE))
- {
- DBG2(DBG_JOB, "watched FD %d ready to write", entry->fd);
- notify(this, entry, WATCHER_WRITE);
- }
- if (FD_ISSET(entry->fd, &ex) && (entry->events & WATCHER_EXCEPT))
+ revents = find_revents(pfd, count, entry->fd);
+ if (entry_ready(entry, WATCHER_EXCEPT, revents))
{
DBG2(DBG_JOB, "watched FD %d has exception", entry->fd);
notify(this, entry, WATCHER_EXCEPT);
}
+ else
+ {
+ if (entry_ready(entry, WATCHER_READ, revents))
+ {
+ DBG2(DBG_JOB, "watched FD %d ready to read", entry->fd);
+ notify(this, entry, WATCHER_READ);
+ }
+ if (entry_ready(entry, WATCHER_WRITE, revents))
+ {
+ DBG2(DBG_JOB, "watched FD %d ready to write", entry->fd);
+ notify(this, entry, WATCHER_WRITE);
+ }
+ }
}
enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);
@@ -388,7 +417,7 @@ static job_requeue_t watch(private_watcher_t *this)
{
if (!this->pending && errno != EINTR)
{ /* complain only if no pending updates */
- DBG1(DBG_JOB, "watcher select() error: %s", strerror(errno));
+ DBG1(DBG_JOB, "watcher poll() error: %s", strerror(errno));
}
return JOB_REQUEUE_DIRECT;
}
diff --git a/src/libstrongswan/selectors/traffic_selector.c b/src/libstrongswan/selectors/traffic_selector.c
index 94b77467a..3b7f8c5a0 100644
--- a/src/libstrongswan/selectors/traffic_selector.c
+++ b/src/libstrongswan/selectors/traffic_selector.c
@@ -449,41 +449,9 @@ METHOD(traffic_selector_t, get_subset, traffic_selector_t*,
}
METHOD(traffic_selector_t, equals, bool,
- private_traffic_selector_t *this, traffic_selector_t *other_public)
+ private_traffic_selector_t *this, traffic_selector_t *other)
{
- private_traffic_selector_t *other;
-
- other = (private_traffic_selector_t*)other_public;
- if (this->type != other->type)
- {
- return FALSE;
- }
- if (!(this->from_port == other->from_port &&
- this->to_port == other->to_port &&
- this->protocol == other->protocol))
- {
- return FALSE;
- }
- switch (this->type)
- {
- case TS_IPV4_ADDR_RANGE:
- if (memeq(this->from4, other->from4, sizeof(this->from4)) &&
- memeq(this->to4, other->to4, sizeof(this->to4)))
- {
- return TRUE;
- }
- break;
- case TS_IPV6_ADDR_RANGE:
- if (memeq(this->from6, other->from6, sizeof(this->from6)) &&
- memeq(this->to6, other->to6, sizeof(this->to6)))
- {
- return TRUE;
- }
- break;
- default:
- break;
- }
- return FALSE;
+ return traffic_selector_cmp(&this->public, other, NULL) == 0;
}
METHOD(traffic_selector_t, get_from_address, chunk_t,
@@ -717,12 +685,96 @@ METHOD(traffic_selector_t, clone_, traffic_selector_t*,
}
}
+METHOD(traffic_selector_t, hash, u_int,
+ private_traffic_selector_t *this, u_int hash)
+{
+ return chunk_hash_inc(get_from_address(this),
+ chunk_hash_inc(get_to_address(this),
+ chunk_hash_inc(chunk_from_thing(this->from_port),
+ chunk_hash_inc(chunk_from_thing(this->to_port),
+ chunk_hash_inc(chunk_from_thing(this->protocol),
+ hash)))));
+}
+
METHOD(traffic_selector_t, destroy, void,
private_traffic_selector_t *this)
{
free(this);
}
+/**
+ * Compare two integers
+ */
+static int compare_int(int a, int b)
+{
+ return a - b;
+}
+
+/*
+ * See header
+ */
+int traffic_selector_cmp(traffic_selector_t *a_pub, traffic_selector_t *b_pub,
+ void *opts)
+{
+ private_traffic_selector_t *a, *b;
+ int res;
+
+ a = (private_traffic_selector_t*)a_pub;
+ b = (private_traffic_selector_t*)b_pub;
+
+ /* IPv4 before IPv6 */
+ res = compare_int(a->type, b->type);
+ if (res)
+ {
+ return res;
+ }
+ switch (a->type)
+ {
+ case TS_IPV4_ADDR_RANGE:
+ /* lower starting subnets first */
+ res = memcmp(a->from4, b->from4, sizeof(a->from4));
+ if (res)
+ {
+ return res;
+ }
+ /* larger subnets first */
+ res = memcmp(b->to4, a->to4, sizeof(a->to4));
+ if (res)
+ {
+ return res;
+ }
+ break;
+ case TS_IPV6_ADDR_RANGE:
+ res = memcmp(a->from6, b->from6, sizeof(a->from6));
+ if (res)
+ {
+ return res;
+ }
+ res = memcmp(b->to6, a->to6, sizeof(a->to6));
+ if (res)
+ {
+ return res;
+ }
+ break;
+ default:
+ return 1;
+ }
+ /* lower protocols first */
+ res = compare_int(a->protocol, b->protocol);
+ if (res)
+ {
+ return res;
+ }
+ /* lower starting ports first */
+ res = compare_int(a->from_port, b->from_port);
+ if (res)
+ {
+ return res;
+ }
+ /* larger port ranges first */
+ return compare_int(b->to_port, a->to_port);
+}
+
/*
* see header
*/
@@ -933,6 +985,7 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol,
.set_address = _set_address,
.to_subnet = _to_subnet,
.clone = _clone_,
+ .hash = _hash,
.destroy = _destroy,
},
.from_port = from_port,
diff --git a/src/libstrongswan/selectors/traffic_selector.h b/src/libstrongswan/selectors/traffic_selector.h
index ab6813acc..cf9a2861b 100644
--- a/src/libstrongswan/selectors/traffic_selector.h
+++ b/src/libstrongswan/selectors/traffic_selector.h
@@ -221,6 +221,14 @@ struct traffic_selector_t {
bool (*to_subnet) (traffic_selector_t *this, host_t **net, u_int8_t *mask);
/**
+ * Create a hash value for the traffic selector.
+ *
+ * @param inc optional value for incremental hashing
+ * @return calculated hash value for the traffic selector
+ */
+ u_int (*hash)(traffic_selector_t *this, u_int inc);
+
+ /**
* Destroys the ts object
*/
void (*destroy) (traffic_selector_t *this);
@@ -249,6 +257,17 @@ static inline u_int8_t traffic_selector_icmp_code(u_int16_t port)
}
/**
+ * Compare two traffic selectors, usable as sort function
+ *
+ * @param a first selector to compare
+ * @param b second selector to compare
+ * @param opts optional sort options, currently unused
+ * @return > 0 if a > b, 0 if a == b, < 0 if a < b
+ */
+int traffic_selector_cmp(traffic_selector_t *a, traffic_selector_t *b,
+ void *opts);
+
+/**
* Create a new traffic selector using human readable params.
*
* If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they
diff --git a/src/libstrongswan/settings/settings_lexer.c b/src/libstrongswan/settings/settings_lexer.c
index 76433012a..0d71a1d01 100644
--- a/src/libstrongswan/settings/settings_lexer.c
+++ b/src/libstrongswan/settings/settings_lexer.c
@@ -456,8 +456,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
yyg->yy_c_buf_p = yy_cp;
/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
-#define YY_NUM_RULES 25
-#define YY_END_OF_BUFFER 26
+#define YY_NUM_RULES 26
+#define YY_END_OF_BUFFER 27
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -465,31 +465,32 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[50] =
+static yyconst flex_int16_t yy_accept[52] =
{ 0,
- 0, 0, 0, 0, 0, 0, 26, 9, 2, 3,
+ 0, 0, 0, 0, 0, 0, 27, 9, 2, 3,
8, 1, 6, 9, 4, 5, 14, 10, 11, 12,
- 24, 16, 15, 17, 9, 2, 1, 1, 3, 9,
- 14, 13, 24, 23, 21, 22, 18, 19, 20, 1,
- 9, 9, 9, 9, 9, 0, 7, 7, 0
+ 25, 16, 15, 17, 9, 2, 1, 1, 3, 9,
+ 14, 13, 25, 24, 23, 24, 21, 22, 18, 19,
+ 20, 1, 9, 9, 9, 9, 9, 0, 7, 7,
+ 0
} ;
static yyconst flex_int32_t yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 5, 1, 6, 7, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 4, 1, 5, 6, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 7, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 8, 1, 1, 1, 1, 1, 9, 10, 11,
+ 1, 9, 1, 1, 1, 1, 1, 10, 11, 12,
- 12, 13, 1, 1, 14, 1, 1, 15, 1, 16,
- 1, 1, 1, 17, 1, 18, 19, 1, 1, 1,
- 1, 1, 20, 1, 21, 1, 1, 1, 1, 1,
+ 13, 14, 1, 1, 15, 1, 1, 16, 1, 17,
+ 1, 1, 1, 18, 1, 19, 20, 1, 1, 1,
+ 1, 1, 21, 1, 22, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -506,88 +507,92 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[22] =
+static yyconst flex_int32_t yy_meta[23] =
{ 0,
- 1, 2, 3, 4, 5, 4, 6, 7, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 8,
- 4
+ 1, 2, 3, 1, 4, 5, 4, 6, 7, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 8, 4
} ;
-static yyconst flex_int16_t yy_base[60] =
+static yyconst flex_int16_t yy_base[62] =
{ 0,
- 0, 0, 20, 40, 24, 28, 63, 0, 33, 145,
- 145, 57, 145, 43, 145, 145, 0, 145, 145, 0,
- 0, 145, 145, 53, 0, 45, 0, 55, 145, 47,
- 0, 145, 0, 145, 145, 145, 145, 145, 145, 0,
- 41, 35, 23, 18, 36, 48, 145, 51, 145, 71,
- 79, 87, 94, 102, 107, 112, 120, 128, 136
+ 0, 0, 21, 42, 26, 28, 63, 0, 31, 155,
+ 155, 59, 155, 44, 155, 155, 0, 155, 155, 0,
+ 0, 155, 155, 62, 0, 48, 0, 57, 155, 47,
+ 0, 155, 0, 155, 155, 49, 155, 155, 155, 155,
+ 155, 0, 30, 21, 28, 12, 37, 52, 155, 54,
+ 155, 81, 89, 97, 104, 112, 117, 122, 130, 138,
+ 146
} ;
-static yyconst flex_int16_t yy_def[60] =
+static yyconst flex_int16_t yy_def[62] =
{ 0,
- 49, 1, 50, 50, 51, 51, 49, 52, 49, 49,
- 49, 53, 49, 52, 49, 49, 54, 49, 49, 55,
- 56, 49, 49, 57, 52, 49, 58, 53, 49, 52,
- 54, 49, 56, 49, 49, 49, 49, 49, 49, 58,
- 52, 52, 52, 52, 52, 59, 49, 59, 0, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49
+ 51, 1, 52, 52, 53, 53, 51, 54, 51, 51,
+ 51, 55, 51, 54, 51, 51, 56, 51, 51, 57,
+ 58, 51, 51, 59, 54, 51, 60, 55, 51, 54,
+ 56, 51, 58, 51, 51, 51, 51, 51, 51, 51,
+ 51, 60, 54, 54, 54, 54, 54, 61, 51, 61,
+ 0, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51
} ;
-static yyconst flex_int16_t yy_nxt[167] =
+static yyconst flex_int16_t yy_nxt[178] =
{ 0,
- 8, 9, 10, 9, 11, 12, 13, 8, 8, 8,
- 8, 8, 8, 14, 8, 8, 8, 8, 8, 15,
- 16, 18, 18, 18, 19, 18, 22, 20, 23, 45,
- 22, 24, 23, 44, 26, 24, 26, 46, 27, 46,
- 18, 18, 18, 18, 19, 18, 26, 20, 26, 48,
- 27, 48, 48, 43, 48, 42, 41, 29, 30, 29,
- 18, 35, 49, 49, 49, 36, 49, 49, 37, 38,
- 39, 17, 17, 17, 17, 17, 17, 17, 17, 21,
- 21, 21, 21, 21, 21, 21, 21, 25, 49, 49,
- 49, 49, 49, 25, 28, 28, 28, 28, 28, 28,
-
- 28, 28, 31, 49, 49, 49, 49, 31, 49, 31,
- 32, 32, 33, 33, 49, 33, 49, 33, 49, 33,
- 34, 34, 34, 34, 34, 34, 34, 34, 40, 40,
- 49, 40, 40, 40, 40, 40, 47, 47, 47, 47,
- 47, 49, 47, 47, 7, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49
+ 8, 9, 10, 8, 9, 11, 12, 13, 8, 8,
+ 8, 8, 8, 8, 14, 8, 8, 8, 8, 8,
+ 15, 16, 18, 18, 47, 18, 19, 18, 22, 20,
+ 22, 23, 26, 23, 24, 26, 24, 27, 48, 46,
+ 45, 48, 18, 18, 18, 44, 18, 19, 18, 26,
+ 20, 35, 26, 50, 27, 50, 50, 43, 50, 29,
+ 30, 29, 51, 18, 35, 36, 51, 51, 51, 51,
+ 51, 37, 51, 51, 51, 38, 51, 51, 39, 40,
+ 41, 17, 17, 17, 17, 17, 17, 17, 17, 21,
+ 21, 21, 21, 21, 21, 21, 21, 25, 51, 51,
+
+ 51, 51, 51, 25, 28, 28, 28, 28, 28, 28,
+ 28, 28, 31, 51, 51, 51, 51, 31, 51, 31,
+ 32, 32, 33, 33, 51, 33, 51, 33, 51, 33,
+ 34, 34, 34, 34, 34, 34, 34, 34, 42, 42,
+ 51, 42, 42, 42, 42, 42, 49, 49, 49, 49,
+ 49, 51, 49, 49, 7, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51
} ;
-static yyconst flex_int16_t yy_chk[167] =
+static yyconst flex_int16_t yy_chk[178] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 3, 3, 3, 3, 3, 5, 3, 5, 44,
- 6, 5, 6, 43, 9, 6, 9, 45, 9, 45,
- 3, 4, 4, 4, 4, 4, 26, 4, 26, 46,
- 26, 46, 48, 42, 48, 41, 30, 28, 14, 12,
- 4, 24, 7, 0, 0, 24, 0, 0, 24, 24,
- 24, 50, 50, 50, 50, 50, 50, 50, 50, 51,
- 51, 51, 51, 51, 51, 51, 51, 52, 0, 0,
- 0, 0, 0, 52, 53, 53, 53, 53, 53, 53,
-
- 53, 53, 54, 0, 0, 0, 0, 54, 0, 54,
- 55, 55, 56, 56, 0, 56, 0, 56, 0, 56,
- 57, 57, 57, 57, 57, 57, 57, 57, 58, 58,
- 0, 58, 58, 58, 58, 58, 59, 59, 59, 59,
- 59, 0, 59, 59, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49
+ 1, 1, 3, 3, 46, 3, 3, 3, 5, 3,
+ 6, 5, 9, 6, 5, 9, 6, 9, 47, 45,
+ 44, 47, 3, 4, 4, 43, 4, 4, 4, 26,
+ 4, 36, 26, 48, 26, 50, 48, 30, 50, 28,
+ 14, 12, 7, 4, 24, 24, 0, 0, 0, 0,
+ 0, 24, 0, 0, 0, 24, 0, 0, 24, 24,
+ 24, 52, 52, 52, 52, 52, 52, 52, 52, 53,
+ 53, 53, 53, 53, 53, 53, 53, 54, 0, 0,
+
+ 0, 0, 0, 54, 55, 55, 55, 55, 55, 55,
+ 55, 55, 56, 0, 0, 0, 0, 56, 0, 56,
+ 57, 57, 58, 58, 0, 58, 0, 58, 0, 58,
+ 59, 59, 59, 59, 59, 59, 59, 59, 60, 60,
+ 0, 60, 60, 60, 60, 60, 61, 61, 61, 61,
+ 61, 0, 61, 61, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51
} ;
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[26] =
+static yyconst flex_int32_t yy_rule_can_match_eol[27] =
{ 0,
0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0,
- 0, 0, 0, 1, 0, 0, };
+ 0, 0, 0, 1, 0, 0, 0, };
-static yyconst flex_int16_t yy_rule_linenum[25] =
+static yyconst flex_int16_t yy_rule_linenum[26] =
{ 0,
59, 60, 61, 63, 64, 65, 67, 72, 77, 85,
105, 108, 111, 114, 120, 122, 123, 146, 147, 148,
- 149, 150, 151, 154
+ 149, 150, 151, 152, 153
} ;
/* The intent behind this definition is that it'll catch
@@ -635,7 +640,7 @@ static void include_files(parser_helper_t *ctx);
/* state used to scan quoted strings */
-#line 639 "settings/settings_lexer.c"
+#line 644 "settings/settings_lexer.c"
#define INITIAL 0
#define inc 1
@@ -947,7 +952,7 @@ YY_DECL
#line 57 "settings/settings_lexer.l"
-#line 951 "settings/settings_lexer.c"
+#line 956 "settings/settings_lexer.c"
yylval = yylval_param;
@@ -1012,13 +1017,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 50 )
+ if ( yy_current_state >= 52 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 145 );
+ while ( yy_base[yy_current_state] != 155 );
yy_find_action:
/* %% [10.0] code to find the action number goes here */
@@ -1053,13 +1058,13 @@ do_action: /* This label is used only to access EOF actions. */
{
if ( yy_act == 0 )
fprintf( stderr, "--scanner backing up\n" );
- else if ( yy_act < 25 )
+ else if ( yy_act < 26 )
fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
(long)yy_rule_linenum[yy_act], yytext );
- else if ( yy_act == 25 )
+ else if ( yy_act == 26 )
fprintf( stderr, "--accepting default rule (\"%s\")\n",
yytext );
- else if ( yy_act == 26 )
+ else if ( yy_act == 27 )
fprintf( stderr, "--(end of buffer or a NUL)\n" );
else
fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -1251,20 +1256,23 @@ case 23:
/* rule 23 can match eol */
YY_RULE_SETUP
#line 151 "settings/settings_lexer.l"
-{
- yyextra->string_add(yyextra, yytext+1);
- }
+/* merge lines that end with EOL characters */
YY_BREAK
case 24:
YY_RULE_SETUP
-#line 154 "settings/settings_lexer.l"
+#line 152 "settings/settings_lexer.l"
+yyextra->string_add(yyextra, yytext+1);
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 153 "settings/settings_lexer.l"
{
yyextra->string_add(yyextra, yytext);
}
YY_BREAK
case YY_STATE_EOF(INITIAL):
-#line 159 "settings/settings_lexer.l"
+#line 158 "settings/settings_lexer.l"
{
settings_parser_pop_buffer_state(yyscanner);
if (!settings_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER)
@@ -1273,12 +1281,12 @@ case YY_STATE_EOF(INITIAL):
}
}
YY_BREAK
-case 25:
+case 26:
YY_RULE_SETUP
-#line 167 "settings/settings_lexer.l"
+#line 166 "settings/settings_lexer.l"
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
-#line 1282 "settings/settings_lexer.c"
+#line 1290 "settings/settings_lexer.c"
case YY_END_OF_BUFFER:
{
@@ -1591,7 +1599,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 50 )
+ if ( yy_current_state >= 52 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1625,11 +1633,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 50 )
+ if ( yy_current_state >= 52 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 49);
+ yy_is_jam = (yy_current_state == 51);
return yy_is_jam ? 0 : yy_current_state;
}
@@ -2646,7 +2654,7 @@ void settings_parser_free (void * ptr , yyscan_t yyscanner)
/* %ok-for-header */
-#line 167 "settings/settings_lexer.l"
+#line 166 "settings/settings_lexer.l"
diff --git a/src/libstrongswan/settings/settings_lexer.l b/src/libstrongswan/settings/settings_lexer.l
index c6546f464..176387f1f 100644
--- a/src/libstrongswan/settings/settings_lexer.l
+++ b/src/libstrongswan/settings/settings_lexer.l
@@ -148,9 +148,8 @@ static void include_files(parser_helper_t *ctx);
\\t yyextra->string_add(yyextra, "\t");
\\b yyextra->string_add(yyextra, "\b");
\\f yyextra->string_add(yyextra, "\f");
- \\(.|\n) {
- yyextra->string_add(yyextra, yytext+1);
- }
+ \\\r?\n /* merge lines that end with EOL characters */
+ \\. yyextra->string_add(yyextra, yytext+1);
[^\\\n"]+ {
yyextra->string_add(yyextra, yytext);
}
diff --git a/src/libstrongswan/tests/Makefile.am b/src/libstrongswan/tests/Makefile.am
index 7ecba19da..8c081c673 100644
--- a/src/libstrongswan/tests/Makefile.am
+++ b/src/libstrongswan/tests/Makefile.am
@@ -29,6 +29,7 @@ tests_SOURCES = tests.h tests.c \
suites/test_enum.c \
suites/test_hashtable.c \
suites/test_identification.c \
+ suites/test_traffic_selector.c \
suites/test_threading.c \
suites/test_process.c \
suites/test_watcher.c \
@@ -40,6 +41,8 @@ tests_SOURCES = tests.h tests.c \
suites/test_array.c \
suites/test_ecdsa.c \
suites/test_rsa.c \
+ suites/test_certpolicy.c \
+ suites/test_certnames.c \
suites/test_host.c \
suites/test_hasher.c \
suites/test_crypter.c \
@@ -49,6 +52,7 @@ tests_SOURCES = tests.h tests.c \
suites/test_asn1_parser.c \
suites/test_printf.c \
suites/test_test_rng.c \
+ suites/test_mgf1.c \
suites/test_ntru.c
tests_CFLAGS = \
diff --git a/src/libstrongswan/tests/Makefile.in b/src/libstrongswan/tests/Makefile.in
index 3268b5488..97e24bdb7 100644
--- a/src/libstrongswan/tests/Makefile.in
+++ b/src/libstrongswan/tests/Makefile.in
@@ -125,6 +125,7 @@ am_tests_OBJECTS = tests-tests.$(OBJEXT) \
suites/tests-test_enum.$(OBJEXT) \
suites/tests-test_hashtable.$(OBJEXT) \
suites/tests-test_identification.$(OBJEXT) \
+ suites/tests-test_traffic_selector.$(OBJEXT) \
suites/tests-test_threading.$(OBJEXT) \
suites/tests-test_process.$(OBJEXT) \
suites/tests-test_watcher.$(OBJEXT) \
@@ -136,6 +137,8 @@ am_tests_OBJECTS = tests-tests.$(OBJEXT) \
suites/tests-test_array.$(OBJEXT) \
suites/tests-test_ecdsa.$(OBJEXT) \
suites/tests-test_rsa.$(OBJEXT) \
+ suites/tests-test_certpolicy.$(OBJEXT) \
+ suites/tests-test_certnames.$(OBJEXT) \
suites/tests-test_host.$(OBJEXT) \
suites/tests-test_hasher.$(OBJEXT) \
suites/tests-test_crypter.$(OBJEXT) \
@@ -145,6 +148,7 @@ am_tests_OBJECTS = tests-tests.$(OBJEXT) \
suites/tests-test_asn1_parser.$(OBJEXT) \
suites/tests-test_printf.$(OBJEXT) \
suites/tests-test_test_rng.$(OBJEXT) \
+ suites/tests-test_mgf1.$(OBJEXT) \
suites/tests-test_ntru.$(OBJEXT)
tests_OBJECTS = $(am_tests_OBJECTS)
tests_DEPENDENCIES = \
@@ -260,6 +264,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@
@@ -320,10 +325,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@
@@ -397,6 +404,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@
@@ -480,6 +489,7 @@ tests_SOURCES = tests.h tests.c \
suites/test_enum.c \
suites/test_hashtable.c \
suites/test_identification.c \
+ suites/test_traffic_selector.c \
suites/test_threading.c \
suites/test_process.c \
suites/test_watcher.c \
@@ -491,6 +501,8 @@ tests_SOURCES = tests.h tests.c \
suites/test_array.c \
suites/test_ecdsa.c \
suites/test_rsa.c \
+ suites/test_certpolicy.c \
+ suites/test_certnames.c \
suites/test_host.c \
suites/test_hasher.c \
suites/test_crypter.c \
@@ -500,6 +512,7 @@ tests_SOURCES = tests.h tests.c \
suites/test_asn1_parser.c \
suites/test_printf.c \
suites/test_test_rng.c \
+ suites/test_mgf1.c \
suites/test_ntru.c
tests_CFLAGS = \
@@ -603,6 +616,8 @@ suites/tests-test_hashtable.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
suites/tests-test_identification.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
+suites/tests-test_traffic_selector.$(OBJEXT): suites/$(am__dirstamp) \
+ suites/$(DEPDIR)/$(am__dirstamp)
suites/tests-test_threading.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
suites/tests-test_process.$(OBJEXT): suites/$(am__dirstamp) \
@@ -625,6 +640,10 @@ suites/tests-test_ecdsa.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
suites/tests-test_rsa.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
+suites/tests-test_certpolicy.$(OBJEXT): suites/$(am__dirstamp) \
+ suites/$(DEPDIR)/$(am__dirstamp)
+suites/tests-test_certnames.$(OBJEXT): suites/$(am__dirstamp) \
+ suites/$(DEPDIR)/$(am__dirstamp)
suites/tests-test_host.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
suites/tests-test_hasher.$(OBJEXT): suites/$(am__dirstamp) \
@@ -643,6 +662,8 @@ suites/tests-test_printf.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
suites/tests-test_test_rng.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
+suites/tests-test_mgf1.$(OBJEXT): suites/$(am__dirstamp) \
+ suites/$(DEPDIR)/$(am__dirstamp)
suites/tests-test_ntru.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
@@ -667,6 +688,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_asn1_parser.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_bio_reader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_bio_writer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_certnames.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_certpolicy.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_chunk.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_crypter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_crypto_factory.Po@am__quote@
@@ -680,6 +703,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_identification.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_linked_list.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_linked_list_enumerator.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_mgf1.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_ntru.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_pen.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_printf.Po@am__quote@
@@ -689,6 +713,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_stream.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_test_rng.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_threading.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_traffic_selector.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_utils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_vectors.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_watcher.Po@am__quote@
@@ -879,6 +904,20 @@ suites/tests-test_identification.obj: suites/test_identification.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_identification.obj `if test -f 'suites/test_identification.c'; then $(CYGPATH_W) 'suites/test_identification.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_identification.c'; fi`
+suites/tests-test_traffic_selector.o: suites/test_traffic_selector.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_traffic_selector.o -MD -MP -MF suites/$(DEPDIR)/tests-test_traffic_selector.Tpo -c -o suites/tests-test_traffic_selector.o `test -f 'suites/test_traffic_selector.c' || echo '$(srcdir)/'`suites/test_traffic_selector.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_traffic_selector.Tpo suites/$(DEPDIR)/tests-test_traffic_selector.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_traffic_selector.c' object='suites/tests-test_traffic_selector.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_traffic_selector.o `test -f 'suites/test_traffic_selector.c' || echo '$(srcdir)/'`suites/test_traffic_selector.c
+
+suites/tests-test_traffic_selector.obj: suites/test_traffic_selector.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_traffic_selector.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_traffic_selector.Tpo -c -o suites/tests-test_traffic_selector.obj `if test -f 'suites/test_traffic_selector.c'; then $(CYGPATH_W) 'suites/test_traffic_selector.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_traffic_selector.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_traffic_selector.Tpo suites/$(DEPDIR)/tests-test_traffic_selector.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_traffic_selector.c' object='suites/tests-test_traffic_selector.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_traffic_selector.obj `if test -f 'suites/test_traffic_selector.c'; then $(CYGPATH_W) 'suites/test_traffic_selector.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_traffic_selector.c'; fi`
+
suites/tests-test_threading.o: suites/test_threading.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_threading.o -MD -MP -MF suites/$(DEPDIR)/tests-test_threading.Tpo -c -o suites/tests-test_threading.o `test -f 'suites/test_threading.c' || echo '$(srcdir)/'`suites/test_threading.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_threading.Tpo suites/$(DEPDIR)/tests-test_threading.Po
@@ -1033,6 +1072,34 @@ suites/tests-test_rsa.obj: suites/test_rsa.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_rsa.obj `if test -f 'suites/test_rsa.c'; then $(CYGPATH_W) 'suites/test_rsa.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_rsa.c'; fi`
+suites/tests-test_certpolicy.o: suites/test_certpolicy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certpolicy.o -MD -MP -MF suites/$(DEPDIR)/tests-test_certpolicy.Tpo -c -o suites/tests-test_certpolicy.o `test -f 'suites/test_certpolicy.c' || echo '$(srcdir)/'`suites/test_certpolicy.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certpolicy.Tpo suites/$(DEPDIR)/tests-test_certpolicy.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_certpolicy.c' object='suites/tests-test_certpolicy.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certpolicy.o `test -f 'suites/test_certpolicy.c' || echo '$(srcdir)/'`suites/test_certpolicy.c
+
+suites/tests-test_certpolicy.obj: suites/test_certpolicy.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certpolicy.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_certpolicy.Tpo -c -o suites/tests-test_certpolicy.obj `if test -f 'suites/test_certpolicy.c'; then $(CYGPATH_W) 'suites/test_certpolicy.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certpolicy.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certpolicy.Tpo suites/$(DEPDIR)/tests-test_certpolicy.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_certpolicy.c' object='suites/tests-test_certpolicy.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certpolicy.obj `if test -f 'suites/test_certpolicy.c'; then $(CYGPATH_W) 'suites/test_certpolicy.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certpolicy.c'; fi`
+
+suites/tests-test_certnames.o: suites/test_certnames.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certnames.o -MD -MP -MF suites/$(DEPDIR)/tests-test_certnames.Tpo -c -o suites/tests-test_certnames.o `test -f 'suites/test_certnames.c' || echo '$(srcdir)/'`suites/test_certnames.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certnames.Tpo suites/$(DEPDIR)/tests-test_certnames.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_certnames.c' object='suites/tests-test_certnames.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certnames.o `test -f 'suites/test_certnames.c' || echo '$(srcdir)/'`suites/test_certnames.c
+
+suites/tests-test_certnames.obj: suites/test_certnames.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certnames.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_certnames.Tpo -c -o suites/tests-test_certnames.obj `if test -f 'suites/test_certnames.c'; then $(CYGPATH_W) 'suites/test_certnames.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certnames.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certnames.Tpo suites/$(DEPDIR)/tests-test_certnames.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_certnames.c' object='suites/tests-test_certnames.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certnames.obj `if test -f 'suites/test_certnames.c'; then $(CYGPATH_W) 'suites/test_certnames.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certnames.c'; fi`
+
suites/tests-test_host.o: suites/test_host.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_host.o -MD -MP -MF suites/$(DEPDIR)/tests-test_host.Tpo -c -o suites/tests-test_host.o `test -f 'suites/test_host.c' || echo '$(srcdir)/'`suites/test_host.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_host.Tpo suites/$(DEPDIR)/tests-test_host.Po
@@ -1159,6 +1226,20 @@ suites/tests-test_test_rng.obj: suites/test_test_rng.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_test_rng.obj `if test -f 'suites/test_test_rng.c'; then $(CYGPATH_W) 'suites/test_test_rng.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_test_rng.c'; fi`
+suites/tests-test_mgf1.o: suites/test_mgf1.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_mgf1.o -MD -MP -MF suites/$(DEPDIR)/tests-test_mgf1.Tpo -c -o suites/tests-test_mgf1.o `test -f 'suites/test_mgf1.c' || echo '$(srcdir)/'`suites/test_mgf1.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_mgf1.Tpo suites/$(DEPDIR)/tests-test_mgf1.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_mgf1.c' object='suites/tests-test_mgf1.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_mgf1.o `test -f 'suites/test_mgf1.c' || echo '$(srcdir)/'`suites/test_mgf1.c
+
+suites/tests-test_mgf1.obj: suites/test_mgf1.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_mgf1.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_mgf1.Tpo -c -o suites/tests-test_mgf1.obj `if test -f 'suites/test_mgf1.c'; then $(CYGPATH_W) 'suites/test_mgf1.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mgf1.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_mgf1.Tpo suites/$(DEPDIR)/tests-test_mgf1.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_mgf1.c' object='suites/tests-test_mgf1.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_mgf1.obj `if test -f 'suites/test_mgf1.c'; then $(CYGPATH_W) 'suites/test_mgf1.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mgf1.c'; fi`
+
suites/tests-test_ntru.o: suites/test_ntru.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_ntru.o -MD -MP -MF suites/$(DEPDIR)/tests-test_ntru.Tpo -c -o suites/tests-test_ntru.o `test -f 'suites/test_ntru.c' || echo '$(srcdir)/'`suites/test_ntru.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_ntru.Tpo suites/$(DEPDIR)/tests-test_ntru.Po
diff --git a/src/libstrongswan/tests/suites/test_certnames.c b/src/libstrongswan/tests/suites/test_certnames.c
new file mode 100644
index 000000000..e30702864
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_certnames.c
@@ -0,0 +1,398 @@
+/*
+ * 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_suite.h"
+
+#include <asn1/asn1.h>
+#include <credentials/sets/mem_cred.h>
+#include <credentials/certificates/x509.h>
+
+/**
+ * RSA private key, so we don't have to generate one
+ */
+static char keydata[] = {
+ 0x30,0x82,0x02,0x5e,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xb1,0x9b,0xd4,0x51,0x24,
+ 0xfc,0x56,0x1d,0x3d,0xfb,0xa2,0xea,0x37,0x02,0x70,0x72,0x87,0x84,0x2f,0x3b,0x2d,
+ 0x6e,0x22,0xef,0x3f,0x37,0x04,0xb2,0x6f,0xb7,0xe7,0xd8,0x58,0x05,0xde,0x34,0xbf,
+ 0x99,0xe6,0x40,0x7a,0x56,0xa7,0x73,0xf5,0x98,0xcb,0xb0,0x37,0x90,0x5e,0xd1,0x3f,
+ 0xf4,0x73,0x50,0x7f,0x53,0x8e,0xf1,0x04,0x25,0xb4,0x77,0x22,0x4e,0x8a,0x9d,0x27,
+ 0x8f,0x6f,0xaf,0x59,0xbd,0xb0,0x0f,0xf0,0xaa,0x11,0x94,0x66,0x16,0x10,0x58,0xad,
+ 0x77,0xa1,0xac,0x58,0xb4,0xd0,0x0d,0xbc,0x11,0xe0,0xc0,0xe9,0x29,0xdc,0x42,0x63,
+ 0x01,0x23,0x4f,0x28,0x41,0x6d,0x34,0x9e,0x0c,0x4a,0xc8,0x62,0x83,0xb5,0x71,0x71,
+ 0x0b,0x51,0xc0,0x4c,0x37,0xd4,0x68,0x19,0x52,0x9a,0x8b,0x02,0x03,0x01,0x00,0x01,
+ 0x02,0x81,0x81,0x00,0x82,0xca,0x33,0x16,0xb2,0x3a,0xd4,0x1b,0x62,0x9a,0x9c,0xc5,
+ 0x07,0x4f,0x57,0x89,0x2f,0x7c,0x4a,0xdf,0xb4,0x3b,0xc7,0xa4,0x11,0x14,0x2d,0xf4,
+ 0x4c,0xca,0xcc,0x03,0x88,0x06,0x82,0x34,0xab,0xe7,0xe4,0x24,0x15,0x33,0x1c,0xcb,
+ 0x0a,0xcf,0xc3,0x27,0x78,0x33,0x6b,0x6f,0x82,0x3e,0x3c,0x70,0xc9,0xe2,0xb9,0x7f,
+ 0x88,0xc3,0x4f,0x59,0xb5,0x8e,0xa3,0x81,0xd9,0x88,0x1f,0xc0,0x38,0xbc,0xc8,0x93,
+ 0x40,0x0f,0x43,0xd8,0x72,0x12,0xb4,0xcc,0x6d,0x76,0x0a,0x6f,0x01,0x05,0xa8,0x88,
+ 0xf4,0x57,0x44,0xd2,0x05,0xc4,0x77,0xf5,0xfb,0x1b,0xf3,0xb2,0x0d,0x90,0xb8,0xb4,
+ 0x63,0x62,0x70,0x2c,0xe4,0x28,0xd8,0x20,0x10,0x85,0x4a,0x5e,0x63,0xa9,0xb0,0xdd,
+ 0xba,0xd0,0x32,0x49,0x02,0x41,0x00,0xdb,0x77,0xf1,0xdd,0x1a,0x12,0xc5,0xfb,0x2b,
+ 0x5b,0xb2,0xcd,0xb6,0xd0,0x4c,0xc4,0xe5,0x93,0xd6,0xf8,0x88,0xfc,0x18,0x40,0x21,
+ 0x9c,0xf7,0x2d,0x60,0x6f,0x91,0xf5,0x73,0x3c,0xf7,0x7f,0x67,0x1d,0x5b,0xb5,0xee,
+ 0x29,0xc1,0xd4,0xc6,0xdb,0x44,0x4c,0x40,0x05,0x63,0xaa,0x71,0x95,0x18,0x14,0xa7,
+ 0x23,0x9f,0x7a,0xee,0x7f,0xb5,0xc7,0x02,0x41,0x00,0xcf,0x2c,0x24,0x50,0x65,0xf4,
+ 0x94,0x7b,0xe9,0xf3,0x13,0x77,0xea,0x27,0x3c,0x6f,0x03,0x84,0xa7,0x7d,0xa2,0x54,
+ 0x40,0x97,0x82,0x0e,0xd9,0x09,0x9f,0x4a,0xa6,0x75,0xe5,0x66,0xe4,0x9c,0x59,0xd9,
+ 0x3a,0xe6,0xf7,0xd8,0x8b,0x68,0xb0,0x21,0x52,0x31,0xb3,0x4a,0xa0,0x2c,0x41,0xd7,
+ 0x1f,0x7b,0xe2,0x0f,0x15,0xc9,0x6e,0xc0,0xe5,0x1d,0x02,0x41,0x00,0x9c,0x1a,0x61,
+ 0x9f,0x89,0xc7,0x26,0xa9,0x33,0xba,0xe2,0xa0,0x6d,0xd3,0x15,0x77,0xcb,0x6f,0xef,
+ 0xad,0x12,0x0a,0x75,0xd9,0x4f,0xcf,0x4d,0x05,0x2a,0x9d,0xd1,0x2c,0xcb,0xcd,0xe6,
+ 0xa0,0xe9,0x20,0x39,0xb6,0x5a,0xf3,0xba,0x99,0xf4,0xe3,0xcb,0x5d,0x8d,0x00,0x08,
+ 0x57,0x18,0xb9,0x1a,0xca,0xbd,0xe3,0x99,0xb1,0x1f,0xe9,0x18,0xcb,0x02,0x40,0x65,
+ 0x35,0x1b,0x48,0x6b,0x86,0x60,0x43,0x68,0xb6,0xe6,0xfb,0xdd,0xd7,0xed,0x1e,0x0e,
+ 0x89,0xef,0x88,0xe0,0x94,0x68,0x39,0x9b,0xbf,0xc5,0x27,0x7e,0x39,0xe9,0xb8,0x0e,
+ 0xa9,0x85,0x65,0x1c,0x3f,0x93,0x16,0xe2,0x5d,0x57,0x3d,0x7d,0x4d,0xc9,0xe9,0x9d,
+ 0xbd,0x07,0x22,0x97,0xc7,0x90,0x09,0xe5,0x15,0x99,0x7f,0x1e,0x2b,0xfd,0xc1,0x02,
+ 0x41,0x00,0x92,0x78,0xfe,0x04,0xa0,0x53,0xed,0x36,0x97,0xbd,0x16,0xce,0x91,0x9b,
+ 0xbe,0x1f,0x8e,0x40,0x00,0x99,0x0c,0x49,0x15,0xca,0x59,0xd3,0xe3,0xd4,0xeb,0x71,
+ 0xcf,0xda,0xd7,0xc8,0x99,0x74,0xfc,0x6b,0xe8,0xfd,0xe5,0xe0,0x49,0x61,0xcb,0xda,
+ 0xe3,0xe7,0x8b,0x72,0xb5,0x69,0x73,0x2b,0x8b,0x54,0xcb,0xd9,0x48,0x6d,0x61,0x02,
+ 0x49,0xe8,
+};
+
+/**
+ * Issue a certificate with permitted/excluded name constraints
+ */
+static certificate_t* create_cert(certificate_t *ca, char *subject, char *san,
+ x509_flag_t flags, identification_t *permitted,
+ identification_t *excluded)
+{
+ private_key_t *privkey;
+ public_key_t *pubkey;
+ certificate_t *cert;
+ identification_t *id;
+ linked_list_t *plist, *elist, *sans;
+
+ privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata),
+ BUILD_END);
+ ck_assert(privkey);
+ pubkey = privkey->get_public_key(privkey);
+ ck_assert(pubkey);
+ plist = linked_list_create();
+ if (permitted)
+ {
+ plist->insert_last(plist, permitted);
+ }
+ elist = linked_list_create();
+ if (excluded)
+ {
+ elist->insert_last(elist, excluded);
+ }
+ sans = linked_list_create();
+ if (san)
+ {
+ id = identification_create_from_string(san);
+ sans->insert_last(sans, id);
+ }
+ id = identification_create_from_string(subject);
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_SIGNING_KEY, privkey,
+ BUILD_PUBLIC_KEY, pubkey,
+ BUILD_SUBJECT, id,
+ BUILD_X509_FLAG, flags,
+ BUILD_SIGNING_CERT, ca,
+ BUILD_SUBJECT_ALTNAMES, sans,
+ BUILD_PERMITTED_NAME_CONSTRAINTS, plist,
+ BUILD_EXCLUDED_NAME_CONSTRAINTS, elist,
+ BUILD_END);
+ ck_assert(cert);
+ id->destroy(id);
+ sans->destroy_offset(sans, offsetof(identification_t, destroy));
+ plist->destroy_offset(plist, offsetof(identification_t, destroy));
+ elist->destroy_offset(elist, offsetof(identification_t, destroy));
+ privkey->destroy(privkey);
+ pubkey->destroy(pubkey);
+
+ return cert;
+}
+
+/**
+ * Check if a certificate with given subject has a valid trustchain
+ */
+static bool check_trust(identification_t *subject)
+{
+ enumerator_t *certs;
+ certificate_t *cert;
+ bool trusted;
+
+ certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY,
+ subject, FALSE);
+ trusted = certs->enumerate(certs, &cert, NULL);
+ certs->destroy(certs);
+
+ return trusted;
+}
+
+static mem_cred_t *creds;
+
+START_SETUP(setup)
+{
+ creds = mem_cred_create();
+ lib->credmgr->add_set(lib->credmgr, &creds->set);
+}
+END_SETUP
+
+START_TEARDOWN(teardown)
+{
+ lib->credmgr->remove_set(lib->credmgr, &creds->set);
+ creds->destroy(creds);
+ lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
+}
+END_TEARDOWN
+
+static struct {
+ char *constraint;
+ char *subject;
+ bool good;
+} permitted_dn[] = {
+ { "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE },
+ { "C=CH, O=strongSwan", "C=CH, O=strong", FALSE },
+ { "C=CH, O=strongSwan", "C=CH, O=strong, CN=tester", FALSE },
+ { "C=CH, O=strongSwan", "C=CH, O=another, CN=tester", FALSE },
+ { "C=CH, O=strongSwan", "C=CH, CN=tester, O=strongSwan", FALSE },
+};
+
+START_TEST(test_permitted_dn)
+{
+ certificate_t *ca, *im, *sj;
+ identification_t *id;
+
+ id = identification_create_from_string(permitted_dn[_i].constraint);
+ ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, id, NULL);
+ id = identification_create_from_string(permitted_dn[_i].constraint);
+ im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, id, NULL);
+ sj = create_cert(im, permitted_dn[_i].subject, NULL, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_trust(sj->get_subject(sj)) == permitted_dn[_i].good);
+}
+END_TEST
+
+static struct {
+ id_type_t ctype;
+ char *cdata;
+ char *subject;
+ bool good;
+} permitted_san[] = {
+ { ID_FQDN, ".strongswan.org", "test.strongswan.org", TRUE },
+ { ID_FQDN, "strongswan.org", "test.strongswan.org", TRUE },
+ { ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", TRUE },
+ { ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", FALSE },
+ { ID_FQDN, "strongswan.org", "strongswan.org.com", FALSE },
+ { ID_FQDN, ".strongswan.org", "strongswan.org", FALSE },
+ { ID_FQDN, "strongswan.org", "nostrongswan.org", FALSE },
+ { ID_FQDN, "strongswan.org", "swan.org", FALSE },
+ { ID_FQDN, "strongswan.org", "swan.org", FALSE },
+ { ID_RFC822_ADDR, "tester@strongswan.org", "tester@strongswan.org", TRUE },
+ { ID_RFC822_ADDR, "tester@strongswan.org", "atester@strongswan.org", FALSE },
+ { ID_RFC822_ADDR, "strongswan.org", "tester@strongswan.org", TRUE },
+ { ID_RFC822_ADDR, "strongswan.org", "tester@test.strongswan.org", FALSE },
+ { ID_RFC822_ADDR, ".strongswan.org", "tester@test.strongswan.org", TRUE },
+ { ID_RFC822_ADDR, ".strongswan.org", "tester@strongswan.org", FALSE },
+};
+
+START_TEST(test_permitted_san)
+{
+ certificate_t *ca, *sj;
+ identification_t *id;
+
+ id = identification_create_from_encoding(permitted_san[_i].ctype,
+ chunk_from_str(permitted_san[_i].cdata));
+ ca = create_cert(NULL, "CN=CA", NULL, X509_CA, id, NULL);
+ sj = create_cert(ca, "CN=SJ", permitted_san[_i].subject, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_trust(sj->get_subject(sj)) == permitted_san[_i].good);
+}
+END_TEST
+
+static struct {
+ char *constraint;
+ char *subject;
+ bool good;
+} excluded_dn[] = {
+ { "C=CH, O=another", "C=CH, O=strongSwan, CN=tester", TRUE },
+ { "C=CH, O=another", "C=CH, O=anot", TRUE },
+ { "C=CH, O=another", "C=CH, O=anot, CN=tester", TRUE },
+ { "C=CH, O=another", "C=CH, O=another, CN=tester", FALSE },
+ { "C=CH, O=another", "C=CH, CN=tester, O=another", TRUE },
+};
+
+START_TEST(test_excluded_dn)
+{
+ certificate_t *ca, *im, *sj;
+ identification_t *id;
+
+ id = identification_create_from_string(excluded_dn[_i].constraint);
+ ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id);
+ id = identification_create_from_string(excluded_dn[_i].constraint);
+ im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, NULL, id);
+ sj = create_cert(im, excluded_dn[_i].subject, NULL, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_trust(sj->get_subject(sj)) == excluded_dn[_i].good);
+}
+END_TEST
+
+static struct {
+ id_type_t ctype;
+ char *cdata;
+ char *subject;
+ bool good;
+} excluded_san[] = {
+ { ID_FQDN, ".strongswan.org", "test.strongswan.org", FALSE },
+ { ID_FQDN, "strongswan.org", "test.strongswan.org", FALSE },
+ { ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", FALSE },
+ { ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", TRUE },
+ { ID_FQDN, "strongswan.org", "strongswan.org.com", TRUE },
+ { ID_FQDN, ".strongswan.org", "strongswan.org", TRUE },
+ { ID_FQDN, "strongswan.org", "nostrongswan.org", TRUE },
+ { ID_FQDN, "strongswan.org", "swan.org", TRUE },
+ { ID_FQDN, "strongswan.org", "swan.org", TRUE },
+ { ID_RFC822_ADDR, "tester@strongswan.org", "tester@strongswan.org", FALSE },
+ { ID_RFC822_ADDR, "tester@strongswan.org", "atester@strongswan.org", TRUE },
+ { ID_RFC822_ADDR, "strongswan.org", "tester@strongswan.org", FALSE },
+ { ID_RFC822_ADDR, "strongswan.org", "tester@test.strongswan.org", TRUE },
+ { ID_RFC822_ADDR, ".strongswan.org", "tester@test.strongswan.org", FALSE },
+ { ID_RFC822_ADDR, ".strongswan.org", "tester@strongswan.org", TRUE },
+};
+
+START_TEST(test_excluded_san)
+{
+ certificate_t *ca, *sj;
+ identification_t *id;
+
+ id = identification_create_from_encoding(excluded_san[_i].ctype,
+ chunk_from_str(excluded_san[_i].cdata));
+ ca = create_cert(NULL, "CN=CA", NULL, X509_CA, NULL, id);
+ sj = create_cert(ca, "CN=SJ", excluded_san[_i].subject, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_trust(sj->get_subject(sj)) == excluded_san[_i].good);
+}
+END_TEST
+
+static struct {
+ char *caconst;
+ char *imconst;
+ char *subject;
+ bool good;
+} permitted_dninh[] = {
+ { "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE },
+ { "C=CH", "C=DE, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE },
+ { "C=CH, O=strongSwan", "C=CH", "C=CH", FALSE },
+};
+
+START_TEST(test_permitted_dninh)
+{
+ certificate_t *ca, *im, *sj;
+ identification_t *id;
+
+ id = identification_create_from_string(permitted_dninh[_i].caconst);
+ ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, id, NULL);
+ id = identification_create_from_string(permitted_dninh[_i].imconst);
+ im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, id, NULL);
+ sj = create_cert(im, permitted_dninh[_i].subject, NULL, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_trust(sj->get_subject(sj)) == permitted_dninh[_i].good);
+}
+END_TEST
+
+static struct {
+ char *caconst;
+ char *imconst;
+ char *subject;
+ bool good;
+} excluded_dninh[] = {
+ { "C=CH, O=strongSwan", "C=CH", "C=DE", TRUE },
+ { "C=CH, O=strongSwan", "C=DE", "C=CH", FALSE },
+ { "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE },
+};
+
+START_TEST(test_excluded_dninh)
+{
+ certificate_t *ca, *im, *sj;
+ identification_t *id;
+
+ id = identification_create_from_string(excluded_dninh[_i].caconst);
+ ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id);
+ id = identification_create_from_string(excluded_dninh[_i].imconst);
+ im = create_cert(ca, "C=DE, CN=IM", NULL, X509_CA, NULL, id);
+ sj = create_cert(im, excluded_dninh[_i].subject, NULL, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_trust(sj->get_subject(sj)) == excluded_dninh[_i].good);
+}
+END_TEST
+
+Suite *certnames_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("certnames");
+
+ tc = tcase_create("permitted DN name constraints");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_loop_test(tc, test_permitted_dn, 0, countof(permitted_dn));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("permitted subjectAltName constraints");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_loop_test(tc, test_permitted_san, 0, countof(permitted_san));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("excluded DN constraints");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_loop_test(tc, test_excluded_dn, 0, countof(excluded_dn));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("excluded subjectAltName constraints");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_loop_test(tc, test_excluded_san, 0, countof(excluded_san));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("permitted DN name constraint inherit");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_loop_test(tc, test_permitted_dninh, 0, countof(permitted_dninh));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("excluded DN name constraint inherit");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_loop_test(tc, test_excluded_dninh, 0, countof(excluded_dninh));
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/tests/suites/test_certpolicy.c b/src/libstrongswan/tests/suites/test_certpolicy.c
new file mode 100644
index 000000000..7501e1a8b
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_certpolicy.c
@@ -0,0 +1,637 @@
+/*
+ * 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_suite.h"
+
+#include <asn1/asn1.h>
+#include <credentials/sets/mem_cred.h>
+#include <credentials/certificates/x509.h>
+
+/**
+ * RSA private key, so we don't have to generate one
+ */
+static char keydata[] = {
+ 0x30,0x82,0x02,0x5e,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xb1,0x9b,0xd4,0x51,0x24,
+ 0xfc,0x56,0x1d,0x3d,0xfb,0xa2,0xea,0x37,0x02,0x70,0x72,0x87,0x84,0x2f,0x3b,0x2d,
+ 0x6e,0x22,0xef,0x3f,0x37,0x04,0xb2,0x6f,0xb7,0xe7,0xd8,0x58,0x05,0xde,0x34,0xbf,
+ 0x99,0xe6,0x40,0x7a,0x56,0xa7,0x73,0xf5,0x98,0xcb,0xb0,0x37,0x90,0x5e,0xd1,0x3f,
+ 0xf4,0x73,0x50,0x7f,0x53,0x8e,0xf1,0x04,0x25,0xb4,0x77,0x22,0x4e,0x8a,0x9d,0x27,
+ 0x8f,0x6f,0xaf,0x59,0xbd,0xb0,0x0f,0xf0,0xaa,0x11,0x94,0x66,0x16,0x10,0x58,0xad,
+ 0x77,0xa1,0xac,0x58,0xb4,0xd0,0x0d,0xbc,0x11,0xe0,0xc0,0xe9,0x29,0xdc,0x42,0x63,
+ 0x01,0x23,0x4f,0x28,0x41,0x6d,0x34,0x9e,0x0c,0x4a,0xc8,0x62,0x83,0xb5,0x71,0x71,
+ 0x0b,0x51,0xc0,0x4c,0x37,0xd4,0x68,0x19,0x52,0x9a,0x8b,0x02,0x03,0x01,0x00,0x01,
+ 0x02,0x81,0x81,0x00,0x82,0xca,0x33,0x16,0xb2,0x3a,0xd4,0x1b,0x62,0x9a,0x9c,0xc5,
+ 0x07,0x4f,0x57,0x89,0x2f,0x7c,0x4a,0xdf,0xb4,0x3b,0xc7,0xa4,0x11,0x14,0x2d,0xf4,
+ 0x4c,0xca,0xcc,0x03,0x88,0x06,0x82,0x34,0xab,0xe7,0xe4,0x24,0x15,0x33,0x1c,0xcb,
+ 0x0a,0xcf,0xc3,0x27,0x78,0x33,0x6b,0x6f,0x82,0x3e,0x3c,0x70,0xc9,0xe2,0xb9,0x7f,
+ 0x88,0xc3,0x4f,0x59,0xb5,0x8e,0xa3,0x81,0xd9,0x88,0x1f,0xc0,0x38,0xbc,0xc8,0x93,
+ 0x40,0x0f,0x43,0xd8,0x72,0x12,0xb4,0xcc,0x6d,0x76,0x0a,0x6f,0x01,0x05,0xa8,0x88,
+ 0xf4,0x57,0x44,0xd2,0x05,0xc4,0x77,0xf5,0xfb,0x1b,0xf3,0xb2,0x0d,0x90,0xb8,0xb4,
+ 0x63,0x62,0x70,0x2c,0xe4,0x28,0xd8,0x20,0x10,0x85,0x4a,0x5e,0x63,0xa9,0xb0,0xdd,
+ 0xba,0xd0,0x32,0x49,0x02,0x41,0x00,0xdb,0x77,0xf1,0xdd,0x1a,0x12,0xc5,0xfb,0x2b,
+ 0x5b,0xb2,0xcd,0xb6,0xd0,0x4c,0xc4,0xe5,0x93,0xd6,0xf8,0x88,0xfc,0x18,0x40,0x21,
+ 0x9c,0xf7,0x2d,0x60,0x6f,0x91,0xf5,0x73,0x3c,0xf7,0x7f,0x67,0x1d,0x5b,0xb5,0xee,
+ 0x29,0xc1,0xd4,0xc6,0xdb,0x44,0x4c,0x40,0x05,0x63,0xaa,0x71,0x95,0x18,0x14,0xa7,
+ 0x23,0x9f,0x7a,0xee,0x7f,0xb5,0xc7,0x02,0x41,0x00,0xcf,0x2c,0x24,0x50,0x65,0xf4,
+ 0x94,0x7b,0xe9,0xf3,0x13,0x77,0xea,0x27,0x3c,0x6f,0x03,0x84,0xa7,0x7d,0xa2,0x54,
+ 0x40,0x97,0x82,0x0e,0xd9,0x09,0x9f,0x4a,0xa6,0x75,0xe5,0x66,0xe4,0x9c,0x59,0xd9,
+ 0x3a,0xe6,0xf7,0xd8,0x8b,0x68,0xb0,0x21,0x52,0x31,0xb3,0x4a,0xa0,0x2c,0x41,0xd7,
+ 0x1f,0x7b,0xe2,0x0f,0x15,0xc9,0x6e,0xc0,0xe5,0x1d,0x02,0x41,0x00,0x9c,0x1a,0x61,
+ 0x9f,0x89,0xc7,0x26,0xa9,0x33,0xba,0xe2,0xa0,0x6d,0xd3,0x15,0x77,0xcb,0x6f,0xef,
+ 0xad,0x12,0x0a,0x75,0xd9,0x4f,0xcf,0x4d,0x05,0x2a,0x9d,0xd1,0x2c,0xcb,0xcd,0xe6,
+ 0xa0,0xe9,0x20,0x39,0xb6,0x5a,0xf3,0xba,0x99,0xf4,0xe3,0xcb,0x5d,0x8d,0x00,0x08,
+ 0x57,0x18,0xb9,0x1a,0xca,0xbd,0xe3,0x99,0xb1,0x1f,0xe9,0x18,0xcb,0x02,0x40,0x65,
+ 0x35,0x1b,0x48,0x6b,0x86,0x60,0x43,0x68,0xb6,0xe6,0xfb,0xdd,0xd7,0xed,0x1e,0x0e,
+ 0x89,0xef,0x88,0xe0,0x94,0x68,0x39,0x9b,0xbf,0xc5,0x27,0x7e,0x39,0xe9,0xb8,0x0e,
+ 0xa9,0x85,0x65,0x1c,0x3f,0x93,0x16,0xe2,0x5d,0x57,0x3d,0x7d,0x4d,0xc9,0xe9,0x9d,
+ 0xbd,0x07,0x22,0x97,0xc7,0x90,0x09,0xe5,0x15,0x99,0x7f,0x1e,0x2b,0xfd,0xc1,0x02,
+ 0x41,0x00,0x92,0x78,0xfe,0x04,0xa0,0x53,0xed,0x36,0x97,0xbd,0x16,0xce,0x91,0x9b,
+ 0xbe,0x1f,0x8e,0x40,0x00,0x99,0x0c,0x49,0x15,0xca,0x59,0xd3,0xe3,0xd4,0xeb,0x71,
+ 0xcf,0xda,0xd7,0xc8,0x99,0x74,0xfc,0x6b,0xe8,0xfd,0xe5,0xe0,0x49,0x61,0xcb,0xda,
+ 0xe3,0xe7,0x8b,0x72,0xb5,0x69,0x73,0x2b,0x8b,0x54,0xcb,0xd9,0x48,0x6d,0x61,0x02,
+ 0x49,0xe8,
+};
+
+/**
+ * Issue a certificate fr given policy, including extended flags
+ */
+static certificate_t* create_cert_ext(certificate_t *ca, char *subject,
+ char *oid, x509_flag_t flags,
+ char *map_s, char *map_i,
+ u_int require_explicit,
+ u_int inhibit_mapping,
+ u_int inhibit_any)
+{
+ private_key_t *privkey;
+ public_key_t *pubkey;
+ certificate_t *cert;
+ identification_t *id;
+ linked_list_t *policies, *maps;
+ x509_cert_policy_t policy = {};
+ x509_policy_mapping_t map = {};
+
+ privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata),
+ BUILD_END);
+ ck_assert(privkey);
+ pubkey = privkey->get_public_key(privkey);
+ ck_assert(pubkey);
+ policies = linked_list_create();
+ if (oid)
+ {
+ policy.oid = asn1_oid_from_string(oid);
+ ck_assert(policy.oid.ptr);
+ policies->insert_last(policies, &policy);
+ }
+ maps = linked_list_create();
+ if (map_s && map_i)
+ {
+ map.subject = asn1_oid_from_string(map_s);
+ ck_assert(map.subject.ptr);
+ map.issuer = asn1_oid_from_string(map_i);
+ ck_assert(map.issuer.ptr);
+ maps->insert_last(maps, &map);
+ }
+ id = identification_create_from_string(subject);
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_SIGNING_KEY, privkey,
+ BUILD_PUBLIC_KEY, pubkey,
+ BUILD_SUBJECT, id,
+ BUILD_X509_FLAG, flags,
+ BUILD_CERTIFICATE_POLICIES, policies,
+ BUILD_POLICY_MAPPINGS, maps,
+ BUILD_SIGNING_CERT, ca,
+ BUILD_POLICY_REQUIRE_EXPLICIT, require_explicit,
+ BUILD_POLICY_INHIBIT_MAPPING, inhibit_mapping,
+ BUILD_POLICY_INHIBIT_ANY, inhibit_any,
+ BUILD_END);
+ ck_assert(cert);
+ id->destroy(id);
+ policies->destroy(policies);
+ maps->destroy(maps);
+ privkey->destroy(privkey);
+ pubkey->destroy(pubkey);
+ free(policy.oid.ptr);
+ free(map.subject.ptr);
+ free(map.issuer.ptr);
+
+ return cert;
+}
+
+/**
+ * Issue a certificate with given certificate policy and flags
+ */
+static certificate_t* create_cert(certificate_t *ca, char *subject,
+ char *oid, x509_flag_t flags,
+ char *map_s, char *map_i)
+{
+ return create_cert_ext(ca, subject, oid, flags, map_s, map_i,
+ X509_NO_CONSTRAINT, X509_NO_CONSTRAINT,
+ X509_NO_CONSTRAINT);
+}
+
+/**
+ * Check if a certificate with given subject has an oid
+ */
+static bool check_oid(identification_t *subject, char *oid)
+{
+ enumerator_t *certs, *auths;
+ certificate_t *cert;
+ auth_cfg_t *auth;
+ bool found = FALSE;
+ auth_rule_t type;
+ char *current;
+
+ certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY,
+ subject, FALSE);
+ if (!certs->enumerate(certs, &cert, &auth))
+ {
+ certs->destroy(certs);
+ ck_assert_msg(FALSE, "no trusted certificate found for %Y", subject);
+ }
+ auths = auth->create_enumerator(auth);
+ while (auths->enumerate(auths, &type, &current))
+ {
+ if (type == AUTH_RULE_CERT_POLICY)
+ {
+ if (streq(current, oid))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ auths->destroy(auths);
+ certs->destroy(certs);
+
+ return found;
+}
+
+/**
+ * Check if a certificate with given subject has a valid trustchain
+ */
+static bool check_trust(identification_t *subject)
+{
+ enumerator_t *certs;
+ certificate_t *cert;
+ bool trusted;
+
+ certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY,
+ subject, FALSE);
+ trusted = certs->enumerate(certs, &cert, NULL);
+ certs->destroy(certs);
+
+ return trusted;
+}
+
+static mem_cred_t *creds;
+
+static char *anyPolicy = "2.5.29.32.0";
+static char *extended = "2.23.140.1.1";
+static char *baseline = "2.23.140.1.2";
+
+START_SETUP(setup)
+{
+ creds = mem_cred_create();
+ lib->credmgr->add_set(lib->credmgr, &creds->set);
+}
+END_SETUP
+
+START_TEARDOWN(teardown)
+{
+ lib->credmgr->remove_set(lib->credmgr, &creds->set);
+ creds->destroy(creds);
+ lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
+}
+END_TEARDOWN
+
+START_TEST(test_valid_fixed)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_valid_any1)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_valid_any2)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_missing)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", NULL, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_wrong)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(!check_oid(sj->get_subject(sj), extended));
+}
+END_TEST
+
+START_TEST(test_invalid_any1)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", NULL, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_any2)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", anyPolicy, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_badchain_wrong)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", extended, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", extended, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(!check_oid(sj->get_subject(sj), baseline));
+ ck_assert(!check_oid(sj->get_subject(sj), extended));
+}
+END_TEST
+
+START_TEST(test_badchain_gap)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", NULL, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_badchain_any)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", extended, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(!check_oid(sj->get_subject(sj), extended));
+}
+END_TEST
+
+START_TEST(test_valid_mapping)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_valid_mapping_twice)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", "2.23.140.1.3", X509_CA,
+ extended, "2.23.140.1.3");
+ im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_mapping_loop)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, baseline);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_mapping_notallowed)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_invalid_mapping_nopolicy)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL);
+ im = create_cert(ca, "CN=IM", "2.23.140.1.3", X509_CA, baseline, extended);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(!check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_inhibit_mapping_good)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert_ext(NULL, "CN=CA", extended, X509_CA, NULL, NULL,
+ X509_NO_CONSTRAINT, 1, X509_NO_CONSTRAINT);
+ im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_inhibit_mapping_bad)
+{
+ certificate_t *ca, *i1, *i2, *sj;
+
+ ca = create_cert_ext(NULL, "CN=CA", extended, X509_CA, NULL, NULL,
+ X509_NO_CONSTRAINT, 1, X509_NO_CONSTRAINT);
+ i1 = create_cert(ca, "CN=IM1", extended, X509_CA, NULL, NULL);
+ i2 = create_cert(i1, "CN=IM2", extended, X509_CA, baseline, extended);
+ sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, i1);
+ creds->add_cert(creds, FALSE, i2);
+ creds->add_cert(creds, FALSE, sj);
+
+ /* TODO: we currently reject the certificate completely, but should
+ * actually just invalidate the policy not mapped properly */
+ ck_assert(!check_trust(sj->get_subject(sj)));
+}
+END_TEST
+
+START_TEST(test_inhibit_any_good)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL,
+ X509_NO_CONSTRAINT, X509_NO_CONSTRAINT, 1);
+ im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_inhibit_any_bad)
+{
+ certificate_t *ca, *i1, *i2, *sj;
+
+ ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL,
+ X509_NO_CONSTRAINT, X509_NO_CONSTRAINT, 1);
+ i1 = create_cert(ca, "CN=IM1", anyPolicy, X509_CA, NULL, NULL);
+ i2 = create_cert(i1, "CN=IM2", anyPolicy, X509_CA, NULL, NULL);
+ sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, i1);
+ creds->add_cert(creds, FALSE, i2);
+ creds->add_cert(creds, FALSE, sj);
+
+ /* TODO: we currently reject the certificate completely, but should
+ * actually just invalidate the policy relying on inhibited anyPolicy */
+ ck_assert(!check_trust(sj->get_subject(sj)));
+}
+END_TEST
+
+START_TEST(test_require_explicit_good)
+{
+ certificate_t *ca, *im, *sj;
+
+ ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL,
+ 1, X509_NO_CONSTRAINT, X509_NO_CONSTRAINT);
+ im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL);
+ sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, im);
+ creds->add_cert(creds, FALSE, sj);
+
+ ck_assert(check_oid(sj->get_subject(sj), baseline));
+}
+END_TEST
+
+START_TEST(test_require_explicit_bad)
+{
+ certificate_t *ca, *i1, *i2, *sj;
+
+ ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL,
+ 1, X509_NO_CONSTRAINT, X509_NO_CONSTRAINT);
+ i1 = create_cert(ca, "CN=IM1", extended, X509_CA, NULL, NULL);
+ i2 = create_cert(i1, "CN=IM2", extended, X509_CA, NULL, NULL);
+ sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL);
+
+ creds->add_cert(creds, TRUE, ca);
+ creds->add_cert(creds, FALSE, i1);
+ creds->add_cert(creds, FALSE, i2);
+ creds->add_cert(creds, FALSE, sj);
+
+ /* TODO: we currently reject the certificate completely, but should
+ * actually just invalidate the policy violating requireExplicit */
+ ck_assert(!check_trust(sj->get_subject(sj)));
+}
+END_TEST
+
+Suite *certpolicy_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("certpolicy");
+
+ tc = tcase_create("policy valid");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_test(tc, test_valid_fixed);
+ tcase_add_test(tc, test_valid_any1);
+ tcase_add_test(tc, test_valid_any2);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("policy invalid");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_test(tc, test_invalid_missing);
+ tcase_add_test(tc, test_invalid_wrong);
+ tcase_add_test(tc, test_invalid_any1);
+ tcase_add_test(tc, test_invalid_any2);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("policy badchain");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_test(tc, test_badchain_wrong);
+ tcase_add_test(tc, test_badchain_gap);
+ tcase_add_test(tc, test_badchain_any);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("policy valid mapping");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_test(tc, test_valid_mapping);
+ tcase_add_test(tc, test_valid_mapping_twice);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("policy invalid mapping");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_test(tc, test_invalid_mapping_loop);
+ tcase_add_test(tc, test_invalid_mapping_notallowed);
+ tcase_add_test(tc, test_invalid_mapping_nopolicy);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("inhibit policy mapping");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_test(tc, test_inhibit_mapping_good);
+ tcase_add_test(tc, test_inhibit_mapping_bad);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("inhibit any policy");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_test(tc, test_inhibit_any_good);
+ tcase_add_test(tc, test_inhibit_any_bad);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("require explicit policy");
+ tcase_add_checked_fixture(tc, setup, teardown);
+ tcase_add_test(tc, test_require_explicit_good);
+ tcase_add_test(tc, test_require_explicit_bad);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/tests/suites/test_chunk.c b/src/libstrongswan/tests/suites/test_chunk.c
index d71e010a2..b5d23658d 100644
--- a/src/libstrongswan/tests/suites/test_chunk.c
+++ b/src/libstrongswan/tests/suites/test_chunk.c
@@ -787,6 +787,11 @@ END_TEST
* test for chunk_internet_checksum[_inc]()
*/
+static inline u_int16_t compensate_alignment(u_int16_t val)
+{
+ return ((val & 0xff) << 8) | (val >> 8);
+}
+
START_TEST(test_chunk_internet_checksum)
{
chunk_t chunk;
@@ -804,9 +809,9 @@ START_TEST(test_chunk_internet_checksum)
/* need to compensate for even/odd alignment */
sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9));
- sum = ntohs(sum);
+ sum = compensate_alignment(sum);
sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 11), sum);
- sum = ntohs(sum);
+ sum = compensate_alignment(sum);
ck_assert_int_eq(0x442e, ntohs(sum));
chunk = chunk_from_chars(0x45,0x00,0x00,0x30,0x44,0x22,0x40,0x00,0x80,0x06,
@@ -821,9 +826,9 @@ START_TEST(test_chunk_internet_checksum)
/* need to compensate for even/odd alignment */
sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9));
- sum = ntohs(sum);
+ sum = compensate_alignment(sum);
sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 10), sum);
- sum = ntohs(sum);
+ sum = compensate_alignment(sum);
ck_assert_int_eq(0x4459, ntohs(sum));
}
END_TEST
diff --git a/src/libstrongswan/tests/suites/test_enum.c b/src/libstrongswan/tests/suites/test_enum.c
index b48b51c0e..53ebd2931 100644
--- a/src/libstrongswan/tests/suites/test_enum.c
+++ b/src/libstrongswan/tests/suites/test_enum.c
@@ -58,6 +58,39 @@ ENUM_NEXT(test_enum_split_names, SPLIT5, SPLIT5, SPLIT4,
ENUM_END(test_enum_split_names, SPLIT5);
/*******************************************************************************
+ * enum flags
+ */
+enum {
+ FLAG1 = (1 << 0),
+ FLAG2 = (1 << 1),
+ FLAG3 = (1 << 2),
+ FLAG4 = (1 << 3),
+ FLAG5 = (1 << 4),
+ FLAG6 = (1 << 5),
+ FLAG7 = (1 << 6),
+ FLAG8 = (1 << 7),
+ FLAG9 = (1 << 8),
+ FLAG10 = (1 << 9),
+ FLAG11 = (1 << 10),
+ FLAG12 = (1 << 11),
+} test_enum_flags;
+
+ENUM_FLAGS(test_enum_flags_names, FLAG1, FLAG5,
+ "FLAG1", "FLAG2", "FLAG3", "FLAG4", "FLAG5");
+
+ENUM_FLAGS(test_enum_flags_incomplete_names, FLAG3, FLAG4,
+ "FLAG3", "FLAG4");
+
+ENUM_FLAGS(test_enum_flags_null_names, FLAG1, FLAG4,
+ "FLAG1", NULL, "FLAG3", NULL);
+
+ENUM_FLAGS(test_enum_flags_overflow_names, FLAG1, FLAG12,
+ "OVERFLOWFLAGLONGNAME1", "OVERFLOWFLAGLONGNAME2", "OVERFLOWFLAGLONGNAME3",
+ "OVERFLOWFLAGLONGNAME4", "OVERFLOWFLAGLONGNAME5", "OVERFLOWFLAGLONGNAME6",
+ "OVERFLOWFLAGLONGNAME7", "OVERFLOWFLAGLONGNAME8", "OVERFLOWFLAGLONGNAME9",
+ "OVERFLOWFLAGLONGNAME10", "OVERFLOWFLAGLONGNAME11", "OVERFLOWFLAGLONGNAME12");
+
+/*******************************************************************************
* enum_to_name
*/
@@ -198,11 +231,52 @@ static struct {
{256, "(256)"},
};
+/*******************************************************************************
+ * flag_to_name
+ */
+
+static struct {
+ int val;
+ char *str;
+} printf_tests_flags[] = {
+ {0, "(unset)"},
+ {FLAG1, "FLAG1"},
+ {FLAG2, "FLAG2"},
+ {FLAG3, "FLAG3"},
+ {FLAG4, "FLAG4"},
+ {FLAG5, "FLAG5"},
+ {FLAG1 | FLAG3, "FLAG1 | FLAG3"},
+ {FLAG1 | FLAG3 | 32, "FLAG1 | FLAG3 | (0x20)"},
+ {FLAG1 | FLAG3 | 32 | 64, "FLAG1 | FLAG3 | (0x20) | (0x40)"},
+ {0x20, "(0x20)"},
+ {0x80000000, "(0x80000000)"},
+ {0xFFFFF, "FLAG1 | FLAG2 | FLAG3 | FLAG4 | "
+ "FLAG5 | (0x20) | (0x40) | (0x80) | "
+ "(0x100) | (0x200) | (0x400) | (0x800) | "
+ "(0x1000) | (0x2000) | (0x4000) | (0x8000) | "
+ "(0x10000) | (0x20000) | (0x40000) | (0x80000)"},
+}, printf_tests_flags_incomplete[] = {
+ {FLAG1, "(0x1)"},
+ {FLAG1 | FLAG2 | FLAG3, "(0x1) | (0x2) | FLAG3"},
+ {FLAG3 | FLAG4 | FLAG5, "FLAG3 | FLAG4 | (0x10)"},
+}, printf_tests_flags_null[] = {
+ {FLAG1 | FLAG2 | FLAG3 | FLAG4, "FLAG1 | FLAG3"},
+}, printf_tests_flags_overflow[] = {
+ {0xFFFFFFFF, "(0xFFFFFFFF)"},
+}, printf_tests_flags_noflagenum[] = {
+ {-1, "(-1)"},
+ {6435, "(6435)"},
+}, enum_flags_to_string_tests[] = {
+ {-1, NULL},
+ {6435, NULL},
+};
+
START_TEST(test_enum_printf_hook_cont)
{
char buf[128];
- snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, printf_tests_cont[_i].val);
+ snprintf(buf, sizeof(buf), "%N",
+ test_enum_cont_names, printf_tests_cont[_i].val);
ck_assert_str_eq(printf_tests_cont[_i].str, buf);
}
END_TEST
@@ -211,11 +285,89 @@ START_TEST(test_enum_printf_hook_split)
{
char buf[128];
- snprintf(buf, sizeof(buf), "%N", test_enum_split_names, printf_tests_split[_i].val);
+ snprintf(buf, sizeof(buf), "%N",
+ test_enum_split_names, printf_tests_split[_i].val);
ck_assert_str_eq(printf_tests_split[_i].str, buf);
}
END_TEST
+START_TEST(test_enum_printf_hook_flags)
+{
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "%N", test_enum_flags_names,
+ printf_tests_flags[_i].val);
+ ck_assert_str_eq(printf_tests_flags[_i].str, buf);
+}
+END_TEST
+
+START_TEST(test_enum_printf_hook_flags_incomplete)
+{
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "%N", test_enum_flags_incomplete_names,
+ printf_tests_flags_incomplete[_i].val);
+ ck_assert_str_eq(printf_tests_flags_incomplete[_i].str, buf);
+}
+END_TEST
+
+START_TEST(test_enum_printf_hook_flags_null)
+{
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "%N", test_enum_flags_null_names,
+ printf_tests_flags_null[_i].val);
+ ck_assert_str_eq(printf_tests_flags_null[_i].str, buf);
+}
+END_TEST
+
+START_TEST(test_enum_printf_hook_flags_overflow)
+{
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "%N", test_enum_flags_overflow_names,
+ printf_tests_flags_overflow[_i].val);
+ ck_assert_str_eq(printf_tests_flags_overflow[_i].str, buf);
+}
+END_TEST
+
+START_TEST(test_enum_printf_hook_flags_noflagenum)
+{
+ char buf[1024];
+
+ snprintf(buf, sizeof(buf), "%N", test_enum_cont_names,
+ printf_tests_flags_noflagenum[_i].val);
+ ck_assert_str_eq(printf_tests_flags_noflagenum[_i].str, buf);
+}
+END_TEST
+
+START_TEST(test_enum_flags_to_string)
+{
+ char buf[1], *str;
+
+ str = enum_flags_to_string(test_enum_flags_names,
+ enum_flags_to_string_tests[_i].val, buf, sizeof(buf));
+ if (str)
+ {
+ ck_assert_str_eq(enum_flags_to_string_tests[_i].str, str);
+ }
+ else
+ {
+ ck_assert(str == enum_flags_to_string_tests[_i].str);
+ }
+}
+END_TEST
+
+START_TEST(test_enum_flags_to_string_noflagenum)
+{
+ char buf[1024];
+
+ enum_flags_to_string(test_enum_cont_names,
+ printf_tests_flags_noflagenum[_i].val, buf, sizeof(buf));
+ ck_assert_str_eq(printf_tests_flags_noflagenum[_i].str, buf);
+}
+END_TEST
+
START_TEST(test_enum_printf_hook_width)
{
char buf[128];
@@ -246,9 +398,19 @@ Suite *enum_suite_create()
tcase_add_loop_test(tc, test_enum_from_name_split, 0, countof(enum_tests_split));
suite_add_tcase(s, tc);
+ tc = tcase_create("enum_flags_to_string");
+ tcase_add_loop_test(tc, test_enum_flags_to_string, 0, countof(enum_flags_to_string_tests));
+ tcase_add_loop_test(tc, test_enum_flags_to_string_noflagenum, 0, countof(printf_tests_flags_noflagenum));
+ suite_add_tcase(s, tc);
+
tc = tcase_create("enum_printf_hook");
tcase_add_loop_test(tc, test_enum_printf_hook_cont, 0, countof(printf_tests_cont));
tcase_add_loop_test(tc, test_enum_printf_hook_split, 0, countof(printf_tests_split));
+ tcase_add_loop_test(tc, test_enum_printf_hook_flags, 0, countof(printf_tests_flags));
+ tcase_add_loop_test(tc, test_enum_printf_hook_flags_incomplete, 0, countof(printf_tests_flags_incomplete));
+ tcase_add_loop_test(tc, test_enum_printf_hook_flags_null, 0, countof(printf_tests_flags_null));
+ tcase_add_loop_test(tc, test_enum_printf_hook_flags_overflow, 0, countof(printf_tests_flags_overflow));
+ tcase_add_loop_test(tc, test_enum_printf_hook_flags_noflagenum, 0, countof(printf_tests_flags_noflagenum));
tcase_add_test(tc, test_enum_printf_hook_width);
suite_add_tcase(s, tc);
diff --git a/src/libstrongswan/tests/suites/test_hasher.c b/src/libstrongswan/tests/suites/test_hasher.c
index 41a9d64ef..14cc32122 100644
--- a/src/libstrongswan/tests/suites/test_hasher.c
+++ b/src/libstrongswan/tests/suites/test_hasher.c
@@ -48,6 +48,9 @@ static hasher_oid_t oids[] = {
{ OID_ECDSA_WITH_SHA256, HASH_SHA256, KEY_ECDSA },
{ OID_ECDSA_WITH_SHA384, HASH_SHA384, KEY_ECDSA },
{ OID_ECDSA_WITH_SHA512, HASH_SHA512, KEY_ECDSA },
+ { OID_BLISS_WITH_SHA256, HASH_SHA256, KEY_BLISS },
+ { OID_BLISS_WITH_SHA384, HASH_SHA384, KEY_BLISS },
+ { OID_BLISS_WITH_SHA512, HASH_SHA512, KEY_BLISS },
{ OID_UNKNOWN, HASH_UNKNOWN, KEY_ECDSA }
};
diff --git a/src/libstrongswan/tests/suites/test_host.c b/src/libstrongswan/tests/suites/test_host.c
index 63442083a..7161b2c5b 100644
--- a/src/libstrongswan/tests/suites/test_host.c
+++ b/src/libstrongswan/tests/suites/test_host.c
@@ -237,6 +237,48 @@ START_TEST(test_create_from_string_and_family_other)
END_TEST
/*******************************************************************************
+ * host_create_from_dns
+ */
+
+static void test_create_from_dns(int family, chunk_t addr)
+{
+ host_t *host;
+
+ host = host_create_from_dns("localhost", family, 500);
+ if (family != AF_INET6)
+ {
+ ck_assert(host != NULL);
+ }
+ if (host)
+ {
+ if (family != AF_UNSPEC)
+ {
+ verify_address(host, addr, family, 500);
+ }
+ host->destroy(host);
+ }
+}
+
+START_TEST(test_create_from_dns_any)
+{
+ test_create_from_dns(AF_UNSPEC, chunk_empty);
+}
+END_TEST
+
+START_TEST(test_create_from_dns_v4)
+{
+ test_create_from_dns(AF_INET, chunk_from_chars(127,0,0,1));
+}
+END_TEST
+
+START_TEST(test_create_from_dns_v6)
+{
+ test_create_from_dns(AF_INET6,
+ chunk_from_chars(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1));
+}
+END_TEST
+
+/*******************************************************************************
* host_create_from_sockaddr
*/
@@ -400,6 +442,90 @@ START_TEST(test_create_from_subnet_v6)
END_TEST
/*******************************************************************************
+ * host_create_from_range
+ */
+
+static const chunk_t addr_v4_to = chunk_from_chars(0xc0, 0xa8, 0x00, 0x05);
+static const chunk_t addr_v6_to = chunk_from_chars(0xfe, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05);
+
+static void verify_range(char *str, int family, chunk_t from_addr,
+ chunk_t to_addr)
+{
+ host_t *from, *to;
+
+ if (!family)
+ {
+ ck_assert(!host_create_from_range(str, &from, &to));
+ }
+ else
+ {
+ ck_assert(host_create_from_range(str, &from, &to));
+ verify_address(from, from_addr, family, 0);
+ verify_address(to, to_addr, family, 0);
+ from->destroy(from);
+ to->destroy(to);
+ }
+}
+
+START_TEST(test_create_from_range_v4)
+{
+ host_t *from, *to;
+
+ ck_assert(host_create_from_range("0.0.0.0-0.0.0.0", &from, &to));
+ verify_any(from, AF_INET, 0);
+ verify_any(to, AF_INET, 0);
+ from->destroy(from);
+ to->destroy(to);
+
+ verify_range("192.168.0.1-192.168.0.1", AF_INET, addr_v4, addr_v4);
+ verify_range("192.168.0.1-192.168.0.5", AF_INET, addr_v4, addr_v4_to);
+ verify_range("192.168.0.1- 192.168.0.5", AF_INET, addr_v4, addr_v4_to);
+ verify_range("192.168.0.1 -192.168.0.5", AF_INET, addr_v4, addr_v4_to);
+ verify_range("192.168.0.1 - 192.168.0.5", AF_INET, addr_v4, addr_v4_to);
+ verify_range("192.168.0.5-192.168.0.1", AF_INET, addr_v4_to, addr_v4);
+
+ verify_range("192.168.0.1", 0, chunk_empty, chunk_empty);
+ verify_range("192.168.0.1-", 0, chunk_empty, chunk_empty);
+ verify_range("-192.168.0.1", 0, chunk_empty, chunk_empty);
+ verify_range("192.168.0.1-192", 0, chunk_empty, chunk_empty);
+ verify_range("192.168.0.1-192.168", 0, chunk_empty, chunk_empty);
+ verify_range("192.168.0.1-192.168.0", 0, chunk_empty, chunk_empty);
+ verify_range("foo.b.a.r", 0, chunk_empty, chunk_empty);
+ verify_range("foo.b.a.r-b.a.r.f", 0, chunk_empty, chunk_empty);
+}
+END_TEST
+
+START_TEST(test_create_from_range_v6)
+{
+ host_t *from, *to;
+
+ ck_assert(host_create_from_range("::-::", &from, &to));
+ verify_any(from, AF_INET6, 0);
+ verify_any(to, AF_INET6, 0);
+ from->destroy(from);
+ to->destroy(to);
+
+ verify_range("fec1::1-fec1::1", AF_INET6, addr_v6, addr_v6);
+ verify_range("fec1::1-fec1::5", AF_INET6, addr_v6, addr_v6_to);
+ verify_range("fec1::1- fec1::5", AF_INET6, addr_v6, addr_v6_to);
+ verify_range("fec1::1 -fec1::5", AF_INET6, addr_v6, addr_v6_to);
+ verify_range("fec1::1 - fec1::5", AF_INET6, addr_v6, addr_v6_to);
+ verify_range("fec1::5-fec1::1", AF_INET6, addr_v6_to, addr_v6);
+
+ verify_range("fec1::1", 0, chunk_empty, chunk_empty);
+ verify_range("fec1::1-", 0, chunk_empty, chunk_empty);
+ verify_range("-fec1::1", 0, chunk_empty, chunk_empty);
+ verify_range("fec1::1-fec1", 0, chunk_empty, chunk_empty);
+ verify_range("foo::bar", 0, chunk_empty, chunk_empty);
+ verify_range("foo::bar-bar::foo", 0, chunk_empty, chunk_empty);
+
+ verify_range("fec1::1-192.168.0.1", 0, chunk_empty, chunk_empty);
+ verify_range("192.168.0.1-fec1::1", 0, chunk_empty, chunk_empty);
+}
+END_TEST
+
+/*******************************************************************************
* host_create_netmask
*/
@@ -610,6 +736,12 @@ Suite *host_suite_create()
tcase_add_test(tc, test_create_from_string_and_family_other);
suite_add_tcase(s, tc);
+ tc = tcase_create("host_create_from_dns");
+ tcase_add_test(tc, test_create_from_dns_any);
+ tcase_add_test(tc, test_create_from_dns_v4);
+ tcase_add_test(tc, test_create_from_dns_v6);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("host_create_from_sockaddr");
tcase_add_test(tc, test_create_from_sockaddr_v4);
tcase_add_test(tc, test_create_from_sockaddr_v6);
@@ -627,6 +759,11 @@ Suite *host_suite_create()
tcase_add_test(tc, test_create_from_subnet_v6);
suite_add_tcase(s, tc);
+ tc = tcase_create("host_create_from_range");
+ tcase_add_test(tc, test_create_from_range_v4);
+ tcase_add_test(tc, test_create_from_range_v6);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("host_create_netmask");
tcase_add_test(tc, test_create_netmask_v4);
tcase_add_test(tc, test_create_netmask_v6);
diff --git a/src/libstrongswan/tests/suites/test_identification.c b/src/libstrongswan/tests/suites/test_identification.c
index 5de785710..de00e4afd 100644
--- a/src/libstrongswan/tests/suites/test_identification.c
+++ b/src/libstrongswan/tests/suites/test_identification.c
@@ -122,58 +122,68 @@ static struct {
} data;
} result;
} string_data[] = {
- {NULL, ID_ANY, { .type = ENC_CHUNK }},
- {"", ID_ANY, { .type = ENC_CHUNK }},
- {"%any", ID_ANY, { .type = ENC_CHUNK }},
- {"%any6", ID_ANY, { .type = ENC_CHUNK }},
- {"0.0.0.0", ID_ANY, { .type = ENC_CHUNK }},
- {"0::0", ID_ANY, { .type = ENC_CHUNK }},
- {"::", ID_ANY, { .type = ENC_CHUNK }},
- {"*", ID_ANY, { .type = ENC_CHUNK }},
- {"any", ID_FQDN, { .type = ENC_SIMPLE }},
- {"any6", ID_FQDN, { .type = ENC_SIMPLE }},
- {"0", ID_FQDN, { .type = ENC_SIMPLE }},
- {"**", ID_FQDN, { .type = ENC_SIMPLE }},
- {"192.168.1.1", ID_IPV4_ADDR, { .type = ENC_CHUNK,
- .data.c = chunk_from_chars(0xc0, 0xa8, 0x01, 0x01) }},
- {"192.168.",ID_FQDN, { .type = ENC_SIMPLE }},
- {".", ID_FQDN, { .type = ENC_SIMPLE }},
- {"fec0::1", ID_IPV6_ADDR, { .type = ENC_CHUNK,
- .data.c = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01) }},
- {"fec0::", ID_IPV6_ADDR, { .type = ENC_CHUNK,
- .data.c = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) }},
- {"fec0:", ID_KEY_ID, { .type = ENC_SIMPLE }},
- {":", ID_KEY_ID, { .type = ENC_SIMPLE }},
- {"alice@strongswan.org", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
- {"alice@strongswan", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
- {"alice@", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
- {"alice", ID_FQDN, { .type = ENC_SIMPLE }},
- {"@", ID_FQDN, { .type = ENC_CHUNK }},
- {" @", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
- {"@strongswan.org", ID_FQDN, { .type = ENC_STRING,
- .data.s = "strongswan.org" }},
- {"@#deadbeef", ID_KEY_ID, { .type = ENC_CHUNK,
- .data.c = chunk_from_chars(0xde, 0xad, 0xbe, 0xef) }},
- {"@#deadbee", ID_KEY_ID, { .type = ENC_CHUNK,
- .data.c = chunk_from_chars(0x0d, 0xea, 0xdb, 0xee) }},
- {"foo=bar", ID_KEY_ID, { .type = ENC_SIMPLE }},
- {"foo=", ID_KEY_ID, { .type = ENC_SIMPLE }},
- {"=bar", ID_KEY_ID, { .type = ENC_SIMPLE }},
- {"C=", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
- .data.c = chunk_from_chars(0x30, 0x0b, 0x31, 0x09, 0x30, 0x07, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x00)}},
- {"C=CH", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
- .data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
- {"C=CH,", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
- .data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
- {"C=CH, ", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
- .data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06,
- 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}},
- {"C=CH, O", ID_KEY_ID, { .type = ENC_SIMPLE }},
+ {NULL, ID_ANY, { .type = ENC_CHUNK }},
+ {"", ID_ANY, { .type = ENC_CHUNK }},
+ {"%any", ID_ANY, { .type = ENC_CHUNK }},
+ {"%any6", ID_ANY, { .type = ENC_CHUNK }},
+ {"0.0.0.0", ID_ANY, { .type = ENC_CHUNK }},
+ {"0::0", ID_ANY, { .type = ENC_CHUNK }},
+ {"::", ID_ANY, { .type = ENC_CHUNK }},
+ {"*", ID_ANY, { .type = ENC_CHUNK }},
+ {"any", ID_FQDN, { .type = ENC_SIMPLE }},
+ {"any6", ID_FQDN, { .type = ENC_SIMPLE }},
+ {"0", ID_FQDN, { .type = ENC_SIMPLE }},
+ {"**", ID_FQDN, { .type = ENC_SIMPLE }},
+ {"192.168.1.1", ID_IPV4_ADDR, { .type = ENC_CHUNK,
+ .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
+ {"192.168.", ID_FQDN, { .type = ENC_SIMPLE }},
+ {".", ID_FQDN, { .type = ENC_SIMPLE }},
+ {"fec0::1", ID_IPV6_ADDR, { .type = ENC_CHUNK,
+ .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01) }},
+ {"fec0::", ID_IPV6_ADDR, { .type = ENC_CHUNK,
+ .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) }},
+ {"fec0:", ID_KEY_ID, { .type = ENC_SIMPLE }},
+ {":", ID_KEY_ID, { .type = ENC_SIMPLE }},
+ {"alice@strongswan.org", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
+ {"alice@strongswan", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
+ {"alice@", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
+ {"alice", ID_FQDN, { .type = ENC_SIMPLE }},
+ {"@", ID_FQDN, { .type = ENC_CHUNK }},
+ {" @", ID_RFC822_ADDR, { .type = ENC_SIMPLE }},
+ {"@strongswan.org", ID_FQDN, { .type = ENC_STRING,
+ .data.s = "strongswan.org" }},
+ {"@#deadbeef", ID_KEY_ID, { .type = ENC_CHUNK,
+ .data.c = chunk_from_chars(0xde,0xad,0xbe,0xef) }},
+ {"@#deadbee", ID_KEY_ID, { .type = ENC_CHUNK,
+ .data.c = chunk_from_chars(0x0d,0xea,0xdb,0xee) }},
+ {"foo=bar", ID_KEY_ID, { .type = ENC_SIMPLE }},
+ {"foo=", ID_KEY_ID, { .type = ENC_SIMPLE }},
+ {"=bar", ID_KEY_ID, { .type = ENC_SIMPLE }},
+ {"C=", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
+ .data.c = chunk_from_chars(0x30,0x0b,0x31,0x09,0x30,0x07,0x06,
+ 0x03,0x55,0x04,0x06,0x13,0x00) }},
+ {"C=CH", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
+ .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
+ 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
+ {"C=CH,", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
+ .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
+ 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
+ {"C=CH, ", ID_DER_ASN1_DN, { .type = ENC_CHUNK,
+ .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06,
+ 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }},
+ {"C=CH, O", ID_KEY_ID, { .type = ENC_SIMPLE }},
+ {"IPv4:#c0a80101", ID_IPV4_ADDR, { .type = ENC_CHUNK,
+ .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
+ { "email:tester", ID_RFC822_ADDR, { .type = ENC_STRING,
+ .data.s = "tester" }},
+ { "{1}:#c0a80101", ID_IPV4_ADDR, { .type = ENC_CHUNK,
+ .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }},
+ { "{0x02}:tester", ID_FQDN, { .type = ENC_STRING,
+ .data.s = "tester" }},
+ { "{99}:somedata", 99, { .type = ENC_STRING,
+ .data.s = "somedata" }},
};
START_TEST(test_from_string)
diff --git a/src/libstrongswan/tests/suites/test_mgf1.c b/src/libstrongswan/tests/suites/test_mgf1.c
new file mode 100644
index 000000000..9388b95d4
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_mgf1.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <tests/utils/test_rng.h>
+#include <utils/test.h>
+#include <crypto/mgf1/mgf1.h>
+#include <crypto/mgf1/mgf1_bitspender.h>
+
+typedef struct {
+ hash_algorithm_t alg;
+ size_t hash_size;
+ size_t ml1, ml2, ml3, seed_len;
+ chunk_t seed;
+ chunk_t hashed_seed;
+ chunk_t mask;
+ uint32_t bits[22];
+} mgf1_test_t;
+
+/**
+ * MGF1 Mask Generation Function Test Vectors
+ */
+mgf1_test_t mgf1_tests[] = {
+ { HASH_SHA1, 20, 60, 20, 15, 24,
+ chunk_from_chars(
+ 0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D,
+ 0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D,
+ 0x8C, 0x9B, 0xD5, 0x63, 0x57, 0x38, 0x11, 0xC2,
+ 0xB5, 0xCA, 0xBF, 0x06, 0x43, 0x45, 0x19, 0xD5,
+ 0xE7, 0x36, 0xD0, 0x29, 0x21, 0xDA, 0x02, 0x20,
+ 0x45, 0xF6, 0x5F, 0x0F, 0x10, 0x04, 0x2A, 0xE3,
+ 0x6A, 0x1D, 0xD5, 0x9F, 0x1D, 0x66, 0x44, 0x8F,
+ 0xFA, 0xC6, 0xCA, 0xA4, 0x6E, 0x3B, 0x00, 0x66,
+ 0xA6, 0xC9, 0x80, 0x5C, 0xF5, 0x2D, 0xD7, 0x72,
+ 0xC6, 0xD4, 0x4F, 0x30, 0x72, 0xA2, 0xAD, 0xE0,
+ 0x33, 0xE8, 0x55, 0xD5, 0xE6, 0xD6, 0x00, 0x1D,
+ 0xA8, 0x68, 0xFF, 0x97, 0x36, 0x8A, 0xF4, 0xD6,
+ 0xF1, 0xB6, 0x7E, 0x1F, 0x06, 0xCB, 0x57, 0xCB,
+ 0x35, 0x38, 0xF2, 0x2D, 0xF6, 0x20),
+ chunk_from_chars(
+ 0xF3, 0x9B, 0x0B, 0xB4, 0x97, 0x50, 0xB5, 0xA7,
+ 0xE6, 0xBD, 0xDA, 0xD0, 0x9A, 0x52, 0xBE, 0xA0,
+ 0x21, 0xC4, 0x90, 0xB6),
+ chunk_from_chars(
+ 0x10, 0x43, 0x76, 0x72, 0x6C, 0xDE, 0xA0, 0x0E,
+ 0x77, 0x51, 0xFB, 0x58, 0x39, 0x8A, 0x36, 0xE1,
+ 0x63, 0x2B, 0xC9, 0x17, 0x56, 0x0C, 0x4B, 0x46,
+ 0xA4, 0x07, 0xA4, 0x3B, 0x8E, 0x33, 0x4D, 0xD1,
+ 0x65, 0xF1, 0xAC, 0xC8, 0x59, 0x21, 0x32, 0x16,
+ 0x44, 0x2B, 0x7F, 0xB2, 0xA8, 0xA7, 0x26, 0x5D,
+ 0xE8, 0x02, 0xBE, 0x8E, 0xDC, 0x34, 0xEB, 0x10,
+ 0x76, 0x16, 0x8C, 0xDD, 0x90, 0x92, 0x3D, 0x29,
+ 0x90, 0x98, 0x46, 0x11, 0x73, 0x53, 0x47, 0xB1,
+ 0x2C, 0xD4, 0x83, 0x78, 0x9B, 0x93, 0x2F, 0x5B,
+ 0xFC, 0x26, 0xFF, 0x42, 0x08, 0x1F, 0x70, 0x66,
+ 0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D,
+ 0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C,
+ 0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92,
+ 0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14),
+ { 0, 0, 0, 4, 1, 1, 46, 103, 38, 411, 848, 57, 3540, 4058, 12403,
+ 0x63, 0x2B, 0xC9, 0x17, 0x56, 669409, 0xA407A43B },
+ },
+ { HASH_SHA256, 32, 64, 32, 33, 40,
+ chunk_from_chars(
+ 0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53,
+ 0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69,
+ 0xC5, 0x9D, 0xDE, 0xF6, 0xFC, 0xFA, 0x93, 0xCE,
+ 0x32, 0x52, 0x66, 0xF9, 0xC9, 0x97, 0xF6, 0x42,
+ 0x00, 0x2C, 0x64, 0xED, 0x1A, 0x6B, 0x14, 0x0A,
+ 0x4B, 0x04, 0xCF, 0x6D, 0x2D, 0x82, 0x0A, 0x07,
+ 0xA2, 0x3B, 0xDE, 0xCE, 0x19, 0x8A, 0x39, 0x43,
+ 0x16, 0x61, 0x29, 0x98, 0x68, 0xEA, 0xE5, 0xCC,
+ 0x0A, 0xF8, 0xE9, 0x71, 0x26, 0xF1, 0x07, 0x36,
+ 0x2C, 0x07, 0x1E, 0xEB, 0xE4, 0x28, 0xA2, 0xF4,
+ 0xA8, 0x12, 0xC0, 0xC8, 0x20, 0x37, 0xF8, 0xF2,
+ 0x6C, 0xAF, 0xDC, 0x6F, 0x2E, 0xD0, 0x62, 0x58,
+ 0xD2, 0x37, 0x03, 0x6D, 0xFA, 0x6E, 0x1A, 0xAC,
+ 0x9F, 0xCA, 0x56, 0xC6, 0xA4, 0x52, 0x41, 0xE8,
+ 0x0F, 0x1B, 0x0C, 0xB9, 0xE6, 0xBA, 0xDE, 0xE1,
+ 0x03, 0x5E, 0xC2, 0xE5, 0xF8, 0xF4, 0xF3, 0x46,
+ 0x3A, 0x12, 0xC0, 0x1F, 0x3A, 0x00, 0xD0, 0x91,
+ 0x18, 0xDD, 0x53, 0xE4, 0x22, 0xF5, 0x26, 0xA4,
+ 0x54, 0xEE, 0x20, 0xF0, 0x80),
+ chunk_from_chars(
+ 0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D,
+ 0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB,
+ 0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C,
+ 0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28),
+ chunk_from_chars(
+ 0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A,
+ 0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46,
+ 0xCB, 0x35, 0x3C, 0xDC, 0xAD, 0x20, 0xD9, 0x3F,
+ 0x0D, 0xD1, 0xAA, 0x64, 0x66, 0x5C, 0xFA, 0x4A,
+ 0xFE, 0xD6, 0x8F, 0x55, 0x57, 0x15, 0xB2, 0xA6,
+ 0xA0, 0xE6, 0xA8, 0xC6, 0xBD, 0x28, 0xB4, 0xD5,
+ 0x6E, 0x5B, 0x4B, 0xB0, 0x97, 0x09, 0xF5, 0xAC,
+ 0x57, 0x65, 0x13, 0x97, 0x71, 0x2C, 0x45, 0x13,
+ 0x3D, 0xEE, 0xFB, 0xBF, 0xFE, 0xAF, 0xBB, 0x4B,
+ 0x0D, 0x5C, 0x45, 0xD4, 0x2F, 0x17, 0x92, 0x07,
+ 0x66, 0x11, 0xF5, 0x46, 0xF8, 0x0C, 0x03, 0x92,
+ 0xF5, 0xF5, 0xFF, 0xA4, 0xF3, 0x52, 0xF4, 0x08,
+ 0x2C, 0x49, 0x32, 0x1A, 0x93, 0x51, 0x98, 0xB6,
+ 0x94, 0x83, 0x39, 0xCF, 0x6B, 0x1F, 0x2F, 0xFC,
+ 0x2B, 0xFF, 0x10, 0x71, 0x7D, 0x35, 0x6C, 0xEA,
+ 0xC5, 0x66, 0xC7, 0x26, 0x7D, 0x9E, 0xAC, 0xDD,
+ 0x35, 0xD7, 0x06, 0x3F, 0x40, 0x82, 0xDA, 0xC3,
+ 0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6,
+ 0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95,
+ 0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42),
+ { 0, 1, 3, 4, 4, 12, 32, 36, 253, 331, 2, 1640, 503, 6924, 580,
+ 0xCB, 0x35, 0x3C, 0xDC, 0xAD, 922950, 0x0DD1AA64 }
+ }
+};
+
+START_TEST(mgf1_test_mgf1)
+{
+ mgf1_t *mgf1;
+ chunk_t mask, mask1, mask2, mask3;
+
+ mask1 = mgf1_tests[_i].mask;
+ mask2 = chunk_skip(mask1, mgf1_tests[_i].ml1);
+ mask3 = chunk_skip(mask2, mgf1_tests[_i].ml2);
+ mask1.len = mgf1_tests[_i].ml1;
+ mask2.len = mgf1_tests[_i].ml2;
+ mask3.len = mgf1_tests[_i].ml3;
+
+ mgf1 = mgf1_create(HASH_UNKNOWN, mgf1_tests[_i].seed, TRUE);
+ ck_assert(mgf1 == NULL);
+
+ mgf1 = mgf1_create(mgf1_tests[_i].alg, chunk_empty, TRUE);
+ ck_assert(mgf1 == NULL);
+
+ /* return mask in allocated chunk */
+ mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE);
+ ck_assert(mgf1);
+
+ /* check hash size */
+ ck_assert(mgf1->get_hash_size(mgf1) == mgf1_tests[_i].hash_size);
+
+ /* get zero number of octets */
+ ck_assert(mgf1->allocate_mask(mgf1, 0, &mask));
+ ck_assert(mask.len == 0 && mask.ptr == NULL);
+
+ /* get non-zero number of octets */
+ ck_assert(mgf1->allocate_mask(mgf1, mgf1_tests[_i].mask.len, &mask));
+ ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
+ mgf1->destroy(mgf1);
+
+ /* copy mask to pre-allocated buffer */
+ mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE);
+ ck_assert(mgf1);
+ ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr));
+ ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
+ mgf1->destroy(mgf1);
+
+ /* get mask in batches without hashing the seed */
+ mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].hashed_seed, FALSE);
+ ck_assert(mgf1);
+
+ /* first batch */
+ ck_assert(mgf1->get_mask(mgf1, mask1.len, mask.ptr));
+ mask.len = mask1.len;
+ ck_assert(chunk_equals(mask, mask1));
+
+ /* second batch */
+ ck_assert(mgf1->get_mask(mgf1, mask2.len, mask.ptr));
+ mask.len = mask2.len;
+ ck_assert(chunk_equals(mask, mask2));
+
+ /* third batch */
+ ck_assert(mgf1->get_mask(mgf1, mask3.len, mask.ptr));
+ mask.len = mask3.len;
+ ck_assert(chunk_equals(mask, mask3));
+
+ mgf1->destroy(mgf1);
+ chunk_free(&mask);
+}
+END_TEST
+
+START_TEST(mgf1_test_bitspender)
+{
+ mgf1_bitspender_t *bitspender;
+ uint32_t bits;
+ uint8_t byte;
+ int j;
+
+ bitspender = mgf1_bitspender_create(HASH_UNKNOWN,
+ mgf1_tests[_i].hashed_seed, FALSE);
+ ck_assert(bitspender == NULL);
+
+ bitspender = mgf1_bitspender_create(mgf1_tests[_i].alg,
+ mgf1_tests[_i].hashed_seed, FALSE);
+ ck_assert(bitspender);
+
+ for (j = 0; j < 15; j++)
+ {
+ ck_assert(bitspender->get_bits(bitspender, j, &bits));
+ DBG1(DBG_LIB, "bits[%d] = %u, bits = %u", j, mgf1_tests[_i].bits[j],
+ bits);
+ ck_assert(bits == mgf1_tests[_i].bits[j]);
+ }
+ ck_assert(!bitspender->get_bits(bitspender, 33, &bits));
+
+ for (j = 15; j < 20; j++)
+ {
+ ck_assert(bitspender->get_byte(bitspender, &byte));
+ DBG1(DBG_LIB, "bits[%d] = 0x%02x, byte = 0x%02x", j,
+ mgf1_tests[_i].bits[j], byte);
+ ck_assert(byte == mgf1_tests[_i].bits[j]);
+ }
+
+ j = 20; /* 23 remaining bits */
+ ck_assert(bitspender->get_bits(bitspender, 23, &bits));
+ DBG1(DBG_LIB, "bits[%d] = %u, bits = %u", j,
+ mgf1_tests[_i].bits[j], bits);
+ ck_assert(bits == mgf1_tests[_i].bits[j]);
+
+ j = 21; /* 32 aligned bits */
+ ck_assert(bitspender->get_bits(bitspender, 32, &bits));
+ DBG1(DBG_LIB, "bits[%d] = 0x%08x, bits = 0x%08x", j,
+ mgf1_tests[_i].bits[j], bits);
+ ck_assert(bits == mgf1_tests[_i].bits[j]);
+
+ bitspender->destroy(bitspender);
+}
+END_TEST
+
+
+Suite *mgf1_suite_create(char *name, int n)
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create(name);
+
+ tc = tcase_create("mgf1");
+ tcase_add_loop_test(tc, mgf1_test_mgf1, n, n + 1);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("bitspender");
+ tcase_add_loop_test(tc, mgf1_test_bitspender, n, n + 1);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
+
+Suite *mgf1_sha1_suite_create()
+{
+ return mgf1_suite_create("mgf1-sha1", 0);
+}
+
+Suite *mgf1_sha256_suite_create()
+{
+ return mgf1_suite_create("mgf1-sha256", 1);
+}
diff --git a/src/libstrongswan/tests/suites/test_ntru.c b/src/libstrongswan/tests/suites/test_ntru.c
index 7c0cb81bf..d209fa2bc 100644
--- a/src/libstrongswan/tests/suites/test_ntru.c
+++ b/src/libstrongswan/tests/suites/test_ntru.c
@@ -16,20 +16,17 @@
#include "test_suite.h"
#include <tests/utils/test_rng.h>
+#include <utils/test.h>
+#include <crypto/mgf1/mgf1.h>
#include <plugins/ntru/ntru_drbg.h>
-#include <plugins/ntru/ntru_mgf1.h>
#include <plugins/ntru/ntru_trits.h>
#include <plugins/ntru/ntru_poly.h>
#include <plugins/ntru/ntru_param_set.h>
#include <plugins/ntru/ntru_private_key.h>
-#include <utils/test.h>
IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_drbg_create, ntru_drbg_t*,
u_int32_t strength, chunk_t pers_str, rng_t *entropy)
-IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_mgf1_create, ntru_mgf1_t*,
- hash_algorithm_t alg, chunk_t seed, bool hash_seed)
-
IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_trits_create, ntru_trits_t*,
size_t len, hash_algorithm_t alg, chunk_t seed)
@@ -334,13 +331,11 @@ typedef struct {
typedef struct {
hash_algorithm_t alg;
size_t hash_size;
- size_t ml1, ml2, ml3, seed_len;
+ size_t seed_len;
chunk_t seed;
- chunk_t hashed_seed;
- chunk_t mask;
chunk_t trits;
poly_test_t poly_test[2];
-} mgf1_test_t;
+} trits_test_t;
uint16_t indices_ees439ep1[] = {
367, 413, 16, 214, 114, 128, 42, 268, 346, 329, 119, 303, 208, 287, 150,
@@ -386,10 +381,10 @@ uint16_t indices_ees1171ep1[] = {
};
/**
- * MGF1 Mask Generation Function Test Vectors
+ * Trits and Polynomial Test Vectors
*/
-mgf1_test_t mgf1_tests[] = {
- { HASH_SHA1, 20, 60, 20, 15, 24,
+static trits_test_t trits_tests[] = {
+ { HASH_SHA1, 20, 24,
chunk_from_chars(
0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D,
0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D,
@@ -406,26 +401,6 @@ mgf1_test_t mgf1_tests[] = {
0xF1, 0xB6, 0x7E, 0x1F, 0x06, 0xCB, 0x57, 0xCB,
0x35, 0x38, 0xF2, 0x2D, 0xF6, 0x20),
chunk_from_chars(
- 0xF3, 0x9B, 0x0B, 0xB4, 0x97, 0x50, 0xB5, 0xA7,
- 0xE6, 0xBD, 0xDA, 0xD0, 0x9A, 0x52, 0xBE, 0xA0,
- 0x21, 0xC4, 0x90, 0xB6),
- chunk_from_chars(
- 0x10, 0x43, 0x76, 0x72, 0x6C, 0xDE, 0xA0, 0x0E,
- 0x77, 0x51, 0xFB, 0x58, 0x39, 0x8A, 0x36, 0xE1,
- 0x63, 0x2B, 0xC9, 0x17, 0x56, 0x0C, 0x4B, 0x46,
- 0xA4, 0x07, 0xA4, 0x3B, 0x8E, 0x33, 0x4D, 0xD1,
- 0x65, 0xF1, 0xAC, 0xC8, 0x59, 0x21, 0x32, 0x16,
- 0x44, 0x2B, 0x7F, 0xB2, 0xA8, 0xA7, 0x26, 0x5D,
- 0xE8, 0x02, 0xBE, 0x8E, 0xDC, 0x34, 0xEB, 0x10,
- 0x76, 0x16, 0x8C, 0xDD, 0x90, 0x92, 0x3D, 0x29,
- 0x90, 0x98, 0x46, 0x11, 0x73, 0x53, 0x47, 0xB1,
- 0x2C, 0xD4, 0x83, 0x78, 0x9B, 0x93, 0x2F, 0x5B,
- 0xFC, 0x26, 0xFF, 0x42, 0x08, 0x1F, 0x70, 0x66,
- 0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D,
- 0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C,
- 0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92,
- 0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14),
- chunk_from_chars(
1, 2, 1, 0, 0, 1, 1, 1, 2, 0, 1, 0, 1, 1, 1, 0, 2, 0, 1, 1,
0, 0, 0, 1, 1, 0, 2, 0, 2, 2, 1, 2, 2, 2, 1, 2, 1, 1, 0, 0,
2, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 2, 0, 0, 1, 0, 1, 0, 2, 0,
@@ -457,7 +432,7 @@ mgf1_test_t mgf1_tests[] = {
}
}
},
- { HASH_SHA256, 32, 64, 32, 33, 40,
+ { HASH_SHA256, 32, 40,
chunk_from_chars(
0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53,
0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69,
@@ -479,32 +454,6 @@ mgf1_test_t mgf1_tests[] = {
0x18, 0xDD, 0x53, 0xE4, 0x22, 0xF5, 0x26, 0xA4,
0x54, 0xEE, 0x20, 0xF0, 0x80),
chunk_from_chars(
- 0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D,
- 0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB,
- 0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C,
- 0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28),
- chunk_from_chars(
- 0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A,
- 0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46,
- 0xCB, 0x35, 0x3C, 0xDC, 0xAD, 0x20, 0xD9, 0x3F,
- 0x0D, 0xD1, 0xAA, 0x64, 0x66, 0x5C, 0xFA, 0x4A,
- 0xFE, 0xD6, 0x8F, 0x55, 0x57, 0x15, 0xB2, 0xA6,
- 0xA0, 0xE6, 0xA8, 0xC6, 0xBD, 0x28, 0xB4, 0xD5,
- 0x6E, 0x5B, 0x4B, 0xB0, 0x97, 0x09, 0xF5, 0xAC,
- 0x57, 0x65, 0x13, 0x97, 0x71, 0x2C, 0x45, 0x13,
- 0x3D, 0xEE, 0xFB, 0xBF, 0xFE, 0xAF, 0xBB, 0x4B,
- 0x0D, 0x5C, 0x45, 0xD4, 0x2F, 0x17, 0x92, 0x07,
- 0x66, 0x11, 0xF5, 0x46, 0xF8, 0x0C, 0x03, 0x92,
- 0xF5, 0xF5, 0xFF, 0xA4, 0xF3, 0x52, 0xF4, 0x08,
- 0x2C, 0x49, 0x32, 0x1A, 0x93, 0x51, 0x98, 0xB6,
- 0x94, 0x83, 0x39, 0xCF, 0x6B, 0x1F, 0x2F, 0xFC,
- 0x2B, 0xFF, 0x10, 0x71, 0x7D, 0x35, 0x6C, 0xEA,
- 0xC5, 0x66, 0xC7, 0x26, 0x7D, 0x9E, 0xAC, 0xDD,
- 0x35, 0xD7, 0x06, 0x3F, 0x40, 0x82, 0xDA, 0xC3,
- 0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6,
- 0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95,
- 0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42),
- chunk_from_chars(
1, 2, 2, 2, 2, 1, 2, 2, 0, 0, 2, 0, 0, 0, 0, 1, 2, 2, 2, 0,
2, 0, 0, 2, 2, 1, 2, 0, 0, 1, 2, 1, 0, 0, 0, 1, 0, 2, 2, 1,
1, 2, 0, 0, 0, 1, 2, 0, 2, 2, 1, 2, 1, 0, 1, 0, 1, 2, 1, 1,
@@ -546,104 +495,34 @@ mgf1_test_t mgf1_tests[] = {
}
};
-START_TEST(test_ntru_mgf1)
-{
- ntru_mgf1_t *mgf1;
- chunk_t mask, mask1, mask2, mask3;
-
- mask1 = mgf1_tests[_i].mask;
- mask2 = chunk_skip(mask1, mgf1_tests[_i].ml1);
- mask3 = chunk_skip(mask2, mgf1_tests[_i].ml2);
- mask1.len = mgf1_tests[_i].ml1;
- mask2.len = mgf1_tests[_i].ml2;
- mask3.len = mgf1_tests[_i].ml3;
-
- mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, HASH_UNKNOWN,
- mgf1_tests[_i].seed, TRUE);
- ck_assert(mgf1 == NULL);
-
- mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
- chunk_empty, TRUE);
- ck_assert(mgf1 == NULL);
-
- /* return mask in allocated chunk */
- mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
- mgf1_tests[_i].seed, TRUE);
- ck_assert(mgf1);
-
- /* check hash size */
- ck_assert(mgf1->get_hash_size(mgf1) == mgf1_tests[_i].hash_size);
-
- /* get zero number of octets */
- ck_assert(mgf1->allocate_mask(mgf1, 0, &mask));
- ck_assert(mask.len == 0 && mask.ptr == NULL);
-
- /* get non-zero number of octets */
- ck_assert(mgf1->allocate_mask(mgf1, mgf1_tests[_i].mask.len, &mask));
- ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
- mgf1->destroy(mgf1);
-
- /* copy mask to pre-allocated buffer */
- mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
- mgf1_tests[_i].seed, TRUE);
- ck_assert(mgf1);
- ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr));
- ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
- mgf1->destroy(mgf1);
-
- /* get mask in batches without hashing the seed */
- mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
- mgf1_tests[_i].hashed_seed, FALSE);
- ck_assert(mgf1);
-
- /* first batch */
- ck_assert(mgf1->get_mask(mgf1, mask1.len, mask.ptr));
- mask.len = mask1.len;
- ck_assert(chunk_equals(mask, mask1));
-
- /* second batch */
- ck_assert(mgf1->get_mask(mgf1, mask2.len, mask.ptr));
- mask.len = mask2.len;
- ck_assert(chunk_equals(mask, mask2));
-
- /* third batch */
- ck_assert(mgf1->get_mask(mgf1, mask3.len, mask.ptr));
- mask.len = mask3.len;
- ck_assert(chunk_equals(mask, mask3));
-
- mgf1->destroy(mgf1);
- chunk_free(&mask);
-}
-END_TEST
-
START_TEST(test_ntru_trits)
{
ntru_trits_t *mask;
chunk_t trits;
- mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
- HASH_UNKNOWN, mgf1_tests[_i].seed);
+ mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len,
+ HASH_UNKNOWN, trits_tests[_i].seed);
ck_assert(mask == NULL);
- mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
- mgf1_tests[_i].alg, chunk_empty);
+ mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len,
+ trits_tests[_i].alg, chunk_empty);
ck_assert(mask == NULL);
- mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
- mgf1_tests[_i].alg, mgf1_tests[_i].seed);
+ mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len,
+ trits_tests[_i].alg, trits_tests[_i].seed);
ck_assert(mask);
trits = chunk_create(mask->get_trits(mask), mask->get_size(mask));
- ck_assert(chunk_equals(trits, mgf1_tests[_i].trits));
+ ck_assert(chunk_equals(trits, trits_tests[_i].trits));
mask->destroy(mask);
/* generate a multiple of 5 trits */
- mask = TEST_FUNCTION(ntru, ntru_trits_create, 10, mgf1_tests[_i].alg,
- mgf1_tests[_i].seed);
+ mask = TEST_FUNCTION(ntru, ntru_trits_create, 10, trits_tests[_i].alg,
+ trits_tests[_i].seed);
ck_assert(mask);
trits = chunk_create(mask->get_trits(mask), mask->get_size(mask));
- ck_assert(chunk_equals(trits, chunk_create(mgf1_tests[_i].trits.ptr, 10)));
+ ck_assert(chunk_equals(trits, chunk_create(trits_tests[_i].trits.ptr, 10)));
mask->destroy(mask);
}
END_TEST
@@ -656,10 +535,10 @@ START_TEST(test_ntru_poly)
poly_test_t *p;
int j, n;
- seed = mgf1_tests[_i].seed;
- seed.len = mgf1_tests[_i].seed_len;
+ seed = trits_tests[_i].seed;
+ seed.len = trits_tests[_i].seed_len;
- p = &mgf1_tests[_i].poly_test[0];
+ p = &trits_tests[_i].poly_test[0];
poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, HASH_UNKNOWN, seed,
p->c_bits, p->N, p->q, p->indices_len, p->indices_len,
p->is_product_form);
@@ -667,9 +546,9 @@ START_TEST(test_ntru_poly)
for (n = 0; n < 2; n++)
{
- p = &mgf1_tests[_i].poly_test[n];
+ p = &trits_tests[_i].poly_test[n];
poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed,
- mgf1_tests[_i].alg, seed, p->c_bits, p->N, p->q,
+ trits_tests[_i].alg, seed, p->c_bits, p->N, p->q,
p->indices_len, p->indices_len, p->is_product_form);
ck_assert(poly != NULL && poly->get_size(poly) == p->indices_size);
@@ -1182,7 +1061,6 @@ START_TEST(test_ntru_ke)
diffie_hellman_t *i_ntru, *r_ntru;
char buf[10];
int k, n, len;
- status_t status;
k = (_i) / countof(parameter_sets);
n = (_i) % countof(parameter_sets);
@@ -1199,23 +1077,21 @@ START_TEST(test_ntru_ke)
ck_assert(i_ntru != NULL);
ck_assert(i_ntru->get_dh_group(i_ntru) == params[k].group);
- i_ntru->get_my_public_value(i_ntru, &pub_key);
+ ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key));
ck_assert(pub_key.len > 0);
r_ntru = lib->crypto->create_dh(lib->crypto, params[k].group);
ck_assert(r_ntru != NULL);
- r_ntru->set_other_public_value(r_ntru, pub_key);
- r_ntru->get_my_public_value(r_ntru, &cipher_text);
+ ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key));
+ ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
ck_assert(cipher_text.len > 0);
- status = r_ntru->get_shared_secret(r_ntru, &r_shared_secret);
- ck_assert(status == SUCCESS);
+ ck_assert(r_ntru->get_shared_secret(r_ntru, &r_shared_secret));
ck_assert(r_shared_secret.len > 0);
- i_ntru->set_other_public_value(i_ntru, cipher_text);
- status = i_ntru->get_shared_secret(i_ntru, &i_shared_secret);
- ck_assert(status == SUCCESS);
+ ck_assert(i_ntru->set_other_public_value(i_ntru, cipher_text));
+ ck_assert(i_ntru->get_shared_secret(i_ntru, &i_shared_secret));
ck_assert(chunk_equals(i_shared_secret, r_shared_secret));
chunk_clear(&i_shared_secret);
@@ -1233,8 +1109,8 @@ START_TEST(test_ntru_retransmission)
chunk_t pub_key1, pub_key2;
i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_256_BIT);
- i_ntru->get_my_public_value(i_ntru, &pub_key1);
- i_ntru->get_my_public_value(i_ntru, &pub_key2);
+ ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key1));
+ ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key2));
ck_assert(chunk_equals(pub_key1, pub_key2));
chunk_free(&pub_key1);
@@ -1260,8 +1136,8 @@ START_TEST(test_ntru_pubkey_oid)
chunk_t cipher_text;
r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
- r_ntru->set_other_public_value(r_ntru, oid_tests[_i]);
- r_ntru->get_my_public_value(r_ntru, &cipher_text);
+ ck_assert(!r_ntru->set_other_public_value(r_ntru, oid_tests[_i]));
+ ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
ck_assert(cipher_text.len == 0);
r_ntru->destroy(r_ntru);
}
@@ -1276,14 +1152,14 @@ START_TEST(test_ntru_wrong_set)
"libstrongswan.plugins.ntru.parameter_set",
"x9_98_bandwidth");
i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT);
- i_ntru->get_my_public_value(i_ntru, &pub_key);
+ ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key));
lib->settings->set_str(lib->settings,
"libstrongswan.plugins.ntru.parameter_set",
"optimum");
r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT);
- r_ntru->set_other_public_value(r_ntru, pub_key);
- r_ntru->get_my_public_value(r_ntru, &cipher_text);
+ ck_assert(!r_ntru->set_other_public_value(r_ntru, pub_key));
+ ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
ck_assert(cipher_text.len == 0);
chunk_free(&pub_key);
@@ -1314,9 +1190,9 @@ START_TEST(test_ntru_ciphertext)
for (i = 0; i < countof(test); i++)
{
i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
- i_ntru->get_my_public_value(i_ntru, &pub_key);
- i_ntru->set_other_public_value(i_ntru, test[i]);
- ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS);
+ ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key));
+ ck_assert(!i_ntru->set_other_public_value(i_ntru, test[i]));
+ ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret));
ck_assert(shared_secret.len == 0);
chunk_free(&pub_key);
@@ -1334,12 +1210,12 @@ START_TEST(test_ntru_wrong_ciphertext)
r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
m_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
- i_ntru->get_my_public_value(i_ntru, &pub_key_i);
- m_ntru->get_my_public_value(m_ntru, &pub_key_m);
- r_ntru->set_other_public_value(r_ntru, pub_key_m);
- r_ntru->get_my_public_value(r_ntru, &cipher_text);
- i_ntru->set_other_public_value(i_ntru, cipher_text);
- ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS);
+ ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key_i));
+ ck_assert(m_ntru->get_my_public_value(m_ntru, &pub_key_m));
+ ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key_m));
+ ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text));
+ ck_assert(!i_ntru->set_other_public_value(i_ntru, cipher_text));
+ ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret));
ck_assert(shared_secret.len == 0);
chunk_free(&pub_key_i);
@@ -1370,16 +1246,12 @@ Suite *ntru_suite_create()
tcase_add_test(tc, test_ntru_drbg_reseed);
suite_add_tcase(s, tc);
- tc = tcase_create("mgf1");
- tcase_add_loop_test(tc, test_ntru_mgf1, 0, countof(mgf1_tests));
- suite_add_tcase(s, tc);
-
tc = tcase_create("trits");
- tcase_add_loop_test(tc, test_ntru_trits, 0, countof(mgf1_tests));
+ tcase_add_loop_test(tc, test_ntru_trits, 0, countof(trits_tests));
suite_add_tcase(s, tc);
tc = tcase_create("poly");
- tcase_add_loop_test(tc, test_ntru_poly, 0, countof(mgf1_tests));
+ tcase_add_loop_test(tc, test_ntru_poly, 0, countof(trits_tests));
suite_add_tcase(s, tc);
tc = tcase_create("ring_mult");
diff --git a/src/libstrongswan/tests/suites/test_settings.c b/src/libstrongswan/tests/suites/test_settings.c
index b9d429a24..9601a34a9 100644
--- a/src/libstrongswan/tests/suites/test_settings.c
+++ b/src/libstrongswan/tests/suites/test_settings.c
@@ -908,7 +908,7 @@ START_SETUP(setup_string_config)
"special = \"all { special } characters # can be used.\"\n"
"unterminated = \"is fine\n"
"but = produces a warning\n"
- "newlines = \"can either be encoded\\nor\\\n"
+ "newlines = \"can either be encoded\\nor \\\n"
"escaped\"\n"
"quotes = \"\\\"and\\\" slashes \\\\ can \\\\ be\" # escaped too\n"
"multiple = \"strings\" are \"combined\"\n"
@@ -922,7 +922,7 @@ START_TEST(test_strings)
verify_string("all { special } characters # can be used.", "special");
verify_string("is fine", "unterminated");
verify_string("produces a warning", "but");
- verify_string("can either be encoded\nor\nescaped", "newlines");
+ verify_string("can either be encoded\nor escaped", "newlines");
verify_string("\"and\" slashes \\ can \\ be", "quotes");
verify_string("strings are combined", "multiple");
}
diff --git a/src/libstrongswan/tests/suites/test_threading.c b/src/libstrongswan/tests/suites/test_threading.c
index 47e448484..55a4cd797 100644
--- a/src/libstrongswan/tests/suites/test_threading.c
+++ b/src/libstrongswan/tests/suites/test_threading.c
@@ -553,6 +553,49 @@ START_TEST(test_rwlock)
}
END_TEST
+static void *rwlock_try_run(void *param)
+{
+ if (rwlock->try_write_lock(rwlock))
+ {
+ rwlock->unlock(rwlock);
+ return param;
+ }
+ return NULL;
+}
+
+START_TEST(test_rwlock_try)
+{
+ uintptr_t magic = 0xcafebabe;
+ thread_t *thread;
+
+ rwlock = rwlock_create(RWLOCK_TYPE_DEFAULT);
+
+ thread = thread_create(rwlock_try_run, (void*)magic);
+ ck_assert_int_eq((uintptr_t)thread->join(thread), magic);
+
+ rwlock->read_lock(rwlock);
+ thread = thread_create(rwlock_try_run, (void*)magic);
+ ck_assert(thread->join(thread) == NULL);
+ rwlock->unlock(rwlock);
+
+ rwlock->read_lock(rwlock);
+ rwlock->read_lock(rwlock);
+ rwlock->read_lock(rwlock);
+ thread = thread_create(rwlock_try_run, (void*)magic);
+ ck_assert(thread->join(thread) == NULL);
+ rwlock->unlock(rwlock);
+ rwlock->unlock(rwlock);
+ rwlock->unlock(rwlock);
+
+ rwlock->write_lock(rwlock);
+ thread = thread_create(rwlock_try_run, (void*)magic);
+ ck_assert(thread->join(thread) == NULL);
+ rwlock->unlock(rwlock);
+
+ rwlock->destroy(rwlock);
+}
+END_TEST
+
/**
* Rwlock condvar
*/
@@ -1132,6 +1175,191 @@ START_TEST(test_cancel_point)
}
END_TEST
+static void close_fd_ptr(void *fd)
+{
+ close(*(int*)fd);
+}
+
+static void cancellation_recv()
+{
+ int sv[2];
+ char buf[1];
+
+ ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
+
+ thread_cleanup_push(close_fd_ptr, &sv[0]);
+ thread_cleanup_push(close_fd_ptr, &sv[1]);
+
+ thread_cancelability(TRUE);
+ while (TRUE)
+ {
+ ck_assert(recv(sv[0], buf, sizeof(buf), 0) == 1);
+ }
+}
+
+static void cancellation_read()
+{
+ int sv[2];
+ char buf[1];
+
+ ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
+
+ thread_cleanup_push(close_fd_ptr, &sv[0]);
+ thread_cleanup_push(close_fd_ptr, &sv[1]);
+
+ thread_cancelability(TRUE);
+ while (TRUE)
+ {
+ ck_assert(read(sv[0], buf, sizeof(buf)) == 1);
+ }
+}
+
+static void cancellation_select()
+{
+ int sv[2];
+ fd_set set;
+
+ ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
+
+ thread_cleanup_push(close_fd_ptr, &sv[0]);
+ thread_cleanup_push(close_fd_ptr, &sv[1]);
+
+ FD_ZERO(&set);
+ FD_SET(sv[0], &set);
+ thread_cancelability(TRUE);
+ while (TRUE)
+ {
+ ck_assert(select(sv[0] + 1, &set, NULL, NULL, NULL) == 1);
+ }
+}
+
+static void cancellation_poll()
+{
+ int sv[2];
+ struct pollfd pfd;
+
+ ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
+
+ thread_cleanup_push(close_fd_ptr, &sv[0]);
+ thread_cleanup_push(close_fd_ptr, &sv[1]);
+
+ pfd.fd = sv[0];
+ pfd.events = POLLIN;
+ thread_cancelability(TRUE);
+ while (TRUE)
+ {
+ ck_assert(poll(&pfd, 1, -1) == 1);
+ }
+}
+
+static void cancellation_accept()
+{
+ host_t *host;
+ int fd, c;
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ ck_assert(fd >= 0);
+ host = host_create_from_string("127.0.0.1", 0);
+ ck_assert_msg(bind(fd, host->get_sockaddr(host),
+ *host->get_sockaddr_len(host)) == 0, "%m");
+ host->destroy(host);
+ ck_assert(listen(fd, 5) == 0);
+
+ thread_cleanup_push(close_fd_ptr, &fd);
+
+ thread_cancelability(TRUE);
+ while (TRUE)
+ {
+ c = accept(fd, NULL, NULL);
+ ck_assert(c >= 0);
+ close(c);
+ }
+}
+
+static void cancellation_cond()
+{
+ mutex_t *mutex;
+ condvar_t *cond;
+
+ mutex = mutex_create(MUTEX_TYPE_DEFAULT);
+ cond = condvar_create(CONDVAR_TYPE_DEFAULT);
+ mutex->lock(mutex);
+
+ thread_cleanup_push((void*)mutex->destroy, mutex);
+ thread_cleanup_push((void*)cond->destroy, cond);
+
+ thread_cancelability(TRUE);
+ while (TRUE)
+ {
+ cond->wait(cond, mutex);
+ }
+}
+
+static void cancellation_rwcond()
+{
+ rwlock_t *lock;
+ rwlock_condvar_t *cond;
+
+ lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
+ cond = rwlock_condvar_create();
+ lock->write_lock(lock);
+
+ thread_cleanup_push((void*)lock->destroy, lock);
+ thread_cleanup_push((void*)cond->destroy, cond);
+
+ thread_cancelability(TRUE);
+ while (TRUE)
+ {
+ cond->wait(cond, lock);
+ }
+}
+
+static void (*cancellation_points[])() = {
+ cancellation_read,
+ cancellation_recv,
+ cancellation_select,
+ cancellation_poll,
+ cancellation_accept,
+ cancellation_cond,
+ cancellation_rwcond,
+};
+
+static void* run_cancellation_point(void (*fn)())
+{
+ fn();
+ return NULL;
+}
+
+static void* run_cancellation_point_pre(void (*fn)())
+{
+ usleep(5000);
+ fn();
+ return NULL;
+}
+
+START_TEST(test_cancellation_point)
+{
+ thread_t *thread;
+
+ thread = thread_create((void*)run_cancellation_point,
+ cancellation_points[_i]);
+ usleep(5000);
+ thread->cancel(thread);
+ thread->join(thread);
+}
+END_TEST
+
+START_TEST(test_cancellation_point_pre)
+{
+ thread_t *thread;
+
+ thread = thread_create((void*)run_cancellation_point_pre,
+ cancellation_points[_i]);
+ thread->cancel(thread);
+ thread->join(thread);
+}
+END_TEST
+
static void cleanup1(void *data)
{
uintptr_t *value = (uintptr_t*)data;
@@ -1423,6 +1651,7 @@ Suite *threading_suite_create()
tc = tcase_create("rwlock");
tcase_add_test(tc, test_rwlock);
+ tcase_add_test(tc, test_rwlock_try);
suite_add_tcase(s, tc);
tc = tcase_create("rwlock condvar");
@@ -1456,6 +1685,13 @@ Suite *threading_suite_create()
tcase_add_test(tc, test_cancel_point);
suite_add_tcase(s, tc);
+ tc = tcase_create("thread cancellation point");
+ tcase_add_loop_test(tc, test_cancellation_point,
+ 0, countof(cancellation_points));
+ tcase_add_loop_test(tc, test_cancellation_point_pre,
+ 0, countof(cancellation_points));
+ suite_add_tcase(s, tc);
+
tc = tcase_create("thread cleanup");
tcase_add_test(tc, test_cleanup);
tcase_add_test(tc, test_cleanup_exit);
diff --git a/src/libstrongswan/tests/suites/test_traffic_selector.c b/src/libstrongswan/tests/suites/test_traffic_selector.c
new file mode 100644
index 000000000..4312c6ce1
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_traffic_selector.c
@@ -0,0 +1,284 @@
+/*
+ * 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 "test_suite.h"
+
+#include <selectors/traffic_selector.h>
+
+
+static void verify(const char *str, const char *alt, traffic_selector_t *ts)
+{
+ char buf[512];
+
+ ck_assert(ts != NULL);
+ snprintf(buf, sizeof(buf), "%R", ts);
+ ts->destroy(ts);
+ if (!streq(buf, str) && !streq(buf, alt))
+ {
+ fail("%s != %s or %s", buf, str, alt);
+ }
+}
+
+START_TEST(test_create_from_string)
+{
+ verify("10.1.0.0/16[tcp/http]", "10.1.0.0/16[6/80]",
+ traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV4_ADDR_RANGE,
+ "10.1.0.0", 80, "10.1.255.255", 80));
+ verify("10.1.0.1..10.1.0.99[udp/1234-1235]",
+ "10.1.0.1..10.1.0.99[17/1234-1235]",
+ traffic_selector_create_from_string(IPPROTO_UDP, TS_IPV4_ADDR_RANGE,
+ "10.1.0.1", 1234, "10.1.0.99", 1235));
+ verify("fec1::/64", NULL,
+ traffic_selector_create_from_string(0, TS_IPV6_ADDR_RANGE,
+ "fec1::", 0, "fec1::ffff:ffff:ffff:ffff", 65535));
+}
+END_TEST
+
+START_TEST(test_create_from_cidr)
+{
+ verify("10.1.0.0/16", NULL,
+ traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535));
+ verify("10.1.0.1/32[udp/1234-1235]", "10.1.0.1/32[17/1234-1235]",
+ traffic_selector_create_from_cidr("10.1.0.1/32", IPPROTO_UDP,
+ 1234, 1235));
+}
+END_TEST
+
+START_TEST(test_create_from_bytes)
+{
+ verify("10.1.0.0/16", NULL,
+ traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE,
+ chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
+ chunk_from_chars(0x0a,0x01,0xff,0xff), 65535));
+}
+END_TEST
+
+START_TEST(test_create_from_subnet)
+{
+ verify("10.1.0.0/16", NULL,
+ traffic_selector_create_from_subnet(
+ host_create_from_string("10.1.0.0", 0), 16, 0, 0, 65535));
+}
+END_TEST
+
+
+START_TEST(test_subset)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
+ b = traffic_selector_create_from_cidr("10.1.5.0/24", 0, 0, 65535);
+ verify("10.1.5.0/24", NULL, a->get_subset(a, b));
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_port)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr("10.0.0.0/8", IPPROTO_TCP, 55, 60);
+ b = traffic_selector_create_from_cidr("10.2.7.16/30", 0, 0, 65535);
+ verify("10.2.7.16/30[tcp/55-60]", "10.2.7.16/30[6/55-60]",
+ a->get_subset(a, b));
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_equal)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 80, 80);
+ b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 80, 80);
+ verify("10.1.0.0/16[tcp/http]", "10.1.0.0/16[6/80]", a->get_subset(a, b));
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_nonet)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
+ b = traffic_selector_create_from_cidr("10.2.0.0/16", 0, 0, 65535);
+ ck_assert(a->get_subset(a, b) == NULL);
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_noport)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 9999);
+ b = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 10000, 65535);
+ ck_assert(a->get_subset(a, b) == NULL);
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_noproto)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 0, 65535);
+ b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_UDP, 0, 65535);
+ ck_assert(a->get_subset(a, b) == NULL);
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_nofamily)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
+ b = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
+ ck_assert(a->get_subset(a, b) == NULL);
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+struct {
+ char *net;
+ char *host;
+ bool inc;
+} include_tests[] = {
+ { "0.0.0.0/0", "192.168.1.2", TRUE },
+ { "::/0", "fec2::1", TRUE },
+ { "fec2::/64", "fec2::afaf", TRUE },
+ { "10.1.0.0/16", "10.1.0.1", TRUE },
+ { "10.5.6.7/32", "10.5.6.7", TRUE },
+ { "0.0.0.0/0", "fec2::1", FALSE },
+ { "::/0", "1.2.3.4", FALSE },
+ { "10.0.0.0/16", "10.1.0.0", FALSE },
+ { "fec2::/64", "fec2:0:0:1::afaf", FALSE },
+};
+
+START_TEST(test_includes)
+{
+ traffic_selector_t *ts;
+ host_t *h;
+
+ ts = traffic_selector_create_from_cidr(include_tests[_i].net, 0, 0, 65535);
+ h = host_create_from_string(include_tests[_i].host, 0);
+ ck_assert(ts->includes(ts, h) == include_tests[_i].inc);
+ ts->destroy(ts);
+ h->destroy(h);
+}
+END_TEST
+
+struct {
+ int res;
+ struct {
+ char *net;
+ u_int8_t proto;
+ u_int16_t from_port;
+ u_int16_t to_port;
+ } a, b;
+} cmp_tests[] = {
+ { 0, { "10.0.0.0/8", 0, 0, 65535 }, { "10.0.0.0/8", 0, 0, 65535 }, },
+ { 0, { "10.0.0.0/8", 17, 123, 456 }, { "10.0.0.0/8", 17, 123, 456 }, },
+ { 0, { "fec2::/64", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, },
+ { 0, { "fec2::/64", 4, 0, 65535 }, { "fec2::/64", 4, 0, 65535 }, },
+
+ { -1, { "1.0.0.0/8", 0, 0, 65535 }, { "2.0.0.0/8", 0, 0, 65535 }, },
+ { 1, { "2.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, },
+ { -1, { "1.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/16", 0, 0, 65535 }, },
+ { 1, { "1.0.0.0/16", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, },
+
+ { -1, { "10.0.0.0/8", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, },
+ { 1, { "fec2::/64", 0, 0, 65535 }, { "10.0.0.0/8", 0, 0, 65535 }, },
+
+ { -1, { "10.0.0.0/8", 16, 123, 456 }, { "10.0.0.0/8", 17, 123, 456 }, },
+ { 1, { "fec2::/64", 5, 0, 65535 }, { "fec2::/64", 4, 0, 65535 }, },
+
+ { -1, { "10.0.0.0/8", 17, 111, 456 }, { "10.0.0.0/8", 17, 222, 456 }, },
+ { 1, { "fec2::/64", 17, 555, 65535 }, { "fec2::/64", 17, 444, 65535 },},
+
+ { -1, { "10.0.0.0/8", 17, 55, 65535 }, { "10.0.0.0/8", 17, 55, 666 }, },
+ { 1, { "fec2::/64", 17, 55, 111 }, { "fec2::/64", 17, 55, 4567 }, },
+
+};
+
+START_TEST(test_cmp)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr(
+ cmp_tests[_i].a.net, cmp_tests[_i].a.proto,
+ cmp_tests[_i].a.from_port, cmp_tests[_i].a.to_port);
+ b = traffic_selector_create_from_cidr(
+ cmp_tests[_i].b.net, cmp_tests[_i].b.proto,
+ cmp_tests[_i].b.from_port, cmp_tests[_i].b.to_port);
+ switch (cmp_tests[_i].res)
+ {
+ case 0:
+ ck_assert(traffic_selector_cmp(a, b, NULL) == 0);
+ break;
+ case 1:
+ ck_assert(traffic_selector_cmp(a, b, NULL) > 0);
+ break;
+ case -1:
+ ck_assert(traffic_selector_cmp(a, b, NULL) < 0);
+ break;
+ }
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+Suite *traffic_selector_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("traffic selector");
+
+ tc = tcase_create("create");
+ tcase_add_test(tc, test_create_from_string);
+ tcase_add_test(tc, test_create_from_cidr);
+ tcase_add_test(tc, test_create_from_bytes);
+ tcase_add_test(tc, test_create_from_subnet);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("subset");
+ tcase_add_test(tc, test_subset);
+ tcase_add_test(tc, test_subset_port);
+ tcase_add_test(tc, test_subset_equal);
+ tcase_add_test(tc, test_subset_nonet);
+ tcase_add_test(tc, test_subset_noport);
+ tcase_add_test(tc, test_subset_noproto);
+ tcase_add_test(tc, test_subset_nofamily);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("includes");
+ tcase_add_loop_test(tc, test_includes, 0, countof(include_tests));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("cmp");
+ tcase_add_loop_test(tc, test_cmp, 0, countof(cmp_tests));
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/tests/suites/test_utils.c b/src/libstrongswan/tests/suites/test_utils.c
index abca4620e..85a854456 100644
--- a/src/libstrongswan/tests/suites/test_utils.c
+++ b/src/libstrongswan/tests/suites/test_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2013-2015 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,6 +18,7 @@
#include <library.h>
#include <utils/utils.h>
#include <ipsec/ipsec_types.h>
+#include <credentials/keys/public_key.h>
#include <time.h>
@@ -695,6 +696,44 @@ START_TEST(test_mark_from_string)
}
END_TEST
+/*******************************************************************************
+ * signature_schemes_for_key
+ */
+
+static struct {
+ key_type_t type;
+ int size;
+ signature_scheme_t expected[4];
+} scheme_data[] = {
+ {KEY_RSA, 1024, { SIGN_RSA_EMSA_PKCS1_SHA256, SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }},
+ {KEY_RSA, 2048, { SIGN_RSA_EMSA_PKCS1_SHA256, SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }},
+ {KEY_RSA, 4096, { SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }},
+ {KEY_RSA, 8192, { SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }},
+ {KEY_ECDSA, 256, { SIGN_ECDSA_WITH_SHA256_DER, SIGN_ECDSA_WITH_SHA384_DER, SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }},
+ {KEY_ECDSA, 384, { SIGN_ECDSA_WITH_SHA384_DER, SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }},
+ {KEY_ECDSA, 512, { SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }},
+ {KEY_BLISS, 128, { SIGN_BLISS_WITH_SHA256, SIGN_BLISS_WITH_SHA384, SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }},
+ {KEY_BLISS, 192, { SIGN_BLISS_WITH_SHA384, SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }},
+ {KEY_BLISS, 256, { SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }},
+};
+
+START_TEST(test_signature_schemes_for_key)
+{
+ enumerator_t *enumerator;
+ signature_scheme_t scheme;
+ int i;
+
+ enumerator = signature_schemes_for_key(scheme_data[_i].type, scheme_data[_i].size);
+ for (i = 0; scheme_data[_i].expected[i] != SIGN_UNKNOWN; i++)
+ {
+ ck_assert(enumerator->enumerate(enumerator, &scheme));
+ ck_assert_int_eq(scheme_data[_i].expected[i], scheme);
+ }
+ ck_assert(!enumerator->enumerate(enumerator, &scheme));
+ enumerator->destroy(enumerator);
+}
+END_TEST
+
Suite *utils_suite_create()
{
Suite *s;
@@ -777,5 +816,9 @@ Suite *utils_suite_create()
tcase_add_loop_test(tc, test_mark_from_string, 0, countof(mark_data));
suite_add_tcase(s, tc);
+ tc = tcase_create("signature_schemes_for_key");
+ tcase_add_loop_test(tc, test_signature_schemes_for_key, 0, countof(scheme_data));
+ suite_add_tcase(s, tc);
+
return s;
}
diff --git a/src/libstrongswan/tests/tests.h b/src/libstrongswan/tests/tests.h
index 586227800..e1d8ca4ba 100644
--- a/src/libstrongswan/tests/tests.h
+++ b/src/libstrongswan/tests/tests.h
@@ -23,6 +23,7 @@ TEST_SUITE(linked_list_enumerator_suite_create)
TEST_SUITE(hashtable_suite_create)
TEST_SUITE(array_suite_create)
TEST_SUITE(identification_suite_create)
+TEST_SUITE(traffic_selector_suite_create)
TEST_SUITE(threading_suite_create)
TEST_SUITE(process_suite_create)
TEST_SUITE(watcher_suite_create)
@@ -32,6 +33,8 @@ TEST_SUITE(settings_suite_create)
TEST_SUITE(vectors_suite_create)
TEST_SUITE_DEPEND(ecdsa_suite_create, PRIVKEY_GEN, KEY_ECDSA)
TEST_SUITE_DEPEND(rsa_suite_create, PRIVKEY_GEN, KEY_RSA)
+TEST_SUITE_DEPEND(certpolicy_suite_create, CERT_ENCODE, CERT_X509)
+TEST_SUITE_DEPEND(certnames_suite_create, CERT_ENCODE, CERT_X509)
TEST_SUITE(host_suite_create)
TEST_SUITE(printf_suite_create)
TEST_SUITE(hasher_suite_create)
@@ -41,5 +44,7 @@ TEST_SUITE(pen_suite_create)
TEST_SUITE(asn1_suite_create)
TEST_SUITE(asn1_parser_suite_create)
TEST_SUITE(test_rng_suite_create)
+TEST_SUITE_DEPEND(mgf1_sha1_suite_create, HASHER, HASH_SHA1)
+TEST_SUITE_DEPEND(mgf1_sha256_suite_create, HASHER, HASH_SHA256)
TEST_SUITE_DEPEND(ntru_suite_create, DH, NTRU_112_BIT)
TEST_SUITE_DEPEND(fetch_http_suite_create, FETCHER, "http://")
diff --git a/src/libstrongswan/threading/semaphore.h b/src/libstrongswan/threading/semaphore.h
index 34d814971..d3ab0f3d9 100644
--- a/src/libstrongswan/threading/semaphore.h
+++ b/src/libstrongswan/threading/semaphore.h
@@ -21,10 +21,7 @@
#ifndef THREADING_SEMAPHORE_H_
#define THREADING_SEMAPHORE_H_
-#ifdef __APPLE__
-/* Mach uses a semaphore_create() call, use a different name for ours */
-#define semaphore_create(x) strongswan_semaphore_create(x)
-#endif /* __APPLE__ */
+#include <utils/utils.h>
typedef struct semaphore_t semaphore_t;
@@ -87,4 +84,3 @@ struct semaphore_t {
semaphore_t *semaphore_create(u_int value);
#endif /** THREADING_SEMAPHORE_H_ @} */
-
diff --git a/src/libstrongswan/threading/thread.h b/src/libstrongswan/threading/thread.h
index 6abb83411..38275541e 100644
--- a/src/libstrongswan/threading/thread.h
+++ b/src/libstrongswan/threading/thread.h
@@ -21,40 +21,9 @@
#ifndef THREADING_THREAD_H_
#define THREADING_THREAD_H_
-typedef struct thread_t thread_t;
-
-#ifdef __APPLE__
-/* thread_create is a syscall used to create Mach kernel threads and although
- * there are no errors or warnings during compilation or linkage the dynamic
- * linker does not use our implementation, therefore we rename it here
- */
-#define thread_create(main, arg) strongswan_thread_create(main, arg)
+#include <utils/utils.h>
-/* on Mac OS X 10.5 several system calls we use are no cancellation points.
- * fortunately, select isn't one of them, so we wrap some of the others with
- * calls to select(2).
- */
-#include <sys/socket.h>
-#include <sys/select.h>
-
-#define WRAP_WITH_SELECT(func, socket, ...)\
- fd_set rfds; FD_ZERO(&rfds); FD_SET(socket, &rfds);\
- if (select(socket + 1, &rfds, NULL, NULL, NULL) <= 0) { return -1; }\
- return func(socket, __VA_ARGS__)
-
-static inline int cancellable_accept(int socket, struct sockaddr *address,
- socklen_t *address_len)
-{
- WRAP_WITH_SELECT(accept, socket, address, address_len);
-}
-#define accept cancellable_accept
-static inline int cancellable_recvfrom(int socket, void *buffer, size_t length,
- int flags, struct sockaddr *address, socklen_t *address_len)
-{
- WRAP_WITH_SELECT(recvfrom, socket, buffer, length, flags, address, address_len);
-}
-#define recvfrom cancellable_recvfrom
-#endif /* __APPLE__ */
+typedef struct thread_t thread_t;
/**
* Main function of a thread.
@@ -189,32 +158,4 @@ void threads_init();
*/
void threads_deinit();
-
-#ifdef __APPLE__
-
-/*
- * While select() is a cancellation point, it seems that OS X does not honor
- * pending cancellation points when entering the function. We manually test for
- * and honor pending cancellation requests, but this obviously can't prevent
- * some race conditions where the the cancellation happens after the check,
- * but before the select.
- */
-static inline int precancellable_select(int nfds, fd_set *restrict readfds,
- fd_set *restrict writefds, fd_set *restrict errorfds,
- struct timeval *restrict timeout)
-{
- if (thread_cancelability(TRUE))
- {
- thread_cancellation_point();
- }
- else
- {
- thread_cancelability(FALSE);
- }
- return select(nfds, readfds, writefds, errorfds, timeout);
-}
-#define select precancellable_select
-
-#endif /* __APPLE__ */
-
#endif /** THREADING_THREAD_H_ @} */
diff --git a/src/libstrongswan/threading/windows/rwlock.c b/src/libstrongswan/threading/windows/rwlock.c
index 0de57f713..fc0d6d864 100644
--- a/src/libstrongswan/threading/windows/rwlock.c
+++ b/src/libstrongswan/threading/windows/rwlock.c
@@ -85,8 +85,6 @@ METHOD(rwlock_t, write_lock, void,
METHOD(rwlock_t, try_write_lock, bool,
private_rwlock_t *this)
{
- /* TODO: causes random failures and segfaults. Bug? */
- return FALSE;
return TryAcquireSRWLockExclusive(&this->srw);
}
diff --git a/src/libstrongswan/utils/chunk.c b/src/libstrongswan/utils/chunk.c
index 4b24b37c2..c4471be70 100644
--- a/src/libstrongswan/utils/chunk.c
+++ b/src/libstrongswan/utils/chunk.c
@@ -992,7 +992,7 @@ u_int32_t chunk_hash_static(chunk_t chunk)
*/
u_int16_t chunk_internet_checksum_inc(chunk_t data, u_int16_t checksum)
{
- u_int32_t sum = ntohs(~checksum);
+ u_int32_t sum = ntohs((u_int16_t)~checksum);
while (data.len > 1)
{
diff --git a/src/libstrongswan/utils/compat/apple.h b/src/libstrongswan/utils/compat/apple.h
new file mode 100644
index 000000000..61afb9d9e
--- /dev/null
+++ b/src/libstrongswan/utils/compat/apple.h
@@ -0,0 +1,119 @@
+/*
+ * 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 apple apple
+ * @{ @ingroup compat
+ */
+
+#ifndef APPLE_H_
+#define APPLE_H_
+
+#include <poll.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+
+/* thread_create is a syscall used to create Mach kernel threads and although
+ * there are no errors or warnings during compilation or linkage the dynamic
+ * linker does not use our implementation, therefore we rename it here
+ */
+#define thread_create(main, arg) strongswan_thread_create(main, arg)
+
+/* Mach uses a semaphore_create() call, use a different name for ours */
+#define semaphore_create(x) strongswan_semaphore_create(x)
+
+/* Since OS X 10.10 XPC includes some additional conflicting Mach types */
+#define host_t strongswan_host_t
+#define processor_t strongswan_processor_t
+#define task_t strongswan_task_t
+#define thread_t strongswan_thread_t
+
+/* forward declaration, see below */
+static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds,
+ int timeout);
+
+/* on Mac OS X 10.5 several system calls we use are no cancellation points.
+ * fortunately, select isn't one of them, so we wrap some of the others with
+ * calls to select(2).
+ */
+
+#define WRAP_WITH_POLL(func, socket, ...) \
+ struct pollfd pfd = { \
+ .fd = socket, \
+ .events = POLLIN, \
+ }; \
+ if (precancellable_poll(&pfd, 1, -1) <= 0) \
+ {\
+ return -1; \
+ }\
+ return func(socket, __VA_ARGS__)
+
+static inline int cancellable_accept(int socket, struct sockaddr *address,
+ socklen_t *address_len)
+{
+ WRAP_WITH_POLL(accept, socket, address, address_len);
+}
+#define accept cancellable_accept
+static inline int cancellable_recvfrom(int socket, void *buffer, size_t length,
+ int flags, struct sockaddr *address, socklen_t *address_len)
+{
+ WRAP_WITH_POLL(recvfrom, socket, buffer, length, flags, address, address_len);
+}
+#define recvfrom cancellable_recvfrom
+
+#include <threading/thread.h>
+
+/*
+ * While select() is a cancellation point, it seems that OS X does not honor
+ * pending cancellation points when entering the function. We manually test for
+ * and honor pending cancellation requests, but this obviously can't prevent
+ * some race conditions where the the cancellation happens after the check,
+ * but before the select.
+ */
+static inline int precancellable_select(int nfds, fd_set *restrict readfds,
+ fd_set *restrict writefds, fd_set *restrict errorfds,
+ struct timeval *restrict timeout)
+{
+ if (thread_cancelability(TRUE))
+ {
+ thread_cancellation_point();
+ }
+ else
+ {
+ thread_cancelability(FALSE);
+ }
+ return select(nfds, readfds, writefds, errorfds, timeout);
+}
+#define select precancellable_select
+
+/*
+ * The same as to select(2) applies to poll(2)
+ */
+static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds,
+ int timeout)
+{
+ if (thread_cancelability(TRUE))
+ {
+ thread_cancellation_point();
+ }
+ else
+ {
+ thread_cancelability(FALSE);
+ }
+ return poll(fds, nfds, timeout);
+}
+#define poll precancellable_poll
+
+#endif /** APPLE_H_ @}*/
diff --git a/src/libstrongswan/utils/windows.c b/src/libstrongswan/utils/compat/windows.c
index 8820287b1..1f22ffa02 100644
--- a/src/libstrongswan/utils/windows.c
+++ b/src/libstrongswan/utils/compat/windows.c
@@ -13,7 +13,10 @@
* for more details.
*/
-#include "utils.h"
+/* WSAPoll() */
+#define _WIN32_WINNT 0x0600
+
+#include <utils/utils.h>
#include <errno.h>
@@ -639,3 +642,43 @@ ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
}
return outlen;
}
+
+/**
+ * See header
+ */
+#undef read
+ssize_t windows_read(int fd, void *buf, size_t count)
+{
+ ssize_t ret;
+
+ ret = wserr(recv(fd, buf, count, 0));
+ if (ret == -1 && errno == ENOTSOCK)
+ {
+ ret = read(fd, buf, count);
+ }
+ return ret;
+}
+
+/**
+ * See header
+ */
+#undef write
+ssize_t windows_write(int fd, void *buf, size_t count)
+{
+ ssize_t ret;
+
+ ret = wserr(send(fd, buf, count, 0));
+ if (ret == -1 && errno == ENOTSOCK)
+ {
+ ret = write(fd, buf, count);
+ }
+ return ret;
+}
+
+/**
+ * See header
+ */
+int poll(struct pollfd *fds, int nfds, int timeout)
+{
+ return wserr(WSAPoll(fds, nfds, timeout));
+}
diff --git a/src/libstrongswan/utils/windows.h b/src/libstrongswan/utils/compat/windows.h
index 3761e10ab..fd4f1f196 100644
--- a/src/libstrongswan/utils/windows.h
+++ b/src/libstrongswan/utils/compat/windows.h
@@ -15,7 +15,7 @@
/**
* @defgroup windows windows
- * @{ @ingroup utils
+ * @{ @ingroup compat
*/
#ifndef WINDOWS_H_
@@ -363,6 +363,49 @@ ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
/**
+ * read(2) working on files and sockets, cancellable on sockets only
+ *
+ * On Windows, there does not seem to be a way how a cancellable read can
+ * be implemented on Low level I/O functions for files, _pipe()s or stdio.
+ */
+#define read windows_read
+ssize_t windows_read(int fd, void *buf, size_t count);
+
+/**
+ * write(2) working on files and sockets
+ */
+#define write windows_write
+ssize_t windows_write(int fd, void *buf, size_t count);
+
+#if _WIN32_WINNT < 0x0600
+/**
+ * Define pollfd and flags on our own if not specified
+ */
+struct pollfd {
+ SOCKET fd;
+ short events;
+ short revents;
+};
+enum {
+ POLLERR = 0x0001,
+ POLLHUP = 0x0002,
+ POLLNVAL = 0x0004,
+ POLLWRNORM = 0x0010,
+ POLLWRBAND = 0x0020,
+ POLLPRI = 0x0400,
+ POLLRDNORM = 0x0100,
+ POLLRDBAND = 0x0200,
+ POLLIN = POLLRDNORM | POLLRDBAND,
+ POLLOUT = POLLWRNORM,
+};
+#endif /* _WIN32_WINNT < 0x0600 */
+
+/**
+ * poll(2), implemented using Winsock2 WSAPoll()
+ */
+int poll(struct pollfd *fds, int nfds, int timeout);
+
+/**
* Declaration missing on older WinGW
*/
_CRTIMP errno_t strerror_s(char *buf, size_t size, int errnum);
diff --git a/src/libstrongswan/utils/enum.c b/src/libstrongswan/utils/enum.c
index f96fe2989..089bebb79 100644
--- a/src/libstrongswan/utils/enum.c
+++ b/src/libstrongswan/utils/enum.c
@@ -60,20 +60,103 @@ bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val)
}
/**
+ * Get the position of a flag name using offset calculation
+ */
+static int find_flag_pos(u_int val, u_int first)
+{
+ int offset = 0;
+
+ while (val != 0x01)
+ {
+ val = val >> 1;
+ offset++;
+ }
+ return first - offset;
+}
+
+/**
* Described in header.
*/
+char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len)
+{
+ char *pos = buf, *delim = "";
+ int i, wr;
+
+ if (e->next != ENUM_FLAG_MAGIC)
+ {
+ if (snprintf(buf, len, "(%d)", (int)val) >= len)
+ {
+ return NULL;
+ }
+ return buf;
+ }
+
+ if (snprintf(buf, len, "(unset)") >= len)
+ {
+ return NULL;
+ }
+
+ for (i = 0; val; i++)
+ {
+ u_int flag = 1 << i;
+
+ if (val & flag)
+ {
+ char *name = NULL, hex[32];
+
+ if (flag >= (u_int)e->first && flag <= (u_int)e->last)
+ {
+ name = e->names[find_flag_pos(e->first, i)];
+ }
+ else
+ {
+ snprintf(hex, sizeof(hex), "(0x%X)", flag);
+ name = hex;
+ }
+ if (name)
+ {
+ wr = snprintf(pos, len, "%s%s", delim, name);
+ if (wr >= len)
+ {
+ return NULL;
+ }
+ len -= wr;
+ pos += wr;
+ delim = " | ";
+ }
+ val &= ~flag;
+ }
+ }
+ return buf;
+}
+
+/**
+ * See header.
+ */
int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
const void *const *args)
{
enum_name_t *ed = *((enum_name_t**)(args[0]));
int val = *((int*)(args[1]));
- char *name, buf[32];
+ char *name, buf[512];
- name = enum_to_name(ed, val);
- if (name == NULL)
+ if (ed->next == ENUM_FLAG_MAGIC)
+ {
+ name = enum_flags_to_string(ed, val, buf, sizeof(buf));
+ if (name == NULL)
+ {
+ snprintf(buf, sizeof(buf), "(0x%X)", val);
+ name = buf;
+ }
+ }
+ else
{
- snprintf(buf, sizeof(buf), "(%d)", val);
- name = buf;
+ name = enum_to_name(ed, val);
+ if (name == NULL)
+ {
+ snprintf(buf, sizeof(buf), "(%d)", val);
+ name = buf;
+ }
}
if (spec->minus)
{
diff --git a/src/libstrongswan/utils/enum.h b/src/libstrongswan/utils/enum.h
index 3c03c2a7b..928f4079a 100644
--- a/src/libstrongswan/utils/enum.h
+++ b/src/libstrongswan/utils/enum.h
@@ -27,6 +27,11 @@
typedef struct enum_name_t enum_name_t;
/**
+ * Magic enum_name_t pointer indicating this is an enum name for flags
+ */
+#define ENUM_FLAG_MAGIC ((enum_name_t*)~(uintptr_t)0)
+
+/**
* Struct to store names for enums.
*
* To print the string representation of enumeration values, the strings
@@ -58,7 +63,7 @@ struct enum_name_t {
int first;
/** value of the last enum string */
int last;
- /** next enum_name_t in list */
+ /** next enum_name_t in list, or ENUM_FLAG_MAGIC */
enum_name_t *next;
/** array of strings containing names from first to last */
char *names[];
@@ -107,6 +112,23 @@ struct enum_name_t {
#define ENUM(name, first, last, ...) ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last)
/**
+ * Define a enum name with only one range for flags.
+ *
+ * Using an enum list for flags would be overkill. Hence we use a single
+ * range with all values in range. The next pointer is abused to mark
+ * that the enum name is for flags only. Use NULL if a particular flag
+ * is not meant to be printed.
+ *
+ * @param name name of the enum_name list
+ * @param first enum value of the first enum string
+ * @param last enum value of the last enum string
+ * @param ... a list of strings
+ */
+#define ENUM_FLAGS(name, first, last, ...) \
+ static enum_name_t name##last = {first, last, ENUM_FLAG_MAGIC, { __VA_ARGS__ }}; \
+ ENUM_END(name, last)
+
+/**
* Convert a enum value to its string representation.
*
* @param e enum names for this enum value
@@ -146,6 +168,17 @@ char *enum_to_name(enum_name_t *e, int val);
bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val);
/**
+ * Convert a enum value containing flags to its string representation.
+ *
+ * @param e enum names for this enum value suitable for flags
+ * @param val enum value to get string for
+ * @param buf buffer to write flag string to
+ * @param len buffer size
+ * @return buf, NULL if buffer too small
+ */
+char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len);
+
+/**
* printf hook function for enum_names_t.
*
* Arguments are:
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index 46ac7e890..b69adf399 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -17,6 +17,7 @@
#include <string.h>
#include <stdio.h>
+#include <errno.h>
#include "identification.h"
@@ -927,6 +928,82 @@ static private_identification_t *identification_create(id_type_t type)
return this;
}
+/**
+ * Create an identity for a specific type, determined by prefix
+ */
+static private_identification_t* create_from_string_with_prefix_type(char *str)
+{
+ struct {
+ const char *str;
+ id_type_t type;
+ } prefixes[] = {
+ { "ipv4:", ID_IPV4_ADDR },
+ { "ipv6:", ID_IPV6_ADDR },
+ { "rfc822:", ID_RFC822_ADDR },
+ { "email:", ID_RFC822_ADDR },
+ { "userfqdn:", ID_USER_FQDN },
+ { "fqdn:", ID_FQDN },
+ { "dns:", ID_FQDN },
+ { "asn1dn:", ID_DER_ASN1_DN },
+ { "asn1gn:", ID_DER_ASN1_GN },
+ { "keyid:", ID_KEY_ID },
+ };
+ private_identification_t *this;
+ int i;
+
+ for (i = 0; i < countof(prefixes); i++)
+ {
+ if (strcasepfx(str, prefixes[i].str))
+ {
+ this = identification_create(prefixes[i].type);
+ str += strlen(prefixes[i].str);
+ if (*str == '#')
+ {
+ this->encoded = chunk_from_hex(chunk_from_str(str + 1), NULL);
+ }
+ else
+ {
+ this->encoded = chunk_clone(chunk_from_str(str));
+ }
+ return this;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Create an identity for a specific type, determined by a numerical prefix
+ *
+ * The prefix is of the form "{x}:", where x denotes the numerical identity
+ * type.
+ */
+static private_identification_t* create_from_string_with_num_type(char *str)
+{
+ private_identification_t *this;
+ u_long type;
+
+ if (*str++ != '{')
+ {
+ return NULL;
+ }
+ errno = 0;
+ type = strtoul(str, &str, 0);
+ if (errno || *str++ != '}' || *str++ != ':')
+ {
+ return NULL;
+ }
+ this = identification_create(type);
+ if (*str == '#')
+ {
+ this->encoded = chunk_from_hex(chunk_from_str(str + 1), NULL);
+ }
+ else
+ {
+ this->encoded = chunk_clone(chunk_from_str(str));
+ }
+ return this;
+}
+
/*
* Described in header.
*/
@@ -939,6 +1016,16 @@ identification_t *identification_create_from_string(char *string)
{
string = "%any";
}
+ this = create_from_string_with_prefix_type(string);
+ if (this)
+ {
+ return &this->public;
+ }
+ this = create_from_string_with_num_type(string);
+ if (this)
+ {
+ return &this->public;
+ }
if (strchr(string, '=') != NULL)
{
/* we interpret this as an ASCII X.501 ID_DER_ASN1_DN.
diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h
index e62446879..e6a9fe1c6 100644
--- a/src/libstrongswan/utils/identification.h
+++ b/src/libstrongswan/utils/identification.h
@@ -302,6 +302,15 @@ struct identification_t {
* N, G, I, dnQualifier, ID, EN, EmployeeNumber, E, Email, emailAddress, UN,
* unstructuredName, TCGID.
*
+ * To skip automatic type detection the following prefixes may be used to
+ * enforce a specific type: ipv4:, ipv6:, rfc822:, email:, userfqdn:, fqdn:,
+ * dns:, asn1dn:, asn1gn: and keyid:. If a # follows the :, the remaining data
+ * is interpreted as hex encoded binary data for that ID, otherwise the raw
+ * string following the prefix is used as identity data, without conversion.
+ * To specify a non-standard ID type, the numerical type may be prefixed
+ * between curly backets, building a prefix. For instance the "{1}:" prefix
+ * defines an ID_IPV4_ADDR type.
+ *
* This constructor never returns NULL. If it does not find a suitable
* conversion function, it will copy the string to an ID_KEY_ID.
*
diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h
index da253cc35..7c48d949f 100644
--- a/src/libstrongswan/utils/utils.h
+++ b/src/libstrongswan/utils/utils.h
@@ -29,7 +29,7 @@
#include <string.h>
#ifdef WIN32
-# include "windows.h"
+# include "compat/windows.h"
#else
# define _GNU_SOURCE
# include <arpa/inet.h>
@@ -37,6 +37,7 @@
# include <netdb.h>
# include <netinet/in.h>
# include <sched.h>
+# include <poll.h>
#endif
/**
@@ -96,6 +97,9 @@
#include "enum.h"
#include "utils/strerror.h"
+#ifdef __APPLE__
+# include "compat/apple.h"
+#endif
/**
* Directory separator character in paths on this platform
diff --git a/src/libtls/Makefile.in b/src/libtls/Makefile.in
index 426d8bcb3..e6c23d970 100644
--- a/src/libtls/Makefile.in
+++ b/src/libtls/Makefile.in
@@ -278,6 +278,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@
@@ -338,10 +339,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@
@@ -415,6 +418,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/libtls/tests/Makefile.in b/src/libtls/tests/Makefile.in
index 2e44fb4a5..7d5b3771c 100644
--- a/src/libtls/tests/Makefile.in
+++ b/src/libtls/tests/Makefile.in
@@ -223,6 +223,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@
@@ -283,10 +284,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@
@@ -360,6 +363,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/libtls/tls.c b/src/libtls/tls.c
index 6a8d5030c..08a06f5ef 100644
--- a/src/libtls/tls.c
+++ b/src/libtls/tls.c
@@ -415,6 +415,12 @@ METHOD(tls_t, get_eap_msk, chunk_t,
return this->crypto->get_eap_msk(this->crypto);
}
+METHOD(tls_t, get_auth, auth_cfg_t*,
+ private_tls_t *this)
+{
+ return this->handshake->get_auth(this->handshake);
+}
+
METHOD(tls_t, destroy, void,
private_tls_t *this)
{
@@ -465,6 +471,7 @@ tls_t *tls_create(bool is_server, identification_t *server,
.get_purpose = _get_purpose,
.is_complete = _is_complete,
.get_eap_msk = _get_eap_msk,
+ .get_auth = _get_auth,
.destroy = _destroy,
},
.is_server = is_server,
@@ -487,7 +494,7 @@ tls_t *tls_create(bool is_server, identification_t *server,
this->alert, peer, server)->handshake;
}
this->fragmentation = tls_fragmentation_create(this->handshake, this->alert,
- this->application);
+ this->application, purpose);
this->compression = tls_compression_create(this->fragmentation, this->alert);
this->protection = tls_protection_create(this->compression, this->alert);
this->crypto->set_protection(this->crypto, this->protection);
diff --git a/src/libtls/tls.h b/src/libtls/tls.h
index fc1d9b9fd..f3dc198cf 100644
--- a/src/libtls/tls.h
+++ b/src/libtls/tls.h
@@ -252,6 +252,13 @@ struct tls_t {
chunk_t (*get_eap_msk)(tls_t *this);
/**
+ * Get the authentication details after completing the handshake.
+ *
+ * @return authentication details, internal data
+ */
+ auth_cfg_t* (*get_auth)(tls_t *this);
+
+ /**
* Destroy a tls_t.
*/
void (*destroy)(tls_t *this);
diff --git a/src/libtls/tls_eap.c b/src/libtls/tls_eap.c
index ebe5bc3a8..12d5aed53 100644
--- a/src/libtls/tls_eap.c
+++ b/src/libtls/tls_eap.c
@@ -426,6 +426,12 @@ METHOD(tls_eap_t, set_identifier, void,
this->identifier = identifier;
}
+METHOD(tls_eap_t, get_auth, auth_cfg_t*,
+ private_tls_eap_t *this)
+{
+ return this->tls->get_auth(this->tls);
+}
+
METHOD(tls_eap_t, destroy, void,
private_tls_eap_t *this)
{
@@ -453,6 +459,7 @@ tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size,
.get_msk = _get_msk,
.get_identifier = _get_identifier,
.set_identifier = _set_identifier,
+ .get_auth = _get_auth,
.destroy = _destroy,
},
.type = type,
diff --git a/src/libtls/tls_eap.h b/src/libtls/tls_eap.h
index f3fbba078..df41fc4d7 100644
--- a/src/libtls/tls_eap.h
+++ b/src/libtls/tls_eap.h
@@ -77,6 +77,13 @@ struct tls_eap_t {
void (*set_identifier) (tls_eap_t *this, uint8_t identifier);
/**
+ * Get the authentication details after completing the handshake.
+ *
+ * @return authentication details, internal data
+ */
+ auth_cfg_t* (*get_auth)(tls_eap_t *this);
+
+ /**
* Destroy a tls_eap_t.
*/
void (*destroy)(tls_eap_t *this);
diff --git a/src/libtls/tls_fragmentation.c b/src/libtls/tls_fragmentation.c
index 6e4347e3c..a97ca1eaa 100644
--- a/src/libtls/tls_fragmentation.c
+++ b/src/libtls/tls_fragmentation.c
@@ -96,9 +96,32 @@ struct private_tls_fragmentation_t {
* Upper layer application data protocol
*/
tls_application_t *application;
+
+ /**
+ * Type of context this TLS instance runs in
+ */
+ tls_purpose_t purpose;
};
/**
+ * Check if we should send a close notify once the application finishes
+ */
+static bool send_close_notify(private_tls_fragmentation_t *this)
+{
+ switch (this->purpose)
+ {
+ case TLS_PURPOSE_EAP_TLS:
+ case TLS_PURPOSE_EAP_TTLS:
+ case TLS_PURPOSE_EAP_PEAP:
+ /* not for TLS-in-EAP, as we indicate completion with EAP-SUCCCESS.
+ * Windows does not like close notifies, and hangs/disconnects. */
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
+
+/**
* Process a TLS alert
*/
static status_t process_alert(private_tls_fragmentation_t *this,
@@ -223,6 +246,10 @@ static status_t process_application(private_tls_fragmentation_t *this,
continue;
case SUCCESS:
this->application_finished = TRUE;
+ if (!send_close_notify(this))
+ {
+ return SUCCESS;
+ }
/* FALL */
case FAILED:
default:
@@ -368,6 +395,10 @@ static status_t build_application(private_tls_fragmentation_t *this)
break;
case SUCCESS:
this->application_finished = TRUE;
+ if (!send_close_notify(this))
+ {
+ break;
+ }
/* FALL */
case FAILED:
default:
@@ -463,7 +494,8 @@ METHOD(tls_fragmentation_t, destroy, void,
* See header
*/
tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake,
- tls_alert_t *alert, tls_application_t *application)
+ tls_alert_t *alert, tls_application_t *application,
+ tls_purpose_t purpose)
{
private_tls_fragmentation_t *this;
@@ -478,6 +510,7 @@ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake,
.alert = alert,
.state = ALERT_NONE,
.application = application,
+ .purpose = purpose,
);
return &this->public;
diff --git a/src/libtls/tls_fragmentation.h b/src/libtls/tls_fragmentation.h
index f650e7be8..a49f27b20 100644
--- a/src/libtls/tls_fragmentation.h
+++ b/src/libtls/tls_fragmentation.h
@@ -80,9 +80,11 @@ struct tls_fragmentation_t {
* @param handshake upper layer handshake protocol
* @param alert TLS alert handler
* @param application upper layer application data or NULL
+ * @param purpose type of context this TLS stack is running in
* @return TLS fragmentation layer
*/
tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake,
- tls_alert_t *alert, tls_application_t *application);
+ tls_alert_t *alert, tls_application_t *application,
+ tls_purpose_t purpose);
#endif /** TLS_FRAGMENTATION_H_ @}*/
diff --git a/src/libtls/tls_handshake.h b/src/libtls/tls_handshake.h
index 7fa660c58..7edb49ba0 100644
--- a/src/libtls/tls_handshake.h
+++ b/src/libtls/tls_handshake.h
@@ -98,6 +98,13 @@ struct tls_handshake_t {
identification_t* (*get_server_id)(tls_handshake_t *this);
/**
+ * Get the peers authentication information after completing the handshake.
+ *
+ * @return authentication data, internal data
+ */
+ auth_cfg_t* (*get_auth)(tls_handshake_t *this);
+
+ /**
* Destroy a tls_handshake_t.
*/
void (*destroy)(tls_handshake_t *this);
diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c
index a95b40f55..e6be36b7b 100644
--- a/src/libtls/tls_peer.c
+++ b/src/libtls/tls_peer.c
@@ -312,7 +312,7 @@ static status_t process_certificate(private_tls_peer_t *this,
static public_key_t *find_public_key(private_tls_peer_t *this)
{
public_key_t *public = NULL, *current;
- certificate_t *cert;
+ certificate_t *cert, *found;
enumerator_t *enumerator;
auth_cfg_t *auth;
@@ -323,8 +323,13 @@ static public_key_t *find_public_key(private_tls_peer_t *this)
KEY_ANY, cert->get_subject(cert), this->server_auth);
while (enumerator->enumerate(enumerator, &current, &auth))
{
- public = current->get_ref(current);
- break;
+ found = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+ if (found && cert->equals(cert, found))
+ {
+ public = current->get_ref(current);
+ this->server_auth->merge(this->server_auth, auth, FALSE);
+ break;
+ }
}
enumerator->destroy(enumerator);
}
@@ -379,7 +384,12 @@ static status_t process_modp_key_exchange(private_tls_peer_t *this,
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
return NEED_MORE;
}
- this->dh->set_other_public_value(this->dh, pub);
+ if (!this->dh->set_other_public_value(this->dh, pub))
+ {
+ DBG1(DBG_TLS, "applying DH public value failed");
+ this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+ return NEED_MORE;
+ }
this->state = STATE_KEY_EXCHANGE_RECEIVED;
return NEED_MORE;
@@ -489,7 +499,12 @@ static status_t process_ec_key_exchange(private_tls_peer_t *this,
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
return NEED_MORE;
}
- this->dh->set_other_public_value(this->dh, chunk_skip(pub, 1));
+ if (!this->dh->set_other_public_value(this->dh, chunk_skip(pub, 1)))
+ {
+ DBG1(DBG_TLS, "applying DH public value failed");
+ this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+ return NEED_MORE;
+ }
this->state = STATE_KEY_EXCHANGE_RECEIVED;
return NEED_MORE;
@@ -968,7 +983,7 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this,
{
chunk_t premaster, pub;
- if (this->dh->get_shared_secret(this->dh, &premaster) != SUCCESS)
+ if (!this->dh->get_shared_secret(this->dh, &premaster))
{
DBG1(DBG_TLS, "calculating premaster from DH failed");
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
@@ -985,7 +1000,11 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this,
}
chunk_clear(&premaster);
- this->dh->get_my_public_value(this->dh, &pub);
+ if (!this->dh->get_my_public_value(this->dh, &pub))
+ {
+ this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+ return NEED_MORE;
+ }
if (this->dh->get_dh_group(this->dh) == MODP_CUSTOM)
{
writer->write_data16(writer, pub);
@@ -1153,6 +1172,12 @@ METHOD(tls_handshake_t, get_server_id, identification_t*,
return this->server;
}
+METHOD(tls_handshake_t, get_auth, auth_cfg_t*,
+ private_tls_peer_t *this)
+{
+ return this->server_auth;
+}
+
METHOD(tls_handshake_t, destroy, void,
private_tls_peer_t *this)
{
@@ -1186,6 +1211,7 @@ tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto, tls_alert_t *alert
.finished = _finished,
.get_peer_id = _get_peer_id,
.get_server_id = _get_server_id,
+ .get_auth = _get_auth,
.destroy = _destroy,
},
},
diff --git a/src/libtls/tls_protection.c b/src/libtls/tls_protection.c
index b016db21f..e73fedc5d 100644
--- a/src/libtls/tls_protection.c
+++ b/src/libtls/tls_protection.c
@@ -101,14 +101,13 @@ METHOD(tls_protection_t, build, status_t,
status_t status;
status = this->compression->build(this->compression, type, data);
- if (*type == TLS_CHANGE_CIPHER_SPEC)
- {
- this->seq_out = 0;
- return status;
- }
-
if (status == NEED_MORE)
{
+ if (*type == TLS_CHANGE_CIPHER_SPEC)
+ {
+ this->seq_out = 0;
+ return status;
+ }
if (this->aead_out)
{
if (!this->aead_out->encrypt(this->aead_out, this->version,
diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c
index aeb5a714f..b1a214f7f 100644
--- a/src/libtls/tls_server.c
+++ b/src/libtls/tls_server.c
@@ -494,8 +494,13 @@ static status_t process_key_exchange_dhe(private_tls_server_t *this,
}
pub = chunk_skip(pub, 1);
}
- this->dh->set_other_public_value(this->dh, pub);
- if (this->dh->get_shared_secret(this->dh, &premaster) != SUCCESS)
+ if (!this->dh->set_other_public_value(this->dh, pub))
+ {
+ DBG1(DBG_TLS, "applying DH public value failed");
+ this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+ return NEED_MORE;
+ }
+ if (!this->dh->get_shared_secret(this->dh, &premaster))
{
DBG1(DBG_TLS, "calculating premaster from DH failed");
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
@@ -551,6 +556,7 @@ static status_t process_cert_verify(private_tls_server_t *this,
sig->destroy(sig);
if (verified)
{
+ this->peer_auth->merge(this->peer_auth, auth, FALSE);
break;
}
DBG1(DBG_TLS, "signature verification failed, trying another key");
@@ -914,7 +920,11 @@ static status_t send_server_key_exchange(private_tls_server_t *this,
this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
return NEED_MORE;
}
- this->dh->get_my_public_value(this->dh, &chunk);
+ if (!this->dh->get_my_public_value(this->dh, &chunk))
+ {
+ this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+ return NEED_MORE;
+ }
if (params)
{
writer->write_data16(writer, chunk);
@@ -1073,6 +1083,12 @@ METHOD(tls_handshake_t, get_server_id, identification_t*,
return this->server;
}
+METHOD(tls_handshake_t, get_auth, auth_cfg_t*,
+ private_tls_server_t *this)
+{
+ return this->peer_auth;
+}
+
METHOD(tls_handshake_t, destroy, void,
private_tls_server_t *this)
{
@@ -1107,6 +1123,7 @@ tls_server_t *tls_server_create(tls_t *tls,
.finished = _finished,
.get_peer_id = _get_peer_id,
.get_server_id = _get_server_id,
+ .get_auth = _get_auth,
.destroy = _destroy,
},
},
diff --git a/src/libtls/tls_socket.c b/src/libtls/tls_socket.c
index 648771e75..2ccd97571 100644
--- a/src/libtls/tls_socket.c
+++ b/src/libtls/tls_socket.c
@@ -291,25 +291,24 @@ METHOD(tls_socket_t, splice, bool,
private_tls_socket_t *this, int rfd, int wfd)
{
char buf[PLAIN_BUF_SIZE], *pos;
- fd_set set;
ssize_t in, out;
bool old, plain_eof = FALSE, crypto_eof = FALSE;
+ struct pollfd pfd[] = {
+ { .fd = this->fd, .events = POLLIN, },
+ { .fd = rfd, .events = POLLIN, },
+ };
while (!plain_eof && !crypto_eof)
{
- FD_ZERO(&set);
- FD_SET(rfd, &set);
- FD_SET(this->fd, &set);
-
old = thread_cancelability(TRUE);
- in = select(max(rfd, this->fd) + 1, &set, NULL, NULL, NULL);
+ in = poll(pfd, countof(pfd), -1);
thread_cancelability(old);
if (in == -1)
{
DBG1(DBG_TLS, "TLS select error: %s", strerror(errno));
return FALSE;
}
- while (!plain_eof && FD_ISSET(this->fd, &set))
+ while (!plain_eof && pfd[0].revents & (POLLIN | POLLHUP | POLLNVAL))
{
in = read_(this, buf, sizeof(buf), FALSE);
switch (in)
@@ -342,7 +341,7 @@ METHOD(tls_socket_t, splice, bool,
}
break;
}
- if (!crypto_eof && FD_ISSET(rfd, &set))
+ if (!crypto_eof && pfd[1].revents & (POLLIN | POLLHUP | POLLNVAL))
{
in = read(rfd, buf, sizeof(buf));
switch (in)
diff --git a/src/libtnccs/Android.mk b/src/libtnccs/Android.mk
index 68f85c252..e37973202 100644
--- a/src/libtnccs/Android.mk
+++ b/src/libtnccs/Android.mk
@@ -22,7 +22,7 @@ endif
LOCAL_SRC_FILES += $(call add_plugin, tnc-tnccs)
LOCAL_SRC_FILES += $(call add_plugin, tnccs-20)
-LOCAL_SRC_FILES += $(call add_plugin_subdirs, tnccs-20, batch messages messages/ietf messages/tcg state_machine)
+LOCAL_SRC_FILES += $(call add_plugin_subdirs, tnccs-20, batch messages messages/ietf messages/ita messages/tcg state_machine)
ifneq ($(call plugin_enabled, tnccs-20),)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/plugins/tnccs_20/
endif
diff --git a/src/libtnccs/Makefile.in b/src/libtnccs/Makefile.in
index b0bfdf20d..dc8c1b8cc 100644
--- a/src/libtnccs/Makefile.in
+++ b/src/libtnccs/Makefile.in
@@ -283,6 +283,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@
@@ -343,10 +344,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@
@@ -420,6 +423,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/libtnccs/plugins/tnc_imc/Makefile.in b/src/libtnccs/plugins/tnc_imc/Makefile.in
index 2b76aabe6..3641bdf5b 100644
--- a/src/libtnccs/plugins/tnc_imc/Makefile.in
+++ b/src/libtnccs/plugins/tnc_imc/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/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c
index 859dded79..ce5b48133 100644
--- a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c
+++ b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c
@@ -44,6 +44,7 @@ METHOD(plugin_t, get_features, int,
PLUGIN_CALLBACK(tnc_manager_register, tnc_imc_manager_create),
PLUGIN_PROVIDE(CUSTOM, "imc-manager"),
PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
+ PLUGIN_SDEPEND(CUSTOM, "imv-manager"),
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
PLUGIN_SDEPEND(CERT_DECODE, CERT_TRUSTED_PUBKEY),
};
diff --git a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h
index 8c5521cb2..8cbc70367 100644
--- a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h
+++ b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h
@@ -15,7 +15,7 @@
/**
* @defgroup tnc_imc tnc_imc
- * @ingroup cplugins
+ * @ingroup tplugins
*
* @defgroup tnc_imc_plugin tnc_imc_plugin
* @{ @ingroup tnc_imc
diff --git a/src/libtnccs/plugins/tnc_imv/Makefile.in b/src/libtnccs/plugins/tnc_imv/Makefile.in
index 06e7b0480..c4b1bee23 100644
--- a/src/libtnccs/plugins/tnc_imv/Makefile.in
+++ b/src/libtnccs/plugins/tnc_imv/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/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h b/src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h
index afeee2ea2..5786bbaab 100644
--- a/src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h
+++ b/src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h
@@ -15,7 +15,7 @@
/**
* @defgroup tnc_imv tnc_imv
- * @ingroup cplugins
+ * @ingroup tplugins
*
* @defgroup tnc_imv_plugin tnc_imv_plugin
* @{ @ingroup tnc_imv
diff --git a/src/libtnccs/plugins/tnc_tnccs/Makefile.in b/src/libtnccs/plugins/tnc_tnccs/Makefile.in
index 8910fe761..5b01e317a 100644
--- a/src/libtnccs/plugins/tnc_tnccs/Makefile.in
+++ b/src/libtnccs/plugins/tnc_tnccs/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/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c
index b8683f78c..30e505246 100644
--- a/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c
+++ b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.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
@@ -169,8 +169,8 @@ METHOD(tnccs_manager_t, remove_method, void,
METHOD(tnccs_manager_t, create_instance, tnccs_t*,
private_tnc_tnccs_manager_t *this, tnccs_type_t type, bool is_server,
- identification_t *server, identification_t *peer, tnc_ift_type_t transport,
- tnccs_cb_t cb)
+ identification_t *server_id, identification_t *peer_id, host_t *server_ip,
+ host_t *peer_ip, tnc_ift_type_t transport, tnccs_cb_t cb)
{
enumerator_t *enumerator;
tnccs_entry_t *entry;
@@ -182,7 +182,8 @@ METHOD(tnccs_manager_t, create_instance, tnccs_t*,
{
if (type == entry->type)
{
- protocol = entry->constructor(is_server, server, peer, transport, cb);
+ protocol = entry->constructor(is_server, server_id, peer_id,
+ server_ip, peer_ip, transport, cb);
if (protocol)
{
break;
@@ -716,7 +717,8 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result,
case TNC_ATTRIBUTEID_AR_IDENTITIES:
{
linked_list_t *list;
- identification_t *peer;
+ identification_t *peer_id;
+ host_t *peer_ip;
tnccs_t *tnccs;
tncif_identity_t *tnc_id;
u_int32_t id_type, subject_type;
@@ -726,10 +728,11 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result,
list = linked_list_create();
tnccs = entry->tnccs;
- peer = tnccs->tls.get_peer_id(&tnccs->tls);
- if (peer)
+
+ peer_id = tnccs->tls.get_peer_id(&tnccs->tls);
+ if (peer_id)
{
- switch (peer->get_type(peer))
+ switch (peer_id->get_type(peer_id))
{
case ID_IPV4_ADDR:
id_type = TNC_ID_IPV4_ADDR;
@@ -756,7 +759,7 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result,
subject_type = TNC_SUBJECT_UNKNOWN;
}
if (id_type != TNC_ID_UNKNOWN &&
- asprintf(&id_str, "%Y", peer) >= 0)
+ asprintf(&id_str, "%Y", peer_id) >= 0)
{
id_value = chunk_from_str(id_str);
tnc_id = tncif_identity_create(
@@ -767,6 +770,33 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result,
list->insert_last(list, tnc_id);
}
}
+
+ peer_ip = tnccs->get_peer_ip(tnccs);
+ if (peer_ip)
+ {
+ switch (peer_ip->get_family(peer_ip))
+ {
+ case AF_INET:
+ id_type = TNC_ID_IPV4_ADDR;
+ break;
+ case AF_INET6:
+ id_type = TNC_ID_IPV6_ADDR;
+ break;
+ default:
+ id_type = TNC_ID_UNKNOWN;
+ }
+
+ if (id_type != TNC_ID_UNKNOWN &&
+ asprintf(&id_str, "%H", peer_ip) >= 0)
+ {
+ id_value = chunk_from_str(id_str);
+ tnc_id = tncif_identity_create(
+ pen_type_create(PEN_TCG, id_type), id_value,
+ pen_type_create(PEN_TCG, TNC_SUBJECT_MACHINE),
+ pen_type_create(PEN_TCG, TNC_AUTH_UNKNOWN));
+ list->insert_last(list, tnc_id);
+ }
+ }
result = identity_attribute(buffer_len, buffer, value_len, list);
list->destroy_offset(list, offsetof(tncif_identity_t, destroy));
return result;
diff --git a/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h
index f935fa462..c99d5e7c8 100644
--- a/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h
+++ b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h
@@ -15,7 +15,7 @@
/**
* @defgroup tnc_tnccs tnc_tnccs
- * @ingroup cplugins
+ * @ingroup tplugins
*
* @defgroup tnc_tnccs_plugin tnc_tnccs_plugin
* @{ @ingroup tnc_tnccs
diff --git a/src/libtnccs/plugins/tnccs_11/Makefile.in b/src/libtnccs/plugins/tnccs_11/Makefile.in
index ea6ac5546..e0c039af9 100644
--- a/src/libtnccs/plugins/tnccs_11/Makefile.in
+++ b/src/libtnccs/plugins/tnccs_11/Makefile.in
@@ -241,6 +241,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@
@@ -301,10 +302,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@
@@ -378,6 +381,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/libtnccs/plugins/tnccs_11/tnccs_11.c b/src/libtnccs/plugins/tnccs_11/tnccs_11.c
index 28c5e52b7..0918a2bad 100644
--- a/src/libtnccs/plugins/tnccs_11/tnccs_11.c
+++ b/src/libtnccs/plugins/tnccs_11/tnccs_11.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
@@ -54,12 +54,22 @@ struct private_tnccs_11_t {
/**
* Server identity
*/
- identification_t *server;
+ identification_t *server_id;
/**
* Client identity
*/
- identification_t *peer;
+ identification_t *peer_id;
+
+ /**
+ * Server IP address
+ */
+ host_t *server_ip;
+
+ /**
+ * Client IP address
+ */
+ host_t *peer_ip;
/**
* Underlying TNC IF-T transport protocol
@@ -527,20 +537,20 @@ METHOD(tls_t, is_server, bool,
METHOD(tls_t, get_server_id, identification_t*,
private_tnccs_11_t *this)
{
- return this->server;
+ return this->server_id;
}
METHOD(tls_t, set_peer_id, void,
private_tnccs_11_t *this, identification_t *id)
{
- DESTROY_IF(this->peer);
- this->peer = id->clone(id);
+ DESTROY_IF(this->peer_id);
+ this->peer_id = id->clone(id);
}
METHOD(tls_t, get_peer_id, identification_t*,
private_tnccs_11_t *this)
{
- return this->peer;
+ return this->peer_id;
}
METHOD(tls_t, get_purpose, tls_purpose_t,
@@ -578,14 +588,28 @@ METHOD(tls_t, destroy, void,
{
tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
this->is_server);
- this->server->destroy(this->server);
- this->peer->destroy(this->peer);
+ this->server_id->destroy(this->server_id);
+ this->peer_id->destroy(this->peer_id);
+ this->server_ip->destroy(this->server_ip);
+ this->peer_ip->destroy(this->peer_ip);
this->mutex->destroy(this->mutex);
DESTROY_IF(this->batch);
free(this);
}
}
+METHOD(tnccs_t, get_server_ip, host_t*,
+ private_tnccs_11_t *this)
+{
+ return this->server_ip;
+}
+
+METHOD(tnccs_t, get_peer_ip, host_t*,
+ private_tnccs_11_t *this)
+{
+ return this->peer_ip;
+}
+
METHOD(tnccs_t, get_transport, tnc_ift_type_t,
private_tnccs_11_t *this)
{
@@ -628,9 +652,10 @@ METHOD(tnccs_t, get_ref, tnccs_t*,
/**
* See header
*/
-tnccs_t* tnccs_11_create(bool is_server,
- identification_t *server, identification_t *peer,
- tnc_ift_type_t transport, tnccs_cb_t cb)
+tnccs_t* tnccs_11_create(bool is_server, identification_t *server_id,
+ identification_t *peer_id, host_t *server_ip,
+ host_t *peer_ip, tnc_ift_type_t transport,
+ tnccs_cb_t cb)
{
private_tnccs_11_t *this;
@@ -648,6 +673,8 @@ tnccs_t* tnccs_11_create(bool is_server,
.get_eap_msk = _get_eap_msk,
.destroy = _destroy,
},
+ .get_server_ip = _get_server_ip,
+ .get_peer_ip = _get_peer_ip,
.get_transport = _get_transport,
.set_transport = _set_transport,
.get_auth_type = _get_auth_type,
@@ -656,8 +683,10 @@ tnccs_t* tnccs_11_create(bool is_server,
.get_ref = _get_ref,
},
.is_server = is_server,
- .server = server->clone(server),
- .peer = peer->clone(peer),
+ .server_id = server_id->clone(server_id),
+ .peer_id = peer_id->clone(peer_id),
+ .server_ip = server_ip->clone(server_ip),
+ .peer_ip = peer_ip->clone(peer_ip),
.transport = transport,
.callback = cb,
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
diff --git a/src/libtnccs/plugins/tnccs_11/tnccs_11.h b/src/libtnccs/plugins/tnccs_11/tnccs_11.h
index e805df8bb..60d5518bc 100644
--- a/src/libtnccs/plugins/tnccs_11/tnccs_11.h
+++ b/src/libtnccs/plugins/tnccs_11/tnccs_11.h
@@ -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
@@ -29,14 +29,17 @@
* Create an instance of the TNC IF-TNCCS 1.1 protocol handler.
*
* @param is_server TRUE to act as TNC Server, FALSE for TNC Client
- * @param server Server identity
- * @param peer Client identity
+ * @param server_id Server identity
+ * @param peer_id Client identity
+ * @param server_ip Server IP address
+ * @param peer_ip Client IP address
* @param transport Underlying IF-T transport protocol
* @param cb Callback function if TNC Server, NULL if TNC Client
* @return TNC_IF_TNCCS 1.1 protocol stack
*/
-tnccs_t* tnccs_11_create(bool is_server,
- identification_t *server, identification_t *peer,
- tnc_ift_type_t transport, tnccs_cb_t cb);
+tnccs_t* tnccs_11_create(bool is_server, identification_t *server_id,
+ identification_t *peer_id, host_t *server_ip,
+ host_t *peer_ip, tnc_ift_type_t transport,
+ tnccs_cb_t cb);
#endif /** TNCCS_11_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h b/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h
index 619a073ad..73ea5759b 100644
--- a/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h
+++ b/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h
@@ -15,7 +15,7 @@
/**
* @defgroup tnccs_11 tnccs_11
- * @ingroup cplugins
+ * @ingroup tplugins
*
* @defgroup tnccs_11_plugin tnccs_11_plugin
* @{ @ingroup tnccs_11
diff --git a/src/libtnccs/plugins/tnccs_20/Makefile.am b/src/libtnccs/plugins/tnccs_20/Makefile.am
index 2aefecd26..7d1cdded1 100644
--- a/src/libtnccs/plugins/tnccs_20/Makefile.am
+++ b/src/libtnccs/plugins/tnccs_20/Makefile.am
@@ -18,6 +18,8 @@ endif
libstrongswan_tnccs_20_la_SOURCES = \
tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \
+ tnccs_20_handler.h \
+ tnccs_20_server.h tnccs_20_server.c tnccs_20_client.h tnccs_20_client.c \
batch/pb_tnc_batch.h batch/pb_tnc_batch.c \
messages/pb_tnc_msg.h messages/pb_tnc_msg.c \
messages/ietf/pb_experimental_msg.h messages/ietf/pb_experimental_msg.c \
@@ -28,6 +30,8 @@ libstrongswan_tnccs_20_la_SOURCES = \
messages/ietf/pb_language_preference_msg.h messages/ietf/pb_language_preference_msg.c \
messages/ietf/pb_reason_string_msg.h messages/ietf/pb_reason_string_msg.c \
messages/ietf/pb_remediation_parameters_msg.h messages/ietf/pb_remediation_parameters_msg.c \
+ messages/ita/pb_mutual_capability_msg.h messages/ita/pb_mutual_capability_msg.c \
+ messages/ita/pb_noskip_test_msg.h messages/ita/pb_noskip_test_msg.c \
messages/tcg/pb_pdp_referral_msg.h messages/tcg/pb_pdp_referral_msg.c \
state_machine/pb_tnc_state_machine.h state_machine/pb_tnc_state_machine.c
diff --git a/src/libtnccs/plugins/tnccs_20/Makefile.in b/src/libtnccs/plugins/tnccs_20/Makefile.in
index 90c804710..17d997f76 100644
--- a/src/libtnccs/plugins/tnccs_20/Makefile.in
+++ b/src/libtnccs/plugins/tnccs_20/Makefile.in
@@ -132,8 +132,8 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
am__dirstamp = $(am__leading_dot)dirstamp
am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo \
- batch/pb_tnc_batch.lo messages/pb_tnc_msg.lo \
- messages/ietf/pb_experimental_msg.lo \
+ tnccs_20_server.lo tnccs_20_client.lo batch/pb_tnc_batch.lo \
+ messages/pb_tnc_msg.lo messages/ietf/pb_experimental_msg.lo \
messages/ietf/pb_pa_msg.lo \
messages/ietf/pb_assessment_result_msg.lo \
messages/ietf/pb_access_recommendation_msg.lo \
@@ -141,6 +141,8 @@ am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo \
messages/ietf/pb_language_preference_msg.lo \
messages/ietf/pb_reason_string_msg.lo \
messages/ietf/pb_remediation_parameters_msg.lo \
+ messages/ita/pb_mutual_capability_msg.lo \
+ messages/ita/pb_noskip_test_msg.lo \
messages/tcg/pb_pdp_referral_msg.lo \
state_machine/pb_tnc_state_machine.lo
libstrongswan_tnccs_20_la_OBJECTS = \
@@ -242,6 +244,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@
@@ -302,10 +305,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@
@@ -379,6 +384,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@
@@ -454,6 +461,8 @@ AM_CFLAGS = \
libstrongswan_tnccs_20_la_SOURCES = \
tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \
+ tnccs_20_handler.h \
+ tnccs_20_server.h tnccs_20_server.c tnccs_20_client.h tnccs_20_client.c \
batch/pb_tnc_batch.h batch/pb_tnc_batch.c \
messages/pb_tnc_msg.h messages/pb_tnc_msg.c \
messages/ietf/pb_experimental_msg.h messages/ietf/pb_experimental_msg.c \
@@ -464,6 +473,8 @@ libstrongswan_tnccs_20_la_SOURCES = \
messages/ietf/pb_language_preference_msg.h messages/ietf/pb_language_preference_msg.c \
messages/ietf/pb_reason_string_msg.h messages/ietf/pb_reason_string_msg.c \
messages/ietf/pb_remediation_parameters_msg.h messages/ietf/pb_remediation_parameters_msg.c \
+ messages/ita/pb_mutual_capability_msg.h messages/ita/pb_mutual_capability_msg.c \
+ messages/ita/pb_noskip_test_msg.h messages/ita/pb_noskip_test_msg.c \
messages/tcg/pb_pdp_referral_msg.h messages/tcg/pb_pdp_referral_msg.c \
state_machine/pb_tnc_state_machine.h state_machine/pb_tnc_state_machine.c
@@ -590,6 +601,17 @@ messages/ietf/pb_reason_string_msg.lo: messages/ietf/$(am__dirstamp) \
messages/ietf/pb_remediation_parameters_msg.lo: \
messages/ietf/$(am__dirstamp) \
messages/ietf/$(DEPDIR)/$(am__dirstamp)
+messages/ita/$(am__dirstamp):
+ @$(MKDIR_P) messages/ita
+ @: > messages/ita/$(am__dirstamp)
+messages/ita/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) messages/ita/$(DEPDIR)
+ @: > messages/ita/$(DEPDIR)/$(am__dirstamp)
+messages/ita/pb_mutual_capability_msg.lo: \
+ messages/ita/$(am__dirstamp) \
+ messages/ita/$(DEPDIR)/$(am__dirstamp)
+messages/ita/pb_noskip_test_msg.lo: messages/ita/$(am__dirstamp) \
+ messages/ita/$(DEPDIR)/$(am__dirstamp)
messages/tcg/$(am__dirstamp):
@$(MKDIR_P) messages/tcg
@: > messages/tcg/$(am__dirstamp)
@@ -618,6 +640,8 @@ mostlyclean-compile:
-rm -f messages/*.lo
-rm -f messages/ietf/*.$(OBJEXT)
-rm -f messages/ietf/*.lo
+ -rm -f messages/ita/*.$(OBJEXT)
+ -rm -f messages/ita/*.lo
-rm -f messages/tcg/*.$(OBJEXT)
-rm -f messages/tcg/*.lo
-rm -f state_machine/*.$(OBJEXT)
@@ -627,7 +651,9 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20_client.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20_server.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@batch/$(DEPDIR)/pb_tnc_batch.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@messages/$(DEPDIR)/pb_tnc_msg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@messages/ietf/$(DEPDIR)/pb_access_recommendation_msg.Plo@am__quote@
@@ -638,6 +664,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@messages/ietf/$(DEPDIR)/pb_pa_msg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@messages/ietf/$(DEPDIR)/pb_reason_string_msg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@messages/ietf/$(DEPDIR)/pb_remediation_parameters_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@messages/ita/$(DEPDIR)/pb_mutual_capability_msg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@messages/ita/$(DEPDIR)/pb_noskip_test_msg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@messages/tcg/$(DEPDIR)/pb_pdp_referral_msg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@state_machine/$(DEPDIR)/pb_tnc_state_machine.Plo@am__quote@
@@ -673,6 +701,7 @@ clean-libtool:
-rm -rf batch/.libs batch/_libs
-rm -rf messages/.libs messages/_libs
-rm -rf messages/ietf/.libs messages/ietf/_libs
+ -rm -rf messages/ita/.libs messages/ita/_libs
-rm -rf messages/tcg/.libs messages/tcg/_libs
-rm -rf state_machine/.libs state_machine/_libs
@@ -797,6 +826,8 @@ distclean-generic:
-rm -f messages/$(am__dirstamp)
-rm -f messages/ietf/$(DEPDIR)/$(am__dirstamp)
-rm -f messages/ietf/$(am__dirstamp)
+ -rm -f messages/ita/$(DEPDIR)/$(am__dirstamp)
+ -rm -f messages/ita/$(am__dirstamp)
-rm -f messages/tcg/$(DEPDIR)/$(am__dirstamp)
-rm -f messages/tcg/$(am__dirstamp)
-rm -f state_machine/$(DEPDIR)/$(am__dirstamp)
@@ -811,7 +842,7 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
clean-pluginLTLIBRARIES mostlyclean-am
distclean: distclean-am
- -rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR)
+ -rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/ita/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@@ -857,7 +888,7 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR)
+ -rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/ita/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
diff --git a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c
index 228c08255..faad02b9b 100644
--- a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c
+++ b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Sansar Choinyanbuu
- * Copyright (C) 2010-2012 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
@@ -85,7 +85,7 @@ struct private_pb_tnc_batch_t {
pb_tnc_batch_t public;
/**
- * TNCC if TRUE, TNCS if FALSE
+ * from TNC server if TRUE, from TNC client if FALSE
*/
bool is_server;
@@ -166,6 +166,9 @@ METHOD(pb_tnc_batch_t, add_msg, bool,
case PEN_TCG:
msg_type_names = pb_tnc_tcg_msg_type_names;
break;
+ case PEN_ITA:
+ msg_type_names = pb_tnc_ita_msg_type_names;
+ break;
}
DBG2(DBG_TNC, "adding %N/%N message", pen_names, msg_type.vendor_id,
msg_type_names, msg_type.type);
@@ -176,6 +179,7 @@ METHOD(pb_tnc_batch_t, add_msg, bool,
METHOD(pb_tnc_batch_t, build, void,
private_pb_tnc_batch_t *this)
{
+ u_int8_t version;
u_int32_t msg_len;
chunk_t msg_value;
enumerator_t *enumerator;
@@ -184,9 +188,14 @@ METHOD(pb_tnc_batch_t, build, void,
pb_tnc_msg_info_t *msg_infos;
bio_writer_t *writer;
+ /* Set wrong PB-TNC version for testing purposes to force a PB-TNC error */
+ version = lib->settings->get_int(lib->settings,
+ "%s.plugins.tnccs-20.tests.pb_tnc_version",
+ PB_TNC_VERSION, lib->ns);
+
/* build PB-TNC batch header */
writer = bio_writer_create(this->batch_len);
- writer->write_uint8 (writer, PB_TNC_VERSION);
+ writer->write_uint8 (writer, version);
writer->write_uint8 (writer, this->is_server ?
PB_TNC_BATCH_FLAG_D : PB_TNC_BATCH_FLAG_NONE);
writer->write_uint16(writer, this->type);
@@ -211,6 +220,9 @@ METHOD(pb_tnc_batch_t, build, void,
case PEN_TCG:
msg_infos = pb_tnc_tcg_msg_infos;
break;
+ case PEN_ITA:
+ msg_infos = pb_tnc_ita_msg_infos;
+ break;
}
if (msg_infos[msg_type.type].has_noskip_flag)
{
@@ -228,15 +240,15 @@ METHOD(pb_tnc_batch_t, build, void,
writer->destroy(writer);
}
-static status_t process_batch_header(private_pb_tnc_batch_t *this,
- pb_tnc_state_machine_t *state_machine)
+METHOD(pb_tnc_batch_t, process_header, status_t,
+ private_pb_tnc_batch_t *this, bool directionality, bool is_server,
+ bool *from_server)
{
bio_reader_t *reader;
pb_tnc_msg_t *msg;
pb_error_msg_t *err_msg;
u_int8_t version, flags, reserved, type;
u_int32_t batch_len;
- bool directionality;
if (this->encoding.len < PB_TNC_BATCH_HEADER_SIZE)
{
@@ -267,13 +279,14 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
}
/* Directionality */
- directionality = (flags & PB_TNC_BATCH_FLAG_D) != PB_TNC_BATCH_FLAG_NONE;
- if (directionality == this->is_server)
+ *from_server = (flags & PB_TNC_BATCH_FLAG_D) != PB_TNC_BATCH_FLAG_NONE;
+
+ if (directionality & (*from_server == is_server))
{
DBG1(DBG_TNC, "wrong Directionality: batch is from a PB %s",
- directionality ? "server" : "client");
+ is_server ? "server" : "client");
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
- PB_ERROR_INVALID_PARAMETER, 1);
+ PB_ERROR_INVALID_PARAMETER, 1);
goto fatal;
}
@@ -287,17 +300,6 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
goto fatal;
}
- if (!state_machine->receive_batch(state_machine, this->type))
- {
- DBG1(DBG_TNC, "unexpected PB-TNC batch type: %N",
- pb_tnc_batch_type_names, this->type);
- msg = pb_error_msg_create(TRUE, PEN_IETF,
- PB_ERROR_UNEXPECTED_BATCH_TYPE);
- goto fatal;
- }
- DBG1(DBG_TNC, "processing PB-TNC %N batch", pb_tnc_batch_type_names,
- this->type);
-
/* Batch Length */
if (this->encoding.len != batch_len)
{
@@ -310,12 +312,6 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
this->offset = PB_TNC_BATCH_HEADER_SIZE;
- /* Register an empty CDATA batch with the state machine */
- if (this->type == PB_BATCH_CDATA)
- {
- state_machine->set_empty_cdata(state_machine,
- this->offset == this->encoding.len);
- }
return SUCCESS;
fatal:
@@ -395,11 +391,18 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
msg_type_names = pb_tnc_msg_type_names;
msg_infos = pb_tnc_msg_infos;
}
- else if (vendor_id == PEN_TCG && msg_type <= PB_TCG_MSG_ROOF)
+ else if (vendor_id == PEN_TCG && msg_type <= PB_TCG_MSG_ROOF &&
+ msg_type > PB_TCG_MSG_RESERVED)
{
msg_type_names = pb_tnc_tcg_msg_type_names;
msg_infos = pb_tnc_tcg_msg_infos;
}
+ else if (vendor_id == PEN_ITA && msg_type <= PB_ITA_MSG_ROOF &&
+ msg_type > PB_ITA_MSG_NOSKIP_TEST)
+ {
+ msg_type_names = pb_tnc_ita_msg_type_names;
+ msg_infos = pb_tnc_ita_msg_infos;
+ }
else
{
if (msg_len < PB_TNC_MSG_HEADER_SIZE)
@@ -413,7 +416,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
if (noskip_flag)
{
- DBG1(DBG_TNC, "reject PB-TNC message 0x%06x/0x%08x)",
+ DBG1(DBG_TNC, "reject PB-TNC message (0x%06x/0x%08x)",
vendor_id, msg_type);
msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset);
@@ -421,7 +424,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
}
else
{
- DBG1(DBG_TNC, "ignore PB-TNC message 0x%06x/0x%08x)",
+ DBG1(DBG_TNC, "ignore PB-TNC message (0x%06x/0x%08x)",
vendor_id, msg_type);
this->offset += msg_len;
return SUCCESS;
@@ -502,14 +505,26 @@ fatal:
METHOD(pb_tnc_batch_t, process, status_t,
private_pb_tnc_batch_t *this, pb_tnc_state_machine_t *state_machine)
{
- status_t status;
+ pb_tnc_msg_t *msg;
+ status_t status = SUCCESS;
- status = process_batch_header(this, state_machine);
- if (status != SUCCESS)
+ if (!state_machine->receive_batch(state_machine, this->type))
{
+ DBG1(DBG_TNC, "unexpected PB-TNC batch type: %N",
+ pb_tnc_batch_type_names, this->type);
+ msg = pb_error_msg_create(TRUE, PEN_IETF,
+ PB_ERROR_UNEXPECTED_BATCH_TYPE);
+ this->errors->insert_last(this->errors, msg);
return FAILED;
}
+ /* Register an empty CDATA batch with the state machine */
+ if (this->type == PB_BATCH_CDATA)
+ {
+ state_machine->set_empty_cdata(state_machine,
+ this->offset == this->encoding.len);
+ }
+
while (this->offset < this->encoding.len)
{
switch (process_tnc_msg(this))
@@ -585,7 +600,7 @@ pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type,
/**
* See header
*/
-pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data)
+pb_tnc_batch_t* pb_tnc_batch_create_from_data(chunk_t data)
{
private_pb_tnc_batch_t *this;
@@ -595,12 +610,12 @@ pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data)
.get_encoding = _get_encoding,
.add_msg = _add_msg,
.build = _build,
+ .process_header = _process_header,
.process = _process,
.create_msg_enumerator = _create_msg_enumerator,
.create_error_enumerator = _create_error_enumerator,
.destroy = _destroy,
},
- .is_server = is_server,
.messages = linked_list_create(),
.errors = linked_list_create(),
.encoding = chunk_clone(data),
diff --git a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h
index 106c5578c..6089c7d2e 100644
--- a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h
+++ b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 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
@@ -84,10 +84,21 @@ struct pb_tnc_batch_t {
void (*build)(pb_tnc_batch_t *this);
/**
+ * Process the PB-TNC Batch header
+ *
+ * @param directionality TRUE if no mutual TNC measurements
+ * @param is_server TRUE if called by TNC server
+ * @param from_server TRUE if sent by TNC server
+ * @return return processing status
+ */
+ status_t (*process_header)(pb_tnc_batch_t *this, bool directionality,
+ bool is_server, bool *from_server);
+
+ /**
* Process the PB-TNC Batch
*
- * @param PB-TNC state machine
- * @return return processing status
+ * @param state_machine PB-TNC state machine
+ * @return return processing status
*/
status_t (*process)(pb_tnc_batch_t *this,
pb_tnc_state_machine_t *state_machine);
@@ -95,14 +106,14 @@ struct pb_tnc_batch_t {
/**
* Enumerates over all PB-TNC Messages
*
- * @return return message enumerator
+ * @return return message enumerator
*/
enumerator_t* (*create_msg_enumerator)(pb_tnc_batch_t *this);
/**
* Enumerates over all parsing errors
*
- * @return return error enumerator
+ * @return return error enumerator
*/
enumerator_t* (*create_error_enumerator)(pb_tnc_batch_t *this);
@@ -115,9 +126,9 @@ struct pb_tnc_batch_t {
/**
* Create an empty PB-TNC Batch of a given type
*
- * @param is_server TRUE if server, FALSE if client
- * @param type PB-TNC batch type
- * @param max_batch_len maximum size the PB-TNC batch
+ * @param is_server TRUE if server, FALSE if client
+ * @param type PB-TNC batch type
+ * @param max_batch_len maximum size the PB-TNC batch
*/
pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type,
size_t max_batch_len);
@@ -125,9 +136,8 @@ pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type,
/**
* Create an unprocessed PB-TNC Batch from data
*
- * @param is_server TRUE if server, FALSE if client
* @param data encoded PB-TNC batch
*/
-pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data);
+pb_tnc_batch_t* pb_tnc_batch_create_from_data(chunk_t data);
#endif /** PB_TNC_BATCH_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.c b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.c
new file mode 100644
index 000000000..1f35cae6b
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * 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 "pb_mutual_capability_msg.h"
+
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/debug.h>
+
+ENUM(pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX,
+ PB_MUTUAL_FULL_DUPLEX,
+ "half duplex",
+ "full duplex"
+);
+
+typedef struct private_pb_mutual_capability_msg_t private_pb_mutual_capability_msg_t;
+
+/**
+ * PB-Mutual-Capability message
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |H|F| Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+# define MUTUAL_CAPABILITY_HEADER_SIZE 4
+
+/**
+ * Private data of a pb_mutual_capability_msg_t object.
+ *
+ */
+struct private_pb_mutual_capability_msg_t {
+ /**
+ * Public pb_mutual_capability_msg_t interface.
+ */
+ pb_mutual_capability_msg_t public;
+
+ /**
+ * PB-TNC message type
+ */
+ pen_type_t type;
+
+ /**
+ * PB-TNC mutual protocols
+ */
+ uint32_t protocols;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pen_type_t,
+ private_pb_mutual_capability_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+ private_pb_mutual_capability_msg_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+ private_pb_mutual_capability_msg_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->encoding.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(MUTUAL_CAPABILITY_HEADER_SIZE);
+ writer->write_uint32(writer, this->protocols);
+
+ this->encoding = writer->get_buf(writer);
+ this->encoding = chunk_clone(this->encoding);
+ writer->destroy(writer);
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+ private_pb_mutual_capability_msg_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+
+ *offset = 0;
+
+ /* process message */
+ reader = bio_reader_create(this->encoding);
+ reader->read_uint32(reader, &this->protocols);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+ private_pb_mutual_capability_msg_t *this)
+{
+ free(this->encoding.ptr);
+ free(this);
+}
+
+METHOD(pb_mutual_capability_msg_t, get_protocols, uint32_t,
+ private_pb_mutual_capability_msg_t *this)
+{
+ return this->protocols;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t* pb_mutual_capability_msg_create(uint32_t protocols)
+{
+ private_pb_mutual_capability_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_protocols = _get_protocols,
+ },
+ .type = { PEN_ITA, PB_ITA_MSG_MUTUAL_CAPABILITY },
+ .protocols = protocols,
+ );
+
+ return &this->public.pb_interface;
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_mutual_capability_msg_create_from_data(chunk_t data)
+{
+ private_pb_mutual_capability_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_protocols = _get_protocols,
+ },
+ .type = { PEN_ITA, PB_ITA_MSG_MUTUAL_CAPABILITY },
+ .encoding = chunk_clone(data),
+ );
+
+ return &this->public.pb_interface;
+}
+
diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.h b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.h
new file mode 100644
index 000000000..db810a012
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * 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 pb_mutual_capability_msg pb_mutual_capability_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_MUTUAL_CAPABILITY_MSG_H_
+#define PB_MUTUAL_CAPABILITY_MSG_H_
+
+typedef enum pb_tnc_mutual_protocol_type_t pb_tnc_mutual_protocol_type_t;
+typedef struct pb_mutual_capability_msg_t pb_mutual_capability_msg_t;
+
+#include "messages/pb_tnc_msg.h"
+
+/**
+ * PB-TNC mutual protocol types
+ */
+enum pb_tnc_mutual_protocol_type_t {
+ PB_MUTUAL_HALF_DUPLEX = (1 << 31),
+ PB_MUTUAL_FULL_DUPLEX = (1 << 30)
+};
+
+/**
+ * enum name for pb_mutual_protocol_type_t.
+ */
+extern enum_name_t *pb_tnc_mutual_protocol_type_names;
+
+/**
+ * Class representing the PB-Mutual-Capabilities message type.
+ */
+struct pb_mutual_capability_msg_t {
+
+ /**
+ * PB-TNC Message interface
+ */
+ pb_tnc_msg_t pb_interface;
+
+ /**
+ * Get the PB-TNC mutual protocol types
+ *
+ * @return PB-TNC mutual protocol types
+ */
+ uint32_t(*get_protocols)(pb_mutual_capability_msg_t *this);
+
+};
+
+/**
+ * Create a PB-Mutual-Capability message
+ *
+ * @param protocols Supported PB-TNC mutual protocols
+ */
+pb_tnc_msg_t* pb_mutual_capability_msg_create(uint32_t protocols);
+
+/**
+ * Create an unprocessed PB-Mutual-Capability message from raw data
+ *
+ * @param data PB-Mutual-Capability message data
+ */
+pb_tnc_msg_t* pb_mutual_capability_msg_create_from_data(chunk_t data);
+
+#endif /** PB_MUTUAL_CAPABILITY_MSG_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.c b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.c
new file mode 100644
index 000000000..c95222e3a
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * 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 "pb_noskip_test_msg.h"
+
+typedef struct private_pb_noskip_test_msg_t private_pb_noskip_test_msg_t;
+
+/**
+ * Private data of a pb_noskip_test_msg_t object.
+ *
+ */
+struct private_pb_noskip_test_msg_t {
+ /**
+ * Public pb_noskip_test_msg_t interface.
+ */
+ pb_noskip_test_msg_t public;
+
+ /**
+ * PB-TNC message type
+ */
+ pen_type_t type;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+};
+
+METHOD(pb_tnc_msg_t, get_type, pen_type_t,
+ private_pb_noskip_test_msg_t *this)
+{
+ return this->type;
+}
+
+METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
+ private_pb_noskip_test_msg_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pb_tnc_msg_t, build, void,
+ private_pb_noskip_test_msg_t *this)
+{
+ /* nothing to do since the message is empty */
+}
+
+METHOD(pb_tnc_msg_t, process, status_t,
+ private_pb_noskip_test_msg_t *this, u_int32_t *offset)
+{
+ return SUCCESS;
+}
+
+METHOD(pb_tnc_msg_t, destroy, void,
+ private_pb_noskip_test_msg_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+pb_tnc_msg_t *pb_noskip_test_msg_create(void)
+{
+ private_pb_noskip_test_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .pb_interface = {
+ .get_type = _get_type,
+ .get_encoding = _get_encoding,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ },
+ .type = { PEN_ITA, PB_ITA_MSG_NOSKIP_TEST },
+ );
+
+ return &this->public.pb_interface;
+}
diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.h b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.h
new file mode 100644
index 000000000..6325582da
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * 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 pb_noskip_test_msg pb_noskip_test_msg
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef PB_NOSKIP_TEST_MSG_H_
+#define PB_NOSKIP_TEST_MSG_H_
+
+typedef struct pb_noskip_test_msg_t pb_noskip_test_msg_t;
+
+#include "messages/pb_tnc_msg.h"
+
+/**
+ * Class representing the PB-Noskip-Test message type.
+ */
+struct pb_noskip_test_msg_t {
+
+ /**
+ * PB-TNC Message interface
+ */
+ pb_tnc_msg_t pb_interface;
+};
+
+/**
+ * Create a PB-Noskip-Test message from parameters
+ */
+pb_tnc_msg_t* pb_noskip_test_msg_create(void);
+
+#endif /** PB_NOSKIP_TEST_MSG_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c
index ec43490f4..b46c776e4 100644
--- a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c
+++ b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c
@@ -22,6 +22,7 @@
#include "ietf/pb_access_recommendation_msg.h"
#include "ietf/pb_remediation_parameters_msg.h"
#include "ietf/pb_reason_string_msg.h"
+#include "ita/pb_mutual_capability_msg.h"
#include "tcg/pb_pdp_referral_msg.h"
#include <library.h>
@@ -37,10 +38,17 @@ ENUM(pb_tnc_msg_type_names, PB_MSG_EXPERIMENTAL, PB_MSG_REASON_STRING,
"PB-Reason-String"
);
-ENUM(pb_tnc_tcg_msg_type_names, PB_TCG_MSG_PDP_REFERRAL, PB_TCG_MSG_PDP_REFERRAL,
+ENUM(pb_tnc_tcg_msg_type_names, PB_TCG_MSG_PDP_REFERRAL,
+ PB_TCG_MSG_PDP_REFERRAL,
"PB-PDP-Referral"
);
+ENUM(pb_tnc_ita_msg_type_names, PB_ITA_MSG_NOSKIP_TEST,
+ PB_ITA_MSG_MUTUAL_CAPABILITY,
+ "PB-Noskip-Test",
+ "PB-Mutual-Capability"
+);
+
pb_tnc_msg_info_t pb_tnc_msg_infos[] = {
{ 12, FALSE, FALSE, TRUE_OR_FALSE },
{ 24, FALSE, FALSE, TRUE },
@@ -57,6 +65,11 @@ pb_tnc_msg_info_t pb_tnc_tcg_msg_infos[] = {
{ 20, FALSE, FALSE, FALSE },
};
+pb_tnc_msg_info_t pb_tnc_ita_msg_infos[] = {
+ { 12, TRUE, FALSE, TRUE },
+ { 16, FALSE, FALSE, FALSE },
+};
+
/**
* See header
*/
@@ -91,5 +104,12 @@ pb_tnc_msg_t* pb_tnc_msg_create_from_data(pen_type_t msg_type, chunk_t value)
return pb_pdp_referral_msg_create_from_data(value);
}
}
+ else if (msg_type.vendor_id == PEN_ITA)
+ {
+ if (msg_type.type == PB_ITA_MSG_MUTUAL_CAPABILITY)
+ {
+ return pb_mutual_capability_msg_create_from_data(value);
+ }
+ }
return NULL;
}
diff --git a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h
index 6eeed5156..35b0b7c26 100644
--- a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h
+++ b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h
@@ -54,6 +54,7 @@ extern enum_name_t *pb_tnc_msg_type_names;
* PB-TNC Message Type defined in the TCG namespace
*/
enum pb_tnc_tcg_msg_type_t {
+ PB_TCG_MSG_RESERVED = 0,
PB_TCG_MSG_PDP_REFERRAL = 1,
PB_TCG_MSG_ROOF = 1
};
@@ -64,6 +65,20 @@ enum pb_tnc_tcg_msg_type_t {
extern enum_name_t *pb_tnc_tcg_msg_type_names;
/**
+ * PB-TNC Message Type defined in the ITA namespace
+ */
+enum pb_tnc_ita_msg_type_t {
+ PB_ITA_MSG_NOSKIP_TEST = 0,
+ PB_ITA_MSG_MUTUAL_CAPABILITY = 1,
+ PB_ITA_MSG_ROOF = 1
+};
+
+/**
+ * enum name for pb_tnc_tcg_msg_type_t.
+ */
+extern enum_name_t *pb_tnc_ita_msg_type_names;
+
+/**
* Information entry describing a PB-TNC Message Type
*/
struct pb_tnc_msg_info_t {
@@ -86,6 +101,11 @@ extern pb_tnc_msg_info_t pb_tnc_msg_infos[];
extern pb_tnc_msg_info_t pb_tnc_tcg_msg_infos[];
/**
+ * Information on PB-TNC ITA Message Types
+ */
+extern pb_tnc_msg_info_t pb_tnc_ita_msg_infos[];
+
+/**
* Generic interface for all PB-TNC message types.
*
* To handle all messages in a generic way, this interface
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20.c b/src/libtnccs/plugins/tnccs_20/tnccs_20.c
index dc4da51c6..a1a95733f 100644
--- a/src/libtnccs/plugins/tnccs_20/tnccs_20.c
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Sansar Choinyanbuu
- * 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
@@ -15,30 +15,17 @@
*/
#include "tnccs_20.h"
+#include "tnccs_20_handler.h"
+#include "tnccs_20_server.h"
+#include "tnccs_20_client.h"
#include "batch/pb_tnc_batch.h"
#include "messages/pb_tnc_msg.h"
#include "messages/ietf/pb_pa_msg.h"
-#include "messages/ietf/pb_error_msg.h"
-#include "messages/ietf/pb_assessment_result_msg.h"
-#include "messages/ietf/pb_access_recommendation_msg.h"
-#include "messages/ietf/pb_remediation_parameters_msg.h"
-#include "messages/ietf/pb_reason_string_msg.h"
-#include "messages/ietf/pb_language_preference_msg.h"
-#include "messages/tcg/pb_pdp_referral_msg.h"
-#include "state_machine/pb_tnc_state_machine.h"
#include <tncif_names.h>
#include <tncif_pa_subtypes.h>
-#include <tnc/tnc.h>
-#include <tnc/tnccs/tnccs_manager.h>
-#include <tnc/imc/imc_manager.h>
-#include <tnc/imv/imv_manager.h>
-
-#include <threading/mutex.h>
#include <utils/debug.h>
-#include <collections/linked_list.h>
-#include <pen/pen.h>
typedef struct private_tnccs_20_t private_tnccs_20_t;
@@ -60,77 +47,72 @@ struct private_tnccs_20_t {
/**
* Server identity
*/
- identification_t *server;
+ identification_t *server_id;
/**
* Client identity
*/
- identification_t *peer;
+ identification_t *peer_id;
/**
- * Underlying TNC IF-T transport protocol
+ * Server IP address
*/
- tnc_ift_type_t transport;
+ host_t *server_ip;
/**
- * Type of TNC client authentication
+ * Client IP address
*/
- u_int32_t auth_type;
+ host_t *peer_ip;
/**
- * PB-TNC State Machine
+ * Underlying TNC IF-T transport protocol
*/
- pb_tnc_state_machine_t *state_machine;
+ tnc_ift_type_t transport;
/**
- * Connection ID assigned to this TNCCS connection
+ * TNC IF-T transport protocol for EAP methods
*/
- TNC_ConnectionID connection_id;
+ bool eap_transport;
/**
- * PB-TNC messages to be sent
+ * Type of TNC client authentication
*/
- linked_list_t *messages;
+ u_int32_t auth_type;
/**
- * Type of PB-TNC batch being constructed
+ * Mutual PB-TNC protocol enabled
*/
- pb_tnc_batch_type_t batch_type;
+ bool mutual;
/**
- * Maximum PB-TNC batch size
+ * Direction the next batch will go to
*/
- size_t max_batch_len;
+ bool to_server;
/**
- * Maximum PA-TNC message size
+ * TNC Server
*/
- size_t max_msg_len;
+ tnccs_20_handler_t *tnc_server;
/**
- * Mutex locking the batch in construction
+ * TNC Client
*/
- mutex_t *mutex;
+ tnccs_20_handler_t *tnc_client;
/**
- * Flag set while processing
+ * Active TNCSS handler
*/
- bool fatal_error;
+ tnccs_20_handler_t *tnccs_handler;
/**
- * Flag set by IMC/IMV RequestHandshakeRetry() function
+ * Maximum PB-TNC batch size
*/
- bool request_handshake_retry;
-
- /**
- * SendMessage() by IMC/IMV only allowed if flag is set
- */
- bool send_msg;
+ size_t max_batch_len;
/**
- * Set of IMV recommendations (TNC Server only)
+ * Maximum PA-TNC message size
*/
- recommendations_t *recs;
+ size_t max_msg_len;
/**
* Callback function to communicate recommendation (TNC Server only)
@@ -138,69 +120,30 @@ struct private_tnccs_20_t {
tnccs_cb_t callback;
/**
- * Data to pass to callback function (TNC Server only)
- */
- void *cb_data;
-
- /**
- * PDP server FQDN
- */
- chunk_t pdp_server;
-
- /**
- * PDP server port
- */
- u_int16_t pdp_port;
-
- /**
* reference count
*/
refcount_t ref;
};
-/**
- * If the batch type changes then delete all accumulated PB-TNC messages
- */
-void change_batch_type(private_tnccs_20_t *this, pb_tnc_batch_type_t batch_type)
-{
- pb_tnc_msg_t *msg;
-
- if (batch_type != this->batch_type)
- {
- if (this->batch_type != PB_BATCH_NONE)
- {
- DBG1(DBG_TNC, "cancelling PB-TNC %N batch",
- pb_tnc_batch_type_names, this->batch_type);
-
- while (this->messages->remove_last(this->messages,
- (void**)&msg) == SUCCESS)
- {
- msg->destroy(msg);
- }
- }
- this->batch_type = batch_type;
- }
-}
-
METHOD(tnccs_t, send_msg, TNC_Result,
private_tnccs_20_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
- TNC_UInt32 msg_flags,
+ TNC_UInt32 msg_flags,
TNC_BufferReference msg,
TNC_UInt32 msg_len,
- TNC_VendorID msg_vid,
- TNC_MessageSubtype msg_subtype)
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype)
{
pb_tnc_msg_t *pb_tnc_msg;
- pb_tnc_batch_type_t batch_type;
enum_name_t *pa_subtype_names;
bool excl;
- if (!this->send_msg)
+ if (!this->tnccs_handler->get_send_flag(this->tnccs_handler))
{
DBG1(DBG_TNC, "%s %u not allowed to call SendMessage()",
- this->is_server ? "IMV" : "IMC",
- this->is_server ? imv_id : imc_id);
+ this->to_server ? "IMC" : "IMV",
+ this->to_server ? imc_id : imv_id);
+
return TNC_RESULT_ILLEGAL_OPERATION;
}
excl = (msg_flags & TNC_MESSAGE_FLAGS_EXCLUSIVE) != 0;
@@ -220,698 +163,169 @@ METHOD(tnccs_t, send_msg, TNC_Result,
DBG2(DBG_TNC, "creating PB-PA message type '%N' 0x%06x/0x%08x",
pen_names, msg_vid, msg_vid, msg_subtype);
}
+ this->tnccs_handler->add_msg(this->tnccs_handler, pb_tnc_msg);
- /* adding PA message to SDATA or CDATA batch only */
- batch_type = this->is_server ? PB_BATCH_SDATA : PB_BATCH_CDATA;
- this->mutex->lock(this->mutex);
- if (this->batch_type == PB_BATCH_NONE)
- {
- this->batch_type = batch_type;
- }
- if (this->batch_type == batch_type)
- {
- this->messages->insert_last(this->messages, pb_tnc_msg);
- }
- else
- {
- pb_tnc_msg->destroy(pb_tnc_msg);
- }
- this->mutex->unlock(this->mutex);
return TNC_RESULT_SUCCESS;
}
-/**
- * Handle a single PB-TNC IETF standard message according to its type
- */
-static void handle_ietf_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
-{
- pen_type_t msg_type = msg->get_type(msg);
-
- switch (msg_type.type)
- {
- case PB_MSG_EXPERIMENTAL:
- /* nothing to do */
- break;
- case PB_MSG_PA:
- {
- pb_pa_msg_t *pa_msg;
- pen_type_t msg_subtype;
- u_int16_t imc_id, imv_id;
- chunk_t msg_body;
- bool excl;
- enum_name_t *pa_subtype_names;
-
- pa_msg = (pb_pa_msg_t*)msg;
- msg_subtype = pa_msg->get_subtype(pa_msg);
- msg_body = pa_msg->get_body(pa_msg);
- imc_id = pa_msg->get_collector_id(pa_msg);
- imv_id = pa_msg->get_validator_id(pa_msg);
- excl = pa_msg->get_exclusive_flag(pa_msg);
-
- pa_subtype_names = get_pa_subtype_names(msg_subtype.vendor_id);
- if (pa_subtype_names)
- {
- DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x",
- pen_names, msg_subtype.vendor_id, pa_subtype_names,
- msg_subtype.type, msg_subtype.vendor_id, msg_subtype.type);
- }
- else
- {
- DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x",
- pen_names, msg_subtype.vendor_id, msg_subtype.vendor_id,
- msg_subtype.type);
- }
-
- this->send_msg = TRUE;
- if (this->is_server)
- {
- tnc->imvs->receive_message(tnc->imvs, this->connection_id,
- excl, msg_body.ptr, msg_body.len,
- msg_subtype.vendor_id,
- msg_subtype.type, imc_id, imv_id);
- }
- else
- {
- tnc->imcs->receive_message(tnc->imcs, this->connection_id,
- excl, msg_body.ptr, msg_body.len,
- msg_subtype.vendor_id,
- msg_subtype.type, imv_id, imc_id);
- }
- this->send_msg = FALSE;
- break;
- }
- case PB_MSG_ASSESSMENT_RESULT:
- {
- pb_assessment_result_msg_t *assess_msg;
- u_int32_t result;
-
- assess_msg = (pb_assessment_result_msg_t*)msg;
- result = assess_msg->get_assessment_result(assess_msg);
- DBG1(DBG_TNC, "PB-TNC assessment result is '%N'",
- TNC_IMV_Evaluation_Result_names, result);
- break;
- }
- case PB_MSG_ACCESS_RECOMMENDATION:
- {
- pb_access_recommendation_msg_t *rec_msg;
- pb_access_recommendation_code_t rec;
- TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE;
-
- rec_msg = (pb_access_recommendation_msg_t*)msg;
- rec = rec_msg->get_access_recommendation(rec_msg);
- DBG1(DBG_TNC, "PB-TNC access recommendation is '%N'",
- pb_access_recommendation_code_names, rec);
- switch (rec)
- {
- case PB_REC_ACCESS_ALLOWED:
- state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
- break;
- case PB_REC_ACCESS_DENIED:
- state = TNC_CONNECTION_STATE_ACCESS_NONE;
- break;
- case PB_REC_QUARANTINED:
- state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
- }
- tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
- state);
- break;
- }
- case PB_MSG_REMEDIATION_PARAMETERS:
- {
- pb_remediation_parameters_msg_t *rem_msg;
- pen_type_t parameters_type;
- chunk_t parameters, string, lang_code;
-
- rem_msg = (pb_remediation_parameters_msg_t*)msg;
- parameters_type = rem_msg->get_parameters_type(rem_msg);
- parameters = rem_msg->get_parameters(rem_msg);
-
- if (parameters_type.vendor_id == PEN_IETF)
- {
- switch (parameters_type.type)
- {
- case PB_REMEDIATION_URI:
- DBG1(DBG_TNC, "remediation uri: %.*s",
- parameters.len, parameters.ptr);
- break;
- case PB_REMEDIATION_STRING:
- string = rem_msg->get_string(rem_msg, &lang_code);
- DBG1(DBG_TNC, "remediation string: [%.*s]\n%.*s",
- lang_code.len, lang_code.ptr,
- string.len, string.ptr);
- break;
- default:
- DBG1(DBG_TNC, "remediation parameters: %B", &parameters);
- }
- }
- else
- {
- DBG1(DBG_TNC, "remediation parameters: %B", &parameters);
- }
- break;
- }
- case PB_MSG_ERROR:
- {
- pb_error_msg_t *err_msg;
- bool fatal;
- u_int32_t vendor_id;
- u_int16_t error_code;
-
- err_msg = (pb_error_msg_t*)msg;
- fatal = err_msg->get_fatal_flag(err_msg);
- vendor_id = err_msg->get_vendor_id(err_msg);
- error_code = err_msg->get_error_code(err_msg);
-
- if (fatal)
- {
- this->fatal_error = TRUE;
- }
-
- if (vendor_id == PEN_IETF)
- {
- switch (error_code)
- {
- case PB_ERROR_INVALID_PARAMETER:
- case PB_ERROR_UNSUPPORTED_MANDATORY_MSG:
- DBG1(DBG_TNC, "received %s PB-TNC error '%N' "
- "(offset %u bytes)",
- fatal ? "fatal" : "non-fatal",
- pb_tnc_error_code_names, error_code,
- err_msg->get_offset(err_msg));
- break;
- case PB_ERROR_VERSION_NOT_SUPPORTED:
- DBG1(DBG_TNC, "received %s PB-TNC error '%N' "
- "caused by bad version 0x%02x",
- fatal ? "fatal" : "non-fatal",
- pb_tnc_error_code_names, error_code,
- err_msg->get_bad_version(err_msg));
- break;
- case PB_ERROR_UNEXPECTED_BATCH_TYPE:
- case PB_ERROR_LOCAL_ERROR:
- default:
- DBG1(DBG_TNC, "received %s PB-TNC error '%N'",
- fatal ? "fatal" : "non-fatal",
- pb_tnc_error_code_names, error_code);
- break;
- }
- }
- else
- {
- DBG1(DBG_TNC, "received %s PB-TNC error (%u) "
- "with Vendor ID 0x%06x",
- fatal ? "fatal" : "non-fatal",
- error_code, vendor_id);
- }
- break;
- }
- case PB_MSG_LANGUAGE_PREFERENCE:
- {
- pb_language_preference_msg_t *lang_msg;
- chunk_t lang;
-
- lang_msg = (pb_language_preference_msg_t*)msg;
- lang = lang_msg->get_language_preference(lang_msg);
-
- if (this->recs)
- {
- DBG2(DBG_TNC, "setting language preference to '%.*s'",
- (int)lang.len, lang.ptr);
- this->recs->set_preferred_language(this->recs, lang);
- }
- break;
- }
- case PB_MSG_REASON_STRING:
- {
- pb_reason_string_msg_t *reason_msg;
- chunk_t reason_string, language_code;
-
- reason_msg = (pb_reason_string_msg_t*)msg;
- reason_string = reason_msg->get_reason_string(reason_msg);
- language_code = reason_msg->get_language_code(reason_msg);
- DBG1(DBG_TNC, "reason string is '%.*s' [%.*s]",
- (int)reason_string.len, reason_string.ptr,
- (int)language_code.len, language_code.ptr);
- break;
- }
- default:
- break;
- }
-}
-
-/**
- * Handle a single PB-TNC TCG standard message according to its type
- */
-static void handle_tcg_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
-{
- pen_type_t msg_type = msg->get_type(msg);
-
- switch (msg_type.type)
- {
- case PB_TCG_MSG_PDP_REFERRAL:
- {
- pb_pdp_referral_msg_t *pdp_msg;
- pen_type_t pdp_id_type;
- u_int8_t pdp_protocol;
-
- pdp_msg = (pb_pdp_referral_msg_t*)msg;
- pdp_id_type = pdp_msg->get_identifier_type(pdp_msg);
-
- if (pdp_id_type.vendor_id == PEN_TCG &&
- pdp_id_type.type == PB_PDP_ID_FQDN)
- {
- this->pdp_server = chunk_clone(pdp_msg->get_fqdn(pdp_msg,
- &pdp_protocol, &this->pdp_port));
- if (pdp_protocol != 0)
- {
- DBG1(DBG_TNC, "unsupported PDP transport protocol");
- break;
- }
- DBG1(DBG_TNC, "PDP server '%.*s' is listening on port %u",
- this->pdp_server.len, this->pdp_server.ptr,
- this->pdp_port);
- }
- break;
- }
- default:
- break;
- }
-}
-
-/**
- * Handle a single PB-TNC message according to its type
- */
-static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
-{
- pen_type_t msg_type = msg->get_type(msg);
-
- switch (msg_type.vendor_id)
- {
- case PEN_IETF:
- handle_ietf_message(this, msg);
- break;
- case PEN_TCG:
- handle_tcg_message(this, msg);
- break;
- default:
- break;
- }
-}
-
-/**
- * Build a CRETRY or SRETRY batch
- */
-static void build_retry_batch(private_tnccs_20_t *this)
-{
- pb_tnc_batch_type_t batch_retry_type;
-
- batch_retry_type = this->is_server ? PB_BATCH_SRETRY : PB_BATCH_CRETRY;
- if (this->batch_type == batch_retry_type)
- {
- /* retry batch has already been selected */
- return;
- }
-
- change_batch_type(this, batch_retry_type);
-
- if (this->is_server)
- {
- this->recs->clear_recommendation(this->recs);
- tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
- TNC_CONNECTION_STATE_HANDSHAKE);
- }
-}
-
METHOD(tls_t, process, status_t,
private_tnccs_20_t *this, void *buf, size_t buflen)
{
- chunk_t data;
pb_tnc_batch_t *batch;
- pb_tnc_msg_t *msg;
- enumerator_t *enumerator;
- identification_t *pdp_server;
- u_int16_t *pdp_port;
+ bool from_server, fatal_header_error = FALSE;
status_t status;
+ chunk_t data;
- if (this->is_server && !this->connection_id)
+ /* On arrival of first batch from TNC client create TNC server */
+ if (this->is_server && !this->tnc_server)
{
- this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
- TNCCS_2_0, (tnccs_t*)this, _send_msg,
- &this->request_handshake_retry,
- this->max_msg_len, &this->recs);
- if (!this->connection_id)
+ this->tnc_server = tnccs_20_server_create(&this->public, _send_msg,
+ this->max_batch_len, this->max_msg_len,
+ this->eap_transport);
+ if (!this->tnc_server)
{
return FAILED;
}
- tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
- TNC_CONNECTION_STATE_CREATE);
- tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
- TNC_CONNECTION_STATE_HANDSHAKE);
-
- /* Send a PB-TNC TCG PDP Referral message if PDP is known */
- pdp_server = (identification_t*)lib->get(lib, "pt-tls-server");
- pdp_port = (u_int16_t*)lib->get(lib, "pt-tls-port");
-
- if ((this->transport == TNC_IFT_EAP_1_1 ||
- this->transport == TNC_IFT_EAP_2_0) && pdp_server && pdp_port)
- {
- msg = pb_pdp_referral_msg_create_from_fqdn(
- pdp_server->get_encoding(pdp_server), *pdp_port);
- this->messages->insert_last(this->messages, msg);
- }
-
+ this->tnccs_handler = this->tnc_server;
+ this->tnccs_handler->begin_handshake(this->tnccs_handler, FALSE);
}
data = chunk_create(buf, buflen);
- DBG1(DBG_TNC, "received TNCCS batch (%u bytes) for Connection ID %u",
- data.len, this->connection_id);
+ DBG1(DBG_TNC, "received TNCCS batch (%u bytes)", data.len);
DBG3(DBG_TNC, "%B", &data);
- batch = pb_tnc_batch_create_from_data(this->is_server, data);
- status = batch->process(batch, this->state_machine);
- if (status != FAILED)
+ /* Parse the header of the received PB-TNC batch */
+ batch = pb_tnc_batch_create_from_data(data);
+ status = batch->process_header(batch, !this->mutual, this->is_server,
+ &from_server);
+ if (status == FAILED)
{
- enumerator_t *enumerator;
- pb_tnc_msg_t *msg;
- pb_tnc_batch_type_t batch_type;
- bool empty = TRUE;
-
- batch_type = batch->get_type(batch);
-
- if (batch_type == PB_BATCH_CRETRY)
- {
- /* Send an SRETRY batch in response */
- this->mutex->lock(this->mutex);
- build_retry_batch(this);
- this->mutex->unlock(this->mutex);
- }
- else if (batch_type == PB_BATCH_SRETRY)
- {
- /* Restart the measurements */
- tnc->imcs->notify_connection_change(tnc->imcs,
- this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
- this->send_msg = TRUE;
- tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
- this->send_msg = FALSE;
- }
-
- enumerator = batch->create_msg_enumerator(batch);
- while (enumerator->enumerate(enumerator, &msg))
- {
- handle_message(this, msg);
- empty = FALSE;
- }
- enumerator->destroy(enumerator);
+ fatal_header_error = TRUE;
+ status = VERIFY_ERROR;
+ }
+ this->to_server = this->mutual ? from_server : !this->is_server;
- /* received an empty CLOSE batch from PB-TNC client */
- if (this->is_server && batch_type == PB_BATCH_CLOSE && empty)
+ /* In the mutual case, first batch from TNC server requires a TNC client */
+ if (this->to_server && !this->tnc_client)
+ {
+ this->tnc_client = tnccs_20_client_create(&this->public, _send_msg,
+ this->max_batch_len, this->max_msg_len);
+ if (!this->tnc_client)
{
batch->destroy(batch);
- if (this->fatal_error)
- {
- DBG1(DBG_TNC, "a fatal PB-TNC error occurred, "
- "terminating connection");
- return FAILED;
- }
- else
- {
- return SUCCESS;
- }
- }
-
- this->send_msg = TRUE;
- if (this->is_server)
- {
- tnc->imvs->batch_ending(tnc->imvs, this->connection_id);
- }
- else
- {
- tnc->imcs->batch_ending(tnc->imcs, this->connection_id);
+ return FAILED;
}
- this->send_msg = FALSE;
+ this->tnccs_handler = this->tnc_client;
+ this->tnccs_handler->begin_handshake(this->tnccs_handler, this->mutual);
}
+ else
+ {
+ /* Set active TNCCS handler for processing */
+ this->tnccs_handler = this->to_server ? this->tnc_client :
+ this->tnc_server;
+ }
+ DBG2(DBG_TNC, "TNC %s is handling inbound connection",
+ this->to_server ? "client" : "server");
- switch (status)
+ if (status == SUCCESS)
{
- case FAILED:
- this->fatal_error = TRUE;
- this->mutex->lock(this->mutex);
- change_batch_type(this, PB_BATCH_CLOSE);
- this->mutex->unlock(this->mutex);
- /* fall through to add error messages to outbound batch */
- case VERIFY_ERROR:
- enumerator = batch->create_error_enumerator(batch);
- while (enumerator->enumerate(enumerator, &msg))
- {
- this->mutex->lock(this->mutex);
- this->messages->insert_last(this->messages, msg->get_ref(msg));
- this->mutex->unlock(this->mutex);
- }
- enumerator->destroy(enumerator);
- break;
- case SUCCESS:
- default:
- break;
+ status = this->tnccs_handler->process(this->tnccs_handler, batch);
+ }
+ if (status == VERIFY_ERROR)
+ {
+ this->tnccs_handler->handle_errors(this->tnccs_handler, batch,
+ fatal_header_error);
+ status = NEED_MORE;
}
batch->destroy(batch);
- return NEED_MORE;
-}
+ /* Has a mutual connection been established? */
+ this->mutual = this->is_server ?
+ this->tnc_server->get_mutual(this->tnc_server) :
+ this->tnc_client->get_mutual(this->tnc_client);
-/**
- * Build a RESULT batch if a final recommendation is available
- */
-static void check_and_build_recommendation(private_tnccs_20_t *this)
-{
- TNC_IMV_Action_Recommendation rec;
- TNC_IMV_Evaluation_Result eval;
- TNC_ConnectionState state;
- TNC_IMVID id;
- chunk_t reason, language;
- enumerator_t *enumerator;
- pb_tnc_msg_t *msg;
- pb_access_recommendation_code_t pb_rec;
-
- if (!this->recs->have_recommendation(this->recs, &rec, &eval))
- {
- tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id);
- }
- if (this->recs->have_recommendation(this->recs, &rec, &eval))
+ if (this->mutual && !this->is_server)
{
- this->batch_type = PB_BATCH_RESULT;
+ pb_tnc_state_t client_state, server_state;
- msg = pb_assessment_result_msg_create(eval);
- this->messages->insert_last(this->messages, msg);
+ client_state = !this->tnc_client ? PB_STATE_INIT :
+ this->tnc_client->get_state(this->tnc_client);
+ server_state = !this->tnc_server ? PB_STATE_INIT :
+ this->tnc_server->get_state(this->tnc_server);
- /**
- * Map IMV Action Recommendation codes to PB Access Recommendation codes
- * and communicate Access Recommendation to IMVs
- */
- switch (rec)
+ /* In half-duplex mutual mode toggle the direction on the client side */
+ if ((!this->to_server && client_state != PB_STATE_DECIDED) ||
+ ( this->to_server && server_state != PB_STATE_END))
{
- case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
- state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
- pb_rec = PB_REC_ACCESS_ALLOWED;
- break;
- case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
- state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
- pb_rec = PB_REC_QUARANTINED;
- break;
- case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
- case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
- default:
- state = TNC_CONNECTION_STATE_ACCESS_NONE;
- pb_rec = PB_REC_ACCESS_DENIED;
+ this->to_server = !this->to_server;
+ }
+ else if (client_state == PB_STATE_DECIDED &&
+ server_state == PB_STATE_END)
+ {
+ /* Cause the final CLOSE batch to be sent to the TNC server */
+ this->to_server = TRUE;
}
- tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
- state);
-
- msg = pb_access_recommendation_msg_create(pb_rec);
- this->messages->insert_last(this->messages, msg);
- enumerator = this->recs->create_reason_enumerator(this->recs);
- while (enumerator->enumerate(enumerator, &id, &reason, &language))
+ /* Suppress a successful CLOSE batch coming from the TNC server */
+ if (status == SUCCESS)
{
- msg = pb_reason_string_msg_create(reason, language);
- this->messages->insert_last(this->messages, msg);
+ status = NEED_MORE;
}
- enumerator->destroy(enumerator);
}
+
+ return status;
}
METHOD(tls_t, build, status_t,
private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen)
{
- status_t status;
- pb_tnc_state_t state;
-
- /* Initialize the connection */
- if (!this->is_server && !this->connection_id)
- {
- pb_tnc_msg_t *msg;
- char *pref_lang;
-
- this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
- TNCCS_2_0, (tnccs_t*)this, _send_msg,
- &this->request_handshake_retry,
- this->max_msg_len, NULL);
- if (!this->connection_id)
- {
- return FAILED;
- }
-
- /* Create PB-TNC Language Preference message */
- pref_lang = tnc->imcs->get_preferred_language(tnc->imcs);
- msg = pb_language_preference_msg_create(chunk_create(pref_lang,
- strlen(pref_lang)));
- this->mutex->lock(this->mutex);
- this->batch_type = PB_BATCH_CDATA;
- this->messages->insert_last(this->messages, msg);
- this->mutex->unlock(this->mutex);
-
- tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
- TNC_CONNECTION_STATE_CREATE);
- tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
- TNC_CONNECTION_STATE_HANDSHAKE);
- this->send_msg = TRUE;
- tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
- this->send_msg = FALSE;
- }
-
- state = this->state_machine->get_state(this->state_machine);
-
- if (this->fatal_error && state == PB_STATE_END)
- {
- DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection");
- return FAILED;
- }
-
- /* Do not allow any asynchronous IMCs or IMVs to add additional messages */
- this->mutex->lock(this->mutex);
-
- if (this->request_handshake_retry)
- {
- if (state != PB_STATE_INIT)
- {
- build_retry_batch(this);
- }
-
- /* Reset the flag for the next handshake retry request */
- this->request_handshake_retry = FALSE;
- }
-
- if (this->is_server && state == PB_STATE_SERVER_WORKING &&
- this->recs->have_recommendation(this->recs, NULL, NULL))
+ if (this->to_server)
{
- check_and_build_recommendation(this);
- }
+ DBG2(DBG_TNC, "TNC client is handling outbound connection");
- if (this->batch_type == PB_BATCH_NONE)
- {
- if (this->is_server)
+ /* Before sending the first PB-TNC batch create TNC client */
+ if (this->tnc_client)
{
- if (state == PB_STATE_SERVER_WORKING)
- {
- if (this->state_machine->get_empty_cdata(this->state_machine))
- {
- check_and_build_recommendation(this);
- }
- else
- {
- DBG2(DBG_TNC, "no recommendation available yet, "
- "sending empty PB-TNC SDATA batch");
- this->batch_type = PB_BATCH_SDATA;
- }
- }
+ this->tnccs_handler = this->tnc_client;
}
else
{
- switch (state)
+ this->tnc_client = tnccs_20_client_create(&this->public, _send_msg,
+ this->max_batch_len,
+ this->max_msg_len);
+ if (!this->tnc_client)
{
- case PB_STATE_CLIENT_WORKING:
- DBG2(DBG_TNC, "no client data to send, "
- "sending empty PB-TNC CDATA batch");
- this->batch_type = PB_BATCH_CDATA;
- break;
- case PB_STATE_DECIDED:
- /**
- * In the DECIDED state and if no CRETRY is under way,
- * a PB-TNC client replies with an empty CLOSE batch.
- */
- this->batch_type = PB_BATCH_CLOSE;
- break;
- default:
- break;
+ return FAILED;
}
+ this->tnccs_handler = this->tnc_client;
+ this->tnccs_handler->begin_handshake(this->tnccs_handler,
+ this->mutual);
}
}
-
- if (this->batch_type != PB_BATCH_NONE)
+ else
{
- pb_tnc_batch_t *batch;
- pb_tnc_msg_t *msg;
- chunk_t data;
- int msg_count;
- enumerator_t *enumerator;
+ DBG2(DBG_TNC, "TNC server is handling outbound connection");
- if (this->state_machine->send_batch(this->state_machine, this->batch_type))
+ /* Before sending the first PB-TNC batch create TNC server */
+ if (this->tnc_server)
{
- batch = pb_tnc_batch_create(this->is_server, this->batch_type,
- min(this->max_batch_len, *buflen));
-
- enumerator = this->messages->create_enumerator(this->messages);
- while (enumerator->enumerate(enumerator, &msg))
- {
- if (batch->add_msg(batch, msg))
- {
- this->messages->remove_at(this->messages, enumerator);
- }
- else
- {
- break;
- }
- }
- enumerator->destroy(enumerator);
-
- batch->build(batch);
- data = batch->get_encoding(batch);
- DBG1(DBG_TNC, "sending PB-TNC %N batch (%d bytes) for Connection ID %u",
- pb_tnc_batch_type_names, this->batch_type, data.len,
- this->connection_id);
- DBG3(DBG_TNC, "%B", &data);
-
- *buflen = data.len;
- *msglen = 0;
- memcpy(buf, data.ptr, *buflen);
- batch->destroy(batch);
-
- msg_count = this->messages->get_count(this->messages);
- if (msg_count)
- {
- DBG2(DBG_TNC, "queued %d PB-TNC message%s for next %N batch",
- msg_count, (msg_count == 1) ? "" : "s",
- pb_tnc_batch_type_names, this->batch_type);
- }
- else
- {
- this->batch_type = PB_BATCH_NONE;
- }
-
- status = ALREADY_DONE;
+ this->tnccs_handler = this->tnc_server;
}
else
{
- change_batch_type(this, PB_BATCH_NONE);
- status = INVALID_STATE;
+ this->tnc_server = tnccs_20_server_create(&this->public, _send_msg,
+ this->max_batch_len, this->max_msg_len,
+ this->eap_transport);
+ if (!this->tnc_server)
+ {
+ return FAILED;
+ }
+ this->tnccs_handler = this->tnc_server;
+ this->tnccs_handler->begin_handshake(this->tnccs_handler,
+ this->mutual);
}
}
- else
- {
- DBG1(DBG_TNC, "no PB-TNC batch to send");
- status = INVALID_STATE;
- }
- this->mutex->unlock(this->mutex);
-
- return status;
+ return this->tnccs_handler->build(this->tnccs_handler, buf, buflen, msglen);
}
METHOD(tls_t, is_server, bool,
@@ -923,20 +337,20 @@ METHOD(tls_t, is_server, bool,
METHOD(tls_t, get_server_id, identification_t*,
private_tnccs_20_t *this)
{
- return this->server;
+ return this->server_id;
}
METHOD(tls_t, set_peer_id, void,
private_tnccs_20_t *this, identification_t *id)
{
- DESTROY_IF(this->peer);
- this->peer = id->clone(id);
+ DESTROY_IF(this->peer_id);
+ this->peer_id = id->clone(id);
}
METHOD(tls_t, get_peer_id, identification_t*,
private_tnccs_20_t *this)
{
- return this->peer;
+ return this->peer_id;
}
METHOD(tls_t, get_purpose, tls_purpose_t,
@@ -951,14 +365,17 @@ METHOD(tls_t, is_complete, bool,
TNC_IMV_Action_Recommendation rec;
TNC_IMV_Evaluation_Result eval;
- if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
+ if (this->tnc_server)
{
- return this->callback ? this->callback(rec, eval) : TRUE;
- }
- else
- {
- return FALSE;
+ tnccs_20_server_t *tnc_server;
+
+ tnc_server = (tnccs_20_server_t*)this->tnc_server;
+ if (tnc_server->have_recommendation(tnc_server, &rec, &eval))
+ {
+ return this->callback ? this->callback(rec, eval) : TRUE;
+ }
}
+ return FALSE;
}
METHOD(tls_t, get_eap_msk, chunk_t,
@@ -972,19 +389,28 @@ METHOD(tls_t, destroy, void,
{
if (ref_put(&this->ref))
{
- tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
- this->is_server);
- this->server->destroy(this->server);
- this->peer->destroy(this->peer);
- this->state_machine->destroy(this->state_machine);
- this->mutex->destroy(this->mutex);
- this->messages->destroy_offset(this->messages,
- offsetof(pb_tnc_msg_t, destroy));
- free(this->pdp_server.ptr);
+ DESTROY_IF(this->tnc_server);
+ DESTROY_IF(this->tnc_client);
+ this->server_id->destroy(this->server_id);
+ this->peer_id->destroy(this->peer_id);
+ this->server_ip->destroy(this->server_ip);
+ this->peer_ip->destroy(this->peer_ip);
free(this);
}
}
+METHOD(tnccs_t, get_server_ip, host_t*,
+ private_tnccs_20_t *this)
+{
+ return this->server_ip;
+}
+
+METHOD(tnccs_t, get_peer_ip, host_t*,
+ private_tnccs_20_t *this)
+{
+ return this->peer_ip;
+}
+
METHOD(tnccs_t, get_transport, tnc_ift_type_t,
private_tnccs_20_t *this)
{
@@ -1012,9 +438,19 @@ METHOD(tnccs_t, set_auth_type, void,
METHOD(tnccs_t, get_pdp_server, chunk_t,
private_tnccs_20_t *this, u_int16_t *port)
{
- *port = this->pdp_port;
+ if (this->tnc_client)
+ {
+ tnccs_20_client_t *tnc_client;
+
+ tnc_client = (tnccs_20_client_t*)this->tnc_client;
- return this->pdp_server;
+ return tnc_client->get_pdp_server(tnc_client, port);
+ }
+ else
+ {
+ *port = 0;
+ return chunk_empty;
+ }
}
METHOD(tnccs_t, get_ref, tnccs_t*,
@@ -1027,9 +463,10 @@ METHOD(tnccs_t, get_ref, tnccs_t*,
/**
* See header
*/
-tnccs_t* tnccs_20_create(bool is_server,
- identification_t *server, identification_t *peer,
- tnc_ift_type_t transport, tnccs_cb_t cb)
+tnccs_t* tnccs_20_create(bool is_server, identification_t *server_id,
+ identification_t *peer_id, host_t *server_ip,
+ host_t *peer_ip, tnc_ift_type_t transport,
+ tnccs_cb_t cb)
{
private_tnccs_20_t *this;
size_t max_batch_size, default_max_batch_size;
@@ -1079,6 +516,8 @@ tnccs_t* tnccs_20_create(bool is_server,
.get_eap_msk = _get_eap_msk,
.destroy = _destroy,
},
+ .get_server_ip = _get_server_ip,
+ .get_peer_ip = _get_peer_ip,
.get_transport = _get_transport,
.set_transport = _set_transport,
.get_auth_type = _get_auth_type,
@@ -1087,13 +526,15 @@ tnccs_t* tnccs_20_create(bool is_server,
.get_ref = _get_ref,
},
.is_server = is_server,
- .server = server->clone(server),
- .peer = peer->clone(peer),
+ .to_server = !is_server,
+ .server_id = server_id->clone(server_id),
+ .peer_id = peer_id->clone(peer_id),
+ .server_ip = server_ip->clone(server_ip),
+ .peer_ip = peer_ip->clone(peer_ip),
.transport = transport,
+ .eap_transport = transport == TNC_IFT_EAP_1_1 ||
+ transport == TNC_IFT_EAP_2_0,
.callback = cb,
- .state_machine = pb_tnc_state_machine_create(is_server),
- .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
- .messages = linked_list_create(),
.max_batch_len = max_batch_size,
.max_msg_len = max_message_size,
.ref = 1,
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20.h b/src/libtnccs/plugins/tnccs_20/tnccs_20.h
index 2857b1408..010cbecdc 100644
--- a/src/libtnccs/plugins/tnccs_20/tnccs_20.h
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20.h
@@ -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
@@ -29,14 +29,17 @@
* Create an instance of the TNC IF-TNCCS 2.0 protocol handler.
*
* @param is_server TRUE to act as TNC Server, FALSE for TNC Client
- * @param server Server identity
- * @param peer Client identity
+ * @param server_id Server identity
+ * @param peer_id Client identity
+ * @param server_ip Server IP address
+ * @param peer_ip Client IP address
* @param transport Underlying IF-T transport protocol
* @param cb Callback function if TNC Server, NULL if TNC Client
* @return TNC_IF_TNCCS 2.0 protocol stack
*/
-tnccs_t* tnccs_20_create(bool is_server,
- identification_t *server, identification_t *peer,
- tnc_ift_type_t transport, tnccs_cb_t cb);
+tnccs_t* tnccs_20_create(bool is_server, identification_t *server_id,
+ identification_t *peer_id, host_t *server_ip,
+ host_t *peer_ip, tnc_ift_type_t transport,
+ tnccs_cb_t cb);
#endif /** TNCCS_20_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c
new file mode 100644
index 000000000..4ba8221d0
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c
@@ -0,0 +1,820 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "tnccs_20_client.h"
+#include "messages/pb_tnc_msg.h"
+#include "messages/ietf/pb_pa_msg.h"
+#include "messages/ietf/pb_error_msg.h"
+#include "messages/ietf/pb_assessment_result_msg.h"
+#include "messages/ietf/pb_access_recommendation_msg.h"
+#include "messages/ietf/pb_remediation_parameters_msg.h"
+#include "messages/ietf/pb_reason_string_msg.h"
+#include "messages/ietf/pb_language_preference_msg.h"
+#include "messages/ita/pb_mutual_capability_msg.h"
+#include "messages/ita/pb_noskip_test_msg.h"
+#include "messages/tcg/pb_pdp_referral_msg.h"
+#include "state_machine/pb_tnc_state_machine.h"
+
+#include <tncif_names.h>
+#include <tncif_pa_subtypes.h>
+
+#include <tnc/tnc.h>
+#include <tnc/tnccs/tnccs_manager.h>
+#include <tnc/imc/imc_manager.h>
+
+#include <threading/mutex.h>
+#include <utils/debug.h>
+#include <collections/linked_list.h>
+#include <pen/pen.h>
+
+typedef struct private_tnccs_20_client_t private_tnccs_20_client_t;
+
+/**
+ * Private data of a tnccs_20_client_t object.
+ */
+struct private_tnccs_20_client_t {
+
+ /**
+ * Public tnccs_20_client_t interface.
+ */
+ tnccs_20_client_t public;
+
+ /**
+ * PB-TNC State Machine
+ */
+ pb_tnc_state_machine_t *state_machine;
+
+ /**
+ * Connection ID assigned to this TNCCS connection
+ */
+ TNC_ConnectionID connection_id;
+
+ /**
+ * PB-TNC messages to be sent
+ */
+ linked_list_t *messages;
+
+ /**
+ * Type of PB-TNC batch being constructed
+ */
+ pb_tnc_batch_type_t batch_type;
+
+ /**
+ * Maximum PB-TNC batch size
+ */
+ size_t max_batch_len;
+
+ /**
+ * Mutex locking the batch in construction
+ */
+ mutex_t *mutex;
+
+ /**
+ * Flag set while processing
+ */
+ bool fatal_error;
+
+ /**
+ * Flag set by IMC RequestHandshakeRetry() function
+ */
+ bool request_handshake_retry;
+
+ /**
+ * SendMessage() by IMC only allowed if flag is set
+ */
+ bool send_msg;
+
+ /**
+ * PDP server FQDN
+ */
+ chunk_t pdp_server;
+
+ /**
+ * PDP server port
+ */
+ u_int16_t pdp_port;
+
+ /**
+ * Mutual PB-TNC protocol enabled
+ */
+ bool mutual;
+
+ /**
+ * Mutual Capability message sent
+ */
+ bool sent_mutual_capability;
+
+};
+
+/**
+ * The following two functions are shared with the tnccs_20_server class
+ */
+void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg, bool *fatal_error)
+{
+ pb_error_msg_t *err_msg;
+ u_int32_t vendor_id;
+ u_int16_t error_code;
+ bool fatal;
+
+ err_msg = (pb_error_msg_t*)msg;
+ fatal = err_msg->get_fatal_flag(err_msg);
+ vendor_id = err_msg->get_vendor_id(err_msg);
+ error_code = err_msg->get_error_code(err_msg);
+
+ if (fatal)
+ {
+ *fatal_error = TRUE;
+ }
+
+ if (vendor_id == PEN_IETF)
+ {
+ switch (error_code)
+ {
+ case PB_ERROR_INVALID_PARAMETER:
+ case PB_ERROR_UNSUPPORTED_MANDATORY_MSG:
+ DBG1(DBG_TNC, "received %s PB-TNC error '%N' (offset %u bytes)",
+ fatal ? "fatal" : "non-fatal",
+ pb_tnc_error_code_names, error_code,
+ err_msg->get_offset(err_msg));
+ break;
+ case PB_ERROR_VERSION_NOT_SUPPORTED:
+ DBG1(DBG_TNC, "received %s PB-TNC error '%N' "
+ "caused by bad version 0x%02x",
+ fatal ? "fatal" : "non-fatal",
+ pb_tnc_error_code_names, error_code,
+ err_msg->get_bad_version(err_msg));
+ break;
+ case PB_ERROR_UNEXPECTED_BATCH_TYPE:
+ case PB_ERROR_LOCAL_ERROR:
+ default:
+ DBG1(DBG_TNC, "received %s PB-TNC error '%N'",
+ fatal ? "fatal" : "non-fatal",
+ pb_tnc_error_code_names, error_code);
+ break;
+ }
+ }
+ else
+ {
+ DBG1(DBG_TNC, "received %s PB-TNC error (%u) with Vendor ID 0x%06x",
+ fatal ? "fatal" : "non-fatal", error_code, vendor_id);
+ }
+}
+
+bool tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg)
+{
+ pb_mutual_capability_msg_t *mutual_msg;
+ uint32_t protocols;
+
+ if (!lib->settings->get_bool(lib->settings,
+ "%s.plugins.tnccs-20.mutual", FALSE, lib->ns))
+ {
+ /* PB-TNC mutual capability disabled, ignore message */
+ return FALSE;
+ }
+
+ mutual_msg = (pb_mutual_capability_msg_t*)msg;
+ protocols = mutual_msg->get_protocols(mutual_msg);
+
+ if (protocols & PB_MUTUAL_HALF_DUPLEX)
+ {
+ DBG1(DBG_TNC, "activating mutual PB-TNC %N protocol",
+ pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * If the batch type changes then delete all accumulated PB-TNC messages
+ */
+static void change_batch_type(private_tnccs_20_client_t *this,
+ pb_tnc_batch_type_t batch_type)
+{
+ pb_tnc_msg_t *msg;
+
+ if (batch_type != this->batch_type)
+ {
+ if (this->batch_type != PB_BATCH_NONE)
+ {
+ DBG1(DBG_TNC, "cancelling PB-TNC %N batch",
+ pb_tnc_batch_type_names, this->batch_type);
+
+ while (this->messages->remove_last(this->messages,
+ (void**)&msg) == SUCCESS)
+ {
+ msg->destroy(msg);
+ }
+ }
+ this->batch_type = batch_type;
+ }
+}
+
+/**
+ * Handle a single PB-TNC IETF standard message according to its type
+ */
+static void handle_ietf_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
+{
+ pen_type_t msg_type = msg->get_type(msg);
+
+ switch (msg_type.type)
+ {
+ case PB_MSG_EXPERIMENTAL:
+ /* nothing to do */
+ break;
+ case PB_MSG_PA:
+ {
+ pb_pa_msg_t *pa_msg;
+ pen_type_t msg_subtype;
+ u_int16_t imc_id, imv_id;
+ chunk_t msg_body;
+ bool excl;
+ enum_name_t *pa_subtype_names;
+
+ pa_msg = (pb_pa_msg_t*)msg;
+ msg_subtype = pa_msg->get_subtype(pa_msg);
+ msg_body = pa_msg->get_body(pa_msg);
+ imc_id = pa_msg->get_collector_id(pa_msg);
+ imv_id = pa_msg->get_validator_id(pa_msg);
+ excl = pa_msg->get_exclusive_flag(pa_msg);
+
+ pa_subtype_names = get_pa_subtype_names(msg_subtype.vendor_id);
+ if (pa_subtype_names)
+ {
+ DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x",
+ pen_names, msg_subtype.vendor_id, pa_subtype_names,
+ msg_subtype.type, msg_subtype.vendor_id, msg_subtype.type);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x",
+ pen_names, msg_subtype.vendor_id, msg_subtype.vendor_id,
+ msg_subtype.type);
+ }
+ this->send_msg = TRUE;
+ tnc->imcs->receive_message(tnc->imcs, this->connection_id,
+ excl, msg_body.ptr, msg_body.len,
+ msg_subtype.vendor_id,
+ msg_subtype.type, imv_id, imc_id);
+ this->send_msg = FALSE;
+ break;
+ }
+ case PB_MSG_ASSESSMENT_RESULT:
+ {
+ pb_assessment_result_msg_t *assess_msg;
+ u_int32_t result;
+
+ assess_msg = (pb_assessment_result_msg_t*)msg;
+ result = assess_msg->get_assessment_result(assess_msg);
+ DBG1(DBG_TNC, "PB-TNC assessment result is '%N'",
+ TNC_IMV_Evaluation_Result_names, result);
+ break;
+ }
+ case PB_MSG_ACCESS_RECOMMENDATION:
+ {
+ pb_access_recommendation_msg_t *rec_msg;
+ pb_access_recommendation_code_t rec;
+ TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE;
+
+ rec_msg = (pb_access_recommendation_msg_t*)msg;
+ rec = rec_msg->get_access_recommendation(rec_msg);
+ DBG1(DBG_TNC, "PB-TNC access recommendation is '%N'",
+ pb_access_recommendation_code_names, rec);
+ switch (rec)
+ {
+ case PB_REC_ACCESS_ALLOWED:
+ state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
+ break;
+ case PB_REC_ACCESS_DENIED:
+ state = TNC_CONNECTION_STATE_ACCESS_NONE;
+ break;
+ case PB_REC_QUARANTINED:
+ state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
+ }
+ tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+ state);
+ break;
+ }
+ case PB_MSG_REMEDIATION_PARAMETERS:
+ {
+ pb_remediation_parameters_msg_t *rem_msg;
+ pen_type_t parameters_type;
+ chunk_t parameters, string, lang_code;
+
+ rem_msg = (pb_remediation_parameters_msg_t*)msg;
+ parameters_type = rem_msg->get_parameters_type(rem_msg);
+ parameters = rem_msg->get_parameters(rem_msg);
+
+ if (parameters_type.vendor_id == PEN_IETF)
+ {
+ switch (parameters_type.type)
+ {
+ case PB_REMEDIATION_URI:
+ DBG1(DBG_TNC, "remediation uri: %.*s",
+ parameters.len, parameters.ptr);
+ break;
+ case PB_REMEDIATION_STRING:
+ string = rem_msg->get_string(rem_msg, &lang_code);
+ DBG1(DBG_TNC, "remediation string: [%.*s]\n%.*s",
+ lang_code.len, lang_code.ptr,
+ string.len, string.ptr);
+ break;
+ default:
+ DBG1(DBG_TNC, "remediation parameters: %B", &parameters);
+ }
+ }
+ else
+ {
+ DBG1(DBG_TNC, "remediation parameters: %B", &parameters);
+ }
+ break;
+ }
+ case PB_MSG_ERROR:
+ tnccs_20_handle_ietf_error_msg(msg, &this->fatal_error);
+ break;
+ case PB_MSG_REASON_STRING:
+ {
+ pb_reason_string_msg_t *reason_msg;
+ chunk_t reason_string, language_code;
+
+ reason_msg = (pb_reason_string_msg_t*)msg;
+ reason_string = reason_msg->get_reason_string(reason_msg);
+ language_code = reason_msg->get_language_code(reason_msg);
+ DBG1(DBG_TNC, "reason string is '%.*s' [%.*s]",
+ (int)reason_string.len, reason_string.ptr,
+ (int)language_code.len, language_code.ptr);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/**
+ * Handle a single PB-TNC TCG standard message according to its type
+ */
+static void handle_tcg_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
+{
+ pen_type_t msg_type = msg->get_type(msg);
+
+ switch (msg_type.type)
+ {
+ case PB_TCG_MSG_PDP_REFERRAL:
+ {
+ pb_pdp_referral_msg_t *pdp_msg;
+ pen_type_t pdp_id_type;
+ u_int8_t pdp_protocol;
+
+ pdp_msg = (pb_pdp_referral_msg_t*)msg;
+ pdp_id_type = pdp_msg->get_identifier_type(pdp_msg);
+
+ if (pdp_id_type.vendor_id == PEN_TCG &&
+ pdp_id_type.type == PB_PDP_ID_FQDN)
+ {
+ this->pdp_server = chunk_clone(pdp_msg->get_fqdn(pdp_msg,
+ &pdp_protocol, &this->pdp_port));
+ if (pdp_protocol != 0)
+ {
+ DBG1(DBG_TNC, "unsupported PDP transport protocol");
+ break;
+ }
+ DBG1(DBG_TNC, "PDP server '%.*s' is listening on port %u",
+ this->pdp_server.len, this->pdp_server.ptr,
+ this->pdp_port);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/**
+ * Handle a single PB-TNC ITA standard message according to its type
+ */
+static void handle_ita_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
+{
+ pen_type_t msg_type = msg->get_type(msg);
+
+ switch (msg_type.type)
+ {
+ case PB_ITA_MSG_MUTUAL_CAPABILITY:
+ this->mutual = tnccs_20_handle_ita_mutual_capability_msg(msg);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Handle a single PB-TNC message according to its type
+ */
+static void handle_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
+{
+ pen_type_t msg_type = msg->get_type(msg);
+
+ switch (msg_type.vendor_id)
+ {
+ case PEN_IETF:
+ handle_ietf_message(this, msg);
+ break;
+ case PEN_TCG:
+ handle_tcg_message(this, msg);
+ break;
+ case PEN_ITA:
+ handle_ita_message(this, msg);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Build a CRETRY batch
+ */
+static void build_retry_batch(private_tnccs_20_client_t *this)
+{
+ if (this->batch_type == PB_BATCH_CRETRY)
+ {
+ /* retry batch has already been selected */
+ return;
+ }
+ change_batch_type(this, PB_BATCH_CRETRY);
+}
+
+METHOD(tnccs_20_handler_t, process, status_t,
+ private_tnccs_20_client_t *this, pb_tnc_batch_t *batch)
+{
+ pb_tnc_batch_type_t batch_type;
+ status_t status;
+
+ batch_type = batch->get_type(batch);
+
+ DBG1(DBG_TNC, "processing PB-TNC %N batch for Connection ID %d",
+ pb_tnc_batch_type_names, batch_type, this->connection_id);
+
+ status = batch->process(batch, this->state_machine);
+
+ if (status != FAILED)
+ {
+ enumerator_t *enumerator;
+ pb_tnc_msg_t *msg;
+ bool empty = TRUE;
+
+ if (batch_type == PB_BATCH_SRETRY)
+ {
+ /* Restart the measurements */
+ tnc->imcs->notify_connection_change(tnc->imcs,
+ this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+ this->send_msg = TRUE;
+ tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
+ this->send_msg = FALSE;
+ }
+
+ enumerator = batch->create_msg_enumerator(batch);
+ while (enumerator->enumerate(enumerator, &msg))
+ {
+ handle_message(this, msg);
+ empty = FALSE;
+ }
+ enumerator->destroy(enumerator);
+
+ /* received a CLOSE batch from PB-TNC server */
+ if (batch_type == PB_BATCH_CLOSE)
+ {
+ return empty ? SUCCESS : FAILED;
+ }
+
+ this->send_msg = TRUE;
+ tnc->imcs->batch_ending(tnc->imcs, this->connection_id);
+ this->send_msg = FALSE;
+ }
+
+ switch (status)
+ {
+ case FAILED:
+ this->fatal_error = TRUE;
+ status = VERIFY_ERROR;
+ break;
+ case VERIFY_ERROR:
+ break;
+ case SUCCESS:
+ default:
+ status = NEED_MORE;
+ break;
+ }
+
+ return status;
+}
+
+METHOD(tnccs_20_handler_t, build, status_t,
+ private_tnccs_20_client_t *this, void *buf, size_t *buflen, size_t *msglen)
+{
+ status_t status;
+ pb_tnc_state_t state;
+
+ state = this->state_machine->get_state(this->state_machine);
+
+ if (this->fatal_error && state == PB_STATE_END)
+ {
+ DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection");
+ return FAILED;
+ }
+
+ /* Do not allow any asynchronous IMCs to add additional messages */
+ this->mutex->lock(this->mutex);
+
+ if (this->request_handshake_retry)
+ {
+ if (state != PB_STATE_INIT)
+ {
+ build_retry_batch(this);
+ }
+
+ /* Reset the flag for the next handshake retry request */
+ this->request_handshake_retry = FALSE;
+ }
+
+ if (this->batch_type == PB_BATCH_NONE)
+ {
+ switch (state)
+ {
+ case PB_STATE_CLIENT_WORKING:
+ DBG2(DBG_TNC, "no client data to send, "
+ "sending empty PB-TNC CDATA batch");
+ this->batch_type = PB_BATCH_CDATA;
+ break;
+ case PB_STATE_DECIDED:
+ /**
+ * In the DECIDED state and if no CRETRY is under way,
+ * a PB-TNC client replies with an empty CLOSE batch.
+ */
+ this->batch_type = PB_BATCH_CLOSE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (this->batch_type != PB_BATCH_NONE)
+ {
+ pb_tnc_batch_t *batch;
+ pb_tnc_msg_t *msg;
+ chunk_t data;
+ int msg_count;
+ enumerator_t *enumerator;
+
+ if (this->state_machine->send_batch(this->state_machine, this->batch_type))
+ {
+ batch = pb_tnc_batch_create(FALSE, this->batch_type,
+ min(this->max_batch_len, *buflen));
+
+ enumerator = this->messages->create_enumerator(this->messages);
+ while (enumerator->enumerate(enumerator, &msg))
+ {
+ if (batch->add_msg(batch, msg))
+ {
+ this->messages->remove_at(this->messages, enumerator);
+ }
+ else
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ batch->build(batch);
+ data = batch->get_encoding(batch);
+ DBG1(DBG_TNC, "sending PB-TNC %N batch (%d bytes) for Connection ID %u",
+ pb_tnc_batch_type_names, this->batch_type, data.len,
+ this->connection_id);
+ DBG3(DBG_TNC, "%B", &data);
+
+ *buflen = data.len;
+ *msglen = 0;
+ memcpy(buf, data.ptr, *buflen);
+ batch->destroy(batch);
+
+ msg_count = this->messages->get_count(this->messages);
+ if (msg_count)
+ {
+ DBG2(DBG_TNC, "queued %d PB-TNC message%s for next %N batch",
+ msg_count, (msg_count == 1) ? "" : "s",
+ pb_tnc_batch_type_names, this->batch_type);
+ }
+ else
+ {
+ this->batch_type = PB_BATCH_NONE;
+ }
+
+ status = ALREADY_DONE;
+ }
+ else
+ {
+ change_batch_type(this, PB_BATCH_NONE);
+ status = INVALID_STATE;
+ }
+ }
+ else
+ {
+ DBG1(DBG_TNC, "no PB-TNC batch to send");
+ status = INVALID_STATE;
+ }
+ this->mutex->unlock(this->mutex);
+
+ return status;
+}
+
+METHOD(tnccs_20_handler_t, begin_handshake, void,
+ private_tnccs_20_client_t *this, bool mutual)
+{
+ pb_tnc_msg_t *msg;
+ char *pref_lang;
+
+ tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+ TNC_CONNECTION_STATE_HANDSHAKE);
+
+ /* Announce PB-TNC Mutual Capability if activated */
+ this->sent_mutual_capability = mutual;
+
+ if (!mutual && lib->settings->get_bool(lib->settings,
+ "%s.plugins.tnccs-20.mutual", FALSE, lib->ns))
+ {
+ pb_tnc_mutual_protocol_type_t protocols;
+
+ protocols = PB_MUTUAL_HALF_DUPLEX;
+ DBG2(DBG_TNC, "proposing PB-TNC mutual %N protocol",
+ pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX);
+ msg = pb_mutual_capability_msg_create(protocols);
+ this->mutex->lock(this->mutex);
+ this->messages->insert_last(this->messages, msg);
+ this->mutex->unlock(this->mutex);
+ this->sent_mutual_capability = TRUE;
+ }
+
+ /* Create PB-TNC Language Preference message */
+ pref_lang = tnc->imcs->get_preferred_language(tnc->imcs);
+ msg = pb_language_preference_msg_create(chunk_create(pref_lang,
+ strlen(pref_lang)));
+ this->mutex->lock(this->mutex);
+ this->messages->insert_last(this->messages, msg);
+ this->mutex->unlock(this->mutex);
+
+ this->send_msg = TRUE;
+ tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
+ this->send_msg = FALSE;
+
+ /* Send a PB-Noskip-Test message for testing purposes */
+ if (lib->settings->get_bool(lib->settings,
+ "%s.plugins.tnccs-20.tests.pb_tnc_noskip", FALSE, lib->ns))
+ {
+ msg = pb_noskip_test_msg_create();
+ this->mutex->lock(this->mutex);
+ this->messages->insert_last(this->messages, msg);
+ this->mutex->unlock(this->mutex);
+ }
+}
+
+METHOD(tnccs_20_handler_t, get_send_flag, bool,
+ private_tnccs_20_client_t *this)
+{
+ return this->send_msg;
+}
+
+METHOD(tnccs_20_handler_t, get_mutual, bool,
+ private_tnccs_20_client_t *this)
+{
+ return this->mutual;
+}
+
+METHOD(tnccs_20_handler_t, get_state, pb_tnc_state_t,
+ private_tnccs_20_client_t *this)
+{
+ return this->state_machine->get_state(this->state_machine);
+}
+
+METHOD(tnccs_20_handler_t, add_msg, void,
+ private_tnccs_20_client_t *this, pb_tnc_msg_t *msg)
+{
+ /* adding PA message to CDATA batch only */
+ this->mutex->lock(this->mutex);
+ if (this->batch_type == PB_BATCH_NONE)
+ {
+ this->batch_type = PB_BATCH_CDATA;
+ }
+ if (this->batch_type == PB_BATCH_CDATA)
+ {
+ this->messages->insert_last(this->messages, msg);
+ }
+ else
+ {
+ msg->destroy(msg);
+ }
+ this->mutex->unlock(this->mutex);
+}
+
+METHOD(tnccs_20_handler_t, handle_errors, void,
+ private_tnccs_20_client_t *this, pb_tnc_batch_t *batch,
+ bool fatal_header_error)
+{
+ pb_tnc_msg_t *msg;
+ enumerator_t *enumerator;
+
+ if (fatal_header_error || this->fatal_error)
+ {
+ this->mutex->lock(this->mutex);
+ change_batch_type(this, PB_BATCH_CLOSE);
+ this->mutex->unlock(this->mutex);
+ }
+
+ enumerator = batch->create_error_enumerator(batch);
+ while (enumerator->enumerate(enumerator, &msg))
+ {
+ this->mutex->lock(this->mutex);
+ this->messages->insert_last(this->messages, msg->get_ref(msg));
+ this->mutex->unlock(this->mutex);
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(tnccs_20_handler_t, destroy, void,
+ private_tnccs_20_client_t *this)
+{
+ if (this->connection_id)
+ {
+ tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id, FALSE);
+ }
+ this->state_machine->destroy(this->state_machine);
+ this->mutex->destroy(this->mutex);
+ this->messages->destroy_offset(this->messages,
+ offsetof(pb_tnc_msg_t, destroy));
+ free(this->pdp_server.ptr);
+ free(this);
+}
+
+METHOD(tnccs_20_client_t, get_pdp_server, chunk_t,
+ private_tnccs_20_client_t *this, u_int16_t *port)
+{
+ *port = this->pdp_port;
+
+ return this->pdp_server;
+}
+
+/**
+ * See header
+ */
+tnccs_20_handler_t* tnccs_20_client_create(tnccs_t *tnccs,
+ tnccs_send_message_t send_msg,
+ size_t max_batch_len,
+ size_t max_msg_len)
+{
+ private_tnccs_20_client_t *this;
+
+ INIT(this,
+ .public = {
+ .handler = {
+ .process = _process,
+ .build = _build,
+ .begin_handshake = _begin_handshake,
+ .get_send_flag = _get_send_flag,
+ .get_mutual = _get_mutual,
+ .get_state = _get_state,
+ .add_msg = _add_msg,
+ .handle_errors = _handle_errors,
+ .destroy = _destroy,
+ },
+ .get_pdp_server = _get_pdp_server,
+ },
+ .state_machine = pb_tnc_state_machine_create(FALSE),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .messages = linked_list_create(),
+ .batch_type = PB_BATCH_CDATA,
+ .max_batch_len = max_batch_len,
+ );
+
+ this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
+ TNCCS_2_0, tnccs, send_msg,
+ &this->request_handshake_retry,
+ max_msg_len, NULL);
+ if (!this->connection_id)
+ {
+ destroy(this);
+ return NULL;
+ }
+ tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+ TNC_CONNECTION_STATE_CREATE);
+
+ return &this->public.handler;
+}
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_client.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.h
new file mode 100644
index 000000000..7a5f33ebc
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tnccs_20_client_h tnccs_20_client
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef TNCCS_20_CLIENT_H_
+#define TNCCS_20_CLIENT_H_
+
+#include <library.h>
+
+#include <tnc/tnccs/tnccs.h>
+
+#include "tnccs_20_handler.h"
+
+typedef struct tnccs_20_client_t tnccs_20_client_t;
+
+/**
+ * Interface for a TNC client
+ */
+struct tnccs_20_client_t {
+
+ /**
+ * IF-TNCCS 2.0 protocol handler interface
+ */
+ tnccs_20_handler_t handler;
+
+ /**
+ * Get PDP server information if available
+ *
+ * @param port PT-TLS port of the PDP server
+ * @return FQDN of PDP server
+ */
+ chunk_t (*get_pdp_server)(tnccs_20_client_t *this, u_int16_t *port);
+
+};
+
+/**
+ * Create an instance of the TNC IF-TNCCS 2.0 client-side protocol handler.
+ *
+ * @param tnccs TNC IF-TNCCS 2.0 stack
+ * @param send_msg TNF IF-TNCCS 2.0 send message callback function
+ * @param max_batch_len Maximum PB-TNC batch size
+ * @param max_msg_len Maximum PA-TNC message size
+ */
+tnccs_20_handler_t* tnccs_20_client_create(tnccs_t *tnccs,
+ tnccs_send_message_t send_msg,
+ size_t max_batch_len,
+ size_t max_msg_len);
+
+#endif /** TNCCS_20_CLIENT_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h
new file mode 100644
index 000000000..5c4d7a7b4
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tnccs_20_handler_h tnccs_20_handler
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef TNCCS_20_HANDLER_H_
+#define TNCCS_20_HANDLER_H_
+
+#include <library.h>
+
+#include "batch/pb_tnc_batch.h"
+#include "messages/pb_tnc_msg.h"
+
+typedef struct tnccs_20_handler_t tnccs_20_handler_t;
+
+/**
+ * Interface for an IF-TNCCS 2.0 protocol handler
+ */
+struct tnccs_20_handler_t {
+
+ /**
+ * Process content of received PB-TNC batch
+ *
+ * @param batch PB-TNC batch to be processed
+ * @return status
+ */
+ status_t (*process)(tnccs_20_handler_t *this, pb_tnc_batch_t *batch);
+
+ /**
+ * Build PB-TNC batch to be sent
+ *
+ * @param buf buffer to write PB-TNC batch to
+ * @param buflen size of buffer, receives bytes written
+ * @param msglen receives size of all PB-TNCH batch
+ * @return status
+ */
+ status_t (*build)(tnccs_20_handler_t *this, void *buf, size_t *buflen,
+ size_t *msglen);
+
+ /**
+ * Put the IMCs or IMVs into the handshake state
+ *
+ * @param mutual TRUE if PB-TNC mutual mode is already established
+ */
+ void (*begin_handshake)(tnccs_20_handler_t *this, bool mutual);
+
+ /**
+ * Indicates if IMCs or IMVs are allowed to send PA-TNC messages
+ *
+ * @return TRUE if allowed to send
+ */
+ bool (*get_send_flag)(tnccs_20_handler_t *this);
+
+ /**
+ * Indicates if the PB-TNC mutual protocol has been enabled
+ *
+ * @return TRUE if enabled
+ */
+ bool (*get_mutual)(tnccs_20_handler_t *this);
+
+ /**
+ * Get state of the PB-TNC protocol
+ *
+ * @return PB-TNC state
+ */
+ pb_tnc_state_t (*get_state)(tnccs_20_handler_t *this);
+
+ /**
+ * Add a PB-PA message to the handler's message queue
+ *
+ * @param msg PB-PA message to be added
+ */
+ void (*add_msg)(tnccs_20_handler_t *this, pb_tnc_msg_t *msg);
+
+ /**
+ * Handle errors that occurred during PB-TNC batch header processing
+ *
+ * @param batch batch where a fatal error occurred
+ * @param fatal_header_error TRUE if fatal error in batch header
+ */
+ void (*handle_errors)(tnccs_20_handler_t *this, pb_tnc_batch_t *batch,
+ bool fatal_header_error);
+
+ /**
+ * Destroys a tnccs_20_handler_t object.
+ */
+ void (*destroy)(tnccs_20_handler_t *this);
+};
+
+#endif /** TNCCS_20_HANDLER_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h
index 1c4ecf4c9..5073fbe7c 100644
--- a/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h
@@ -15,7 +15,7 @@
/**
* @defgroup tnccs_20 tnccs_20
- * @ingroup cplugins
+ * @ingroup tplugins
*
* @defgroup tnccs_20_plugin tnccs_20_plugin
* @{ @ingroup tnccs_20
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c
new file mode 100644
index 000000000..038fc178b
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c
@@ -0,0 +1,693 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "tnccs_20_server.h"
+#include "messages/pb_tnc_msg.h"
+#include "messages/ietf/pb_pa_msg.h"
+#include "messages/ietf/pb_error_msg.h"
+#include "messages/ietf/pb_assessment_result_msg.h"
+#include "messages/ietf/pb_access_recommendation_msg.h"
+#include "messages/ietf/pb_remediation_parameters_msg.h"
+#include "messages/ietf/pb_reason_string_msg.h"
+#include "messages/ietf/pb_language_preference_msg.h"
+#include "messages/ita/pb_mutual_capability_msg.h"
+#include "messages/ita/pb_noskip_test_msg.h"
+#include "messages/tcg/pb_pdp_referral_msg.h"
+#include "state_machine/pb_tnc_state_machine.h"
+
+#include <tncif_names.h>
+#include <tncif_pa_subtypes.h>
+
+#include <tnc/tnc.h>
+#include <tnc/tnccs/tnccs_manager.h>
+#include <tnc/imv/imv_manager.h>
+
+#include <threading/mutex.h>
+#include <utils/debug.h>
+#include <collections/linked_list.h>
+#include <pen/pen.h>
+
+typedef struct private_tnccs_20_server_t private_tnccs_20_server_t;
+
+/**
+ * Private data of a tnccs_20_server_t object.
+ */
+struct private_tnccs_20_server_t {
+
+ /**
+ * Public tnccs_20_server_t interface.
+ */
+ tnccs_20_server_t public;
+
+ /**
+ * PB-TNC State Machine
+ */
+ pb_tnc_state_machine_t *state_machine;
+
+ /**
+ * Connection ID assigned to this TNCCS connection
+ */
+ TNC_ConnectionID connection_id;
+
+ /**
+ * PB-TNC messages to be sent
+ */
+ linked_list_t *messages;
+
+ /**
+ * Type of PB-TNC batch being constructed
+ */
+ pb_tnc_batch_type_t batch_type;
+
+ /**
+ * Maximum PB-TNC batch size
+ */
+ size_t max_batch_len;
+
+ /**
+ * Mutex locking the batch in construction
+ */
+ mutex_t *mutex;
+
+ /**
+ * Flag set while processing
+ */
+ bool fatal_error;
+
+ /**
+ * Flag set by IMC/IMV RequestHandshakeRetry() function
+ */
+ bool request_handshake_retry;
+
+ /**
+ * SendMessage() by IMV only allowed if flag is set
+ */
+ bool send_msg;
+
+ /**
+ * Set of IMV recommendations
+ */
+ recommendations_t *recs;
+
+ /**
+ * TNC IF-T transport protocol for EAP methods
+ */
+ bool eap_transport;
+
+ /**
+ * Mutual PB-TNC protocol enabled
+ */
+ bool mutual;
+
+ /**
+ * Mutual Capability message sent
+ */
+ bool sent_mutual_capability;
+
+};
+
+/**
+ * The following two functions are shared with the tnccs_20_server class
+ */
+extern void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg,
+ bool *fatal_error);
+extern bool tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg);
+
+/**
+ * If the batch type changes then delete all accumulated PB-TNC messages
+ */
+static void change_batch_type(private_tnccs_20_server_t *this,
+ pb_tnc_batch_type_t batch_type)
+{
+ pb_tnc_msg_t *msg;
+
+ if (batch_type != this->batch_type)
+ {
+ if (this->batch_type != PB_BATCH_NONE)
+ {
+ DBG1(DBG_TNC, "cancelling PB-TNC %N batch",
+ pb_tnc_batch_type_names, this->batch_type);
+
+ while (this->messages->remove_last(this->messages,
+ (void**)&msg) == SUCCESS)
+ {
+ msg->destroy(msg);
+ }
+ }
+ this->batch_type = batch_type;
+ }
+}
+
+/**
+ * Handle a single PB-TNC IETF standard message according to its type
+ */
+static void handle_ietf_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
+{
+ pen_type_t msg_type = msg->get_type(msg);
+
+ switch (msg_type.type)
+ {
+ case PB_MSG_EXPERIMENTAL:
+ /* nothing to do */
+ break;
+ case PB_MSG_PA:
+ {
+ pb_pa_msg_t *pa_msg;
+ pen_type_t msg_subtype;
+ u_int16_t imc_id, imv_id;
+ chunk_t msg_body;
+ bool excl;
+ enum_name_t *pa_subtype_names;
+
+ pa_msg = (pb_pa_msg_t*)msg;
+ msg_subtype = pa_msg->get_subtype(pa_msg);
+ msg_body = pa_msg->get_body(pa_msg);
+ imc_id = pa_msg->get_collector_id(pa_msg);
+ imv_id = pa_msg->get_validator_id(pa_msg);
+ excl = pa_msg->get_exclusive_flag(pa_msg);
+
+ pa_subtype_names = get_pa_subtype_names(msg_subtype.vendor_id);
+ if (pa_subtype_names)
+ {
+ DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x",
+ pen_names, msg_subtype.vendor_id, pa_subtype_names,
+ msg_subtype.type, msg_subtype.vendor_id, msg_subtype.type);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x",
+ pen_names, msg_subtype.vendor_id, msg_subtype.vendor_id,
+ msg_subtype.type);
+ }
+ this->send_msg = TRUE;
+ tnc->imvs->receive_message(tnc->imvs, this->connection_id,
+ excl, msg_body.ptr, msg_body.len,
+ msg_subtype.vendor_id,
+ msg_subtype.type, imc_id, imv_id);
+ this->send_msg = FALSE;
+ break;
+ }
+ case PB_MSG_ERROR:
+ tnccs_20_handle_ietf_error_msg(msg, &this->fatal_error);
+ break;
+ case PB_MSG_LANGUAGE_PREFERENCE:
+ {
+ pb_language_preference_msg_t *lang_msg;
+ chunk_t lang;
+
+ lang_msg = (pb_language_preference_msg_t*)msg;
+ lang = lang_msg->get_language_preference(lang_msg);
+ DBG2(DBG_TNC, "setting language preference to '%.*s'",
+ (int)lang.len, lang.ptr);
+ this->recs->set_preferred_language(this->recs, lang);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/**
+ * Handle a single PB-TNC ITA standard message according to its type
+ */
+static void handle_ita_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
+{
+ pen_type_t msg_type = msg->get_type(msg);
+
+ switch (msg_type.type)
+ {
+ case PB_ITA_MSG_MUTUAL_CAPABILITY:
+ this->mutual = tnccs_20_handle_ita_mutual_capability_msg(msg);
+
+ /* Respond with PB-TNC Mutual Capability message if necessary */
+ if (this->mutual && !this->sent_mutual_capability)
+ {
+ msg = pb_mutual_capability_msg_create(PB_MUTUAL_HALF_DUPLEX);
+ this->mutex->lock(this->mutex);
+ this->messages->insert_last(this->messages, msg);
+ this->mutex->unlock(this->mutex);
+ this->sent_mutual_capability = TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Handle a single PB-TNC message according to its type
+ */
+static void handle_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
+{
+ pen_type_t msg_type = msg->get_type(msg);
+
+ switch (msg_type.vendor_id)
+ {
+ case PEN_IETF:
+ handle_ietf_message(this, msg);
+ break;
+ case PEN_ITA:
+ handle_ita_message(this, msg);
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * Build an SRETRY batch
+ */
+static void build_retry_batch(private_tnccs_20_server_t *this)
+{
+ if (this->batch_type == PB_BATCH_SRETRY)
+ {
+ /* retry batch has already been selected */
+ return;
+ }
+ change_batch_type(this, PB_BATCH_SRETRY);
+
+ this->recs->clear_recommendation(this->recs);
+ tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+ TNC_CONNECTION_STATE_HANDSHAKE);
+}
+
+METHOD(tnccs_20_handler_t, process, status_t,
+ private_tnccs_20_server_t *this, pb_tnc_batch_t *batch)
+{
+ pb_tnc_batch_type_t batch_type;
+ status_t status;
+
+ batch_type = batch->get_type(batch);
+
+ DBG1(DBG_TNC, "processing PB-TNC %N batch for Connection ID %d",
+ pb_tnc_batch_type_names, batch_type, this->connection_id);
+ status = batch->process(batch, this->state_machine);
+
+ if (status != FAILED)
+ {
+ enumerator_t *enumerator;
+ pb_tnc_msg_t *msg;
+ bool empty = TRUE;
+
+ if (batch_type == PB_BATCH_CRETRY)
+ {
+ /* Send an SRETRY batch in response */
+ this->mutex->lock(this->mutex);
+ build_retry_batch(this);
+ this->mutex->unlock(this->mutex);
+ }
+
+ enumerator = batch->create_msg_enumerator(batch);
+ while (enumerator->enumerate(enumerator, &msg))
+ {
+ handle_message(this, msg);
+ empty = FALSE;
+ }
+ enumerator->destroy(enumerator);
+
+ /* received a CLOSE batch from PB-TNC client */
+ if (batch_type == PB_BATCH_CLOSE)
+ {
+ return empty ? SUCCESS : FAILED;
+ }
+
+ this->send_msg = TRUE;
+ tnc->imvs->batch_ending(tnc->imvs, this->connection_id);
+ this->send_msg = FALSE;
+ }
+
+ switch (status)
+ {
+ case FAILED:
+ this->fatal_error = TRUE;
+ status = VERIFY_ERROR;
+ break;
+ case VERIFY_ERROR:
+ break;
+ case SUCCESS:
+ default:
+ status = NEED_MORE;
+ break;
+ }
+
+ return status;
+}
+
+/**
+ * Build a RESULT batch if a final recommendation is available
+ */
+static void check_and_build_recommendation(private_tnccs_20_server_t *this)
+{
+ TNC_IMV_Action_Recommendation rec;
+ TNC_IMV_Evaluation_Result eval;
+ TNC_ConnectionState state;
+ TNC_IMVID id;
+ chunk_t reason, language;
+ enumerator_t *enumerator;
+ pb_tnc_msg_t *msg;
+ pb_access_recommendation_code_t pb_rec;
+
+ if (!this->recs->have_recommendation(this->recs, &rec, &eval))
+ {
+ tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id);
+ }
+ if (this->recs->have_recommendation(this->recs, &rec, &eval))
+ {
+ this->batch_type = PB_BATCH_RESULT;
+
+ msg = pb_assessment_result_msg_create(eval);
+ this->messages->insert_last(this->messages, msg);
+
+ /**
+ * Map IMV Action Recommendation codes to PB Access Recommendation codes
+ * and communicate Access Recommendation to IMVs
+ */
+ switch (rec)
+ {
+ case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
+ state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
+ pb_rec = PB_REC_ACCESS_ALLOWED;
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+ state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
+ pb_rec = PB_REC_QUARANTINED;
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
+ default:
+ state = TNC_CONNECTION_STATE_ACCESS_NONE;
+ pb_rec = PB_REC_ACCESS_DENIED;
+ }
+ tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+ state);
+
+ msg = pb_access_recommendation_msg_create(pb_rec);
+ this->messages->insert_last(this->messages, msg);
+
+ enumerator = this->recs->create_reason_enumerator(this->recs);
+ while (enumerator->enumerate(enumerator, &id, &reason, &language))
+ {
+ msg = pb_reason_string_msg_create(reason, language);
+ this->messages->insert_last(this->messages, msg);
+ }
+ enumerator->destroy(enumerator);
+ }
+}
+
+METHOD(tnccs_20_handler_t, build, status_t,
+ private_tnccs_20_server_t *this, void *buf, size_t *buflen, size_t *msglen)
+{
+ status_t status;
+ pb_tnc_state_t state;
+
+ state = this->state_machine->get_state(this->state_machine);
+
+ if (this->fatal_error && state == PB_STATE_END)
+ {
+ DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection");
+ return FAILED;
+ }
+
+ /* Do not allow any asynchronous IMVs to add additional messages */
+ this->mutex->lock(this->mutex);
+
+ if (this->request_handshake_retry)
+ {
+ if (state != PB_STATE_INIT)
+ {
+ build_retry_batch(this);
+ }
+
+ /* Reset the flag for the next handshake retry request */
+ this->request_handshake_retry = FALSE;
+ }
+
+ if (state == PB_STATE_SERVER_WORKING &&
+ this->recs->have_recommendation(this->recs, NULL, NULL))
+ {
+ check_and_build_recommendation(this);
+ }
+
+ if (this->batch_type == PB_BATCH_NONE)
+ {
+ if (state == PB_STATE_SERVER_WORKING)
+ {
+ if (this->state_machine->get_empty_cdata(this->state_machine))
+ {
+ check_and_build_recommendation(this);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "no recommendation available yet, "
+ "sending empty PB-TNC SDATA batch");
+ this->batch_type = PB_BATCH_SDATA;
+ }
+ }
+ }
+
+ if (this->batch_type != PB_BATCH_NONE)
+ {
+ pb_tnc_batch_t *batch;
+ pb_tnc_msg_t *msg;
+ chunk_t data;
+ int msg_count;
+ enumerator_t *enumerator;
+
+ if (this->state_machine->send_batch(this->state_machine, this->batch_type))
+ {
+ batch = pb_tnc_batch_create(TRUE, this->batch_type,
+ min(this->max_batch_len, *buflen));
+
+ enumerator = this->messages->create_enumerator(this->messages);
+ while (enumerator->enumerate(enumerator, &msg))
+ {
+ if (batch->add_msg(batch, msg))
+ {
+ this->messages->remove_at(this->messages, enumerator);
+ }
+ else
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ batch->build(batch);
+ data = batch->get_encoding(batch);
+ DBG1(DBG_TNC, "sending PB-TNC %N batch (%d bytes) for Connection ID %u",
+ pb_tnc_batch_type_names, this->batch_type, data.len,
+ this->connection_id);
+ DBG3(DBG_TNC, "%B", &data);
+
+ *buflen = data.len;
+ *msglen = 0;
+ memcpy(buf, data.ptr, *buflen);
+ batch->destroy(batch);
+
+ msg_count = this->messages->get_count(this->messages);
+ if (msg_count)
+ {
+ DBG2(DBG_TNC, "queued %d PB-TNC message%s for next %N batch",
+ msg_count, (msg_count == 1) ? "" : "s",
+ pb_tnc_batch_type_names, this->batch_type);
+ }
+ else
+ {
+ this->batch_type = PB_BATCH_NONE;
+ }
+
+ status = ALREADY_DONE;
+ }
+ else
+ {
+ change_batch_type(this, PB_BATCH_NONE);
+ status = INVALID_STATE;
+ }
+ }
+ else
+ {
+ DBG1(DBG_TNC, "no PB-TNC batch to send");
+ status = INVALID_STATE;
+ }
+ this->mutex->unlock(this->mutex);
+
+ return status;
+}
+
+METHOD(tnccs_20_handler_t, begin_handshake, void,
+ private_tnccs_20_server_t *this, bool mutual)
+{
+ pb_tnc_msg_t *msg;
+ identification_t *pdp_server;
+ u_int16_t *pdp_port;
+
+ tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+ TNC_CONNECTION_STATE_HANDSHAKE);
+
+ /* Send a PB-TNC TCG PDP Referral message if PDP is known */
+ pdp_server = (identification_t*)lib->get(lib, "pt-tls-server");
+ pdp_port = (u_int16_t*)lib->get(lib, "pt-tls-port");
+
+ if (this->eap_transport && pdp_server && pdp_port)
+ {
+ msg = pb_pdp_referral_msg_create_from_fqdn(
+ pdp_server->get_encoding(pdp_server), *pdp_port);
+ this->mutex->lock(this->mutex);
+ this->messages->insert_last(this->messages, msg);
+ this->mutex->unlock(this->mutex);
+ }
+
+ /* Send a PB-Noskip-Test message for testing purposes */
+ if (lib->settings->get_bool(lib->settings,
+ "%s.plugins.tnccs-20.tests.pb_tnc_noskip", FALSE, lib->ns))
+ {
+ msg = pb_noskip_test_msg_create();
+ this->mutex->lock(this->mutex);
+ this->messages->insert_last(this->messages, msg);
+ this->mutex->unlock(this->mutex);
+ }
+}
+
+METHOD(tnccs_20_handler_t, get_send_flag, bool,
+ private_tnccs_20_server_t *this)
+{
+ return this->send_msg;
+}
+
+METHOD(tnccs_20_handler_t, get_mutual, bool,
+ private_tnccs_20_server_t *this)
+{
+ return this->mutual;
+}
+
+METHOD(tnccs_20_handler_t, get_state, pb_tnc_state_t,
+ private_tnccs_20_server_t *this)
+{
+ return this->state_machine->get_state(this->state_machine);
+}
+
+METHOD(tnccs_20_handler_t, add_msg, void,
+ private_tnccs_20_server_t *this, pb_tnc_msg_t *msg)
+{
+ /* adding PA message to SDATA batch only */
+ this->mutex->lock(this->mutex);
+ if (this->batch_type == PB_BATCH_NONE)
+ {
+ this->batch_type = PB_BATCH_SDATA;
+ }
+ if (this->batch_type == PB_BATCH_SDATA)
+ {
+ this->messages->insert_last(this->messages, msg);
+ }
+ else
+ {
+ msg->destroy(msg);
+ }
+ this->mutex->unlock(this->mutex);
+}
+
+METHOD(tnccs_20_handler_t, handle_errors, void,
+ private_tnccs_20_server_t *this, pb_tnc_batch_t *batch,
+ bool fatal_header_error)
+{
+ pb_tnc_msg_t *msg;
+ enumerator_t *enumerator;
+
+ if (fatal_header_error || this->fatal_error)
+ {
+ this->mutex->lock(this->mutex);
+ change_batch_type(this, PB_BATCH_CLOSE);
+ this->mutex->unlock(this->mutex);
+ }
+
+ enumerator = batch->create_error_enumerator(batch);
+ while (enumerator->enumerate(enumerator, &msg))
+ {
+ this->mutex->lock(this->mutex);
+ this->messages->insert_last(this->messages, msg->get_ref(msg));
+ this->mutex->unlock(this->mutex);
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(tnccs_20_handler_t, destroy, void,
+ private_tnccs_20_server_t *this)
+{
+ if (this->connection_id)
+ {
+ tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id, TRUE);
+ }
+ this->state_machine->destroy(this->state_machine);
+ this->mutex->destroy(this->mutex);
+ this->messages->destroy_offset(this->messages,
+ offsetof(pb_tnc_msg_t, destroy));
+ free(this);
+}
+
+METHOD(tnccs_20_server_t, have_recommendation, bool,
+ private_tnccs_20_server_t *this, TNC_IMV_Action_Recommendation *rec,
+ TNC_IMV_Evaluation_Result *eval)
+{
+ return this->recs->have_recommendation(this->recs, rec, eval);
+}
+
+/**
+ * See header
+ */
+tnccs_20_handler_t* tnccs_20_server_create(tnccs_t *tnccs,
+ tnccs_send_message_t send_msg,
+ size_t max_batch_len,
+ size_t max_msg_len,
+ bool eap_transport)
+{
+ private_tnccs_20_server_t *this;
+
+ INIT(this,
+ .public = {
+ .handler = {
+ .process = _process,
+ .build = _build,
+ .begin_handshake = _begin_handshake,
+ .get_send_flag = _get_send_flag,
+ .get_mutual = _get_mutual,
+ .get_state = _get_state,
+ .add_msg = _add_msg,
+ .handle_errors = _handle_errors,
+ .destroy = _destroy,
+ },
+ .have_recommendation = _have_recommendation,
+ },
+ .state_machine = pb_tnc_state_machine_create(TRUE),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .messages = linked_list_create(),
+ .batch_type = PB_BATCH_SDATA,
+ .max_batch_len = max_batch_len,
+ .eap_transport = eap_transport,
+ );
+
+ this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
+ TNCCS_2_0, tnccs, send_msg,
+ &this->request_handshake_retry,
+ max_msg_len, &this->recs);
+ if (!this->connection_id)
+ {
+ destroy(this);
+ return NULL;
+ }
+ tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+ TNC_CONNECTION_STATE_CREATE);
+
+ return &this->public.handler;
+}
diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_server.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.h
new file mode 100644
index 000000000..5833d1132
--- /dev/null
+++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tnccs_20_server_h tnccs_20_server
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef TNCCS_20_SERVER_H_
+#define TNCCS_20_SERVER_H_
+
+#include <library.h>
+
+#include <tnc/tnccs/tnccs.h>
+
+#include "tnccs_20_handler.h"
+
+typedef struct tnccs_20_server_t tnccs_20_server_t;
+
+/**
+ * Interface for a TNC server
+ */
+struct tnccs_20_server_t {
+
+ /**
+ * IF-TNCCS 2.0 protocol handler interface
+ */
+ tnccs_20_handler_t handler;
+
+ /**
+ * Check if an Action Recommendation is already available
+ *
+ * @param rec TNC Action Recommendation
+ * @param eval TNC Evaluation Result
+ * @return TRUE if Action Recommendation is
+ */
+ bool (*have_recommendation)(tnccs_20_server_t *this,
+ TNC_IMV_Action_Recommendation *rec,
+ TNC_IMV_Evaluation_Result *eval);
+
+};
+
+/**
+ * Create an instance of the TNC IF-TNCCS 2.0 server-side protocol handler.
+ *
+ * @param tnccs TNC IF-TNCCS 2.0 stack
+ * @param send_msg TNF IF-TNCCS 2.0 send message callback function
+ * @param max_batch_len Maximum PB-TNC batch size
+ * @param max_msg_len Maximum PA-TNC message size
+ * @param eap_transport TRUE if IF-T for EAP methods
+ */
+tnccs_20_handler_t* tnccs_20_server_create(tnccs_t *tnccs,
+ tnccs_send_message_t send_msg,
+ size_t max_batch_len,
+ size_t max_msg_len,
+ bool eap_transport);
+
+
+#endif /** TNCCS_20_SERVER_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_dynamic/Makefile.in b/src/libtnccs/plugins/tnccs_dynamic/Makefile.in
index 6a03df994..3f21a22d4 100644
--- a/src/libtnccs/plugins/tnccs_dynamic/Makefile.in
+++ b/src/libtnccs/plugins/tnccs_dynamic/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/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c
index e08236eb7..44b804fb2 100644
--- a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c
+++ b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2013 Andreas Steffen
+ * Copyright (C) 2011-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -34,12 +34,22 @@ struct private_tnccs_dynamic_t {
/**
* Server identity
*/
- identification_t *server;
+ identification_t *server_id;
/**
* Client identity
*/
- identification_t *peer;
+ identification_t *peer_id;
+
+ /**
+ * Server IP address
+ */
+ host_t *server_ip;
+
+ /**
+ * Client IP address
+ */
+ host_t *peer_ip;
/**
* Detected TNC IF-TNCCS stack
@@ -109,8 +119,8 @@ METHOD(tls_t, process, status_t,
DBG1(DBG_TNC, "%N protocol detected dynamically",
tnccs_type_names, type);
tnccs = tnc->tnccs->create_instance(tnc->tnccs, type, TRUE,
- this->server, this->peer, this->transport,
- this->callback);
+ this->server_id, this->peer_id, this->server_ip,
+ this->peer_ip, this->transport, this->callback);
if (!tnccs)
{
DBG1(DBG_TNC, "N% protocol not supported", tnccs_type_names, type);
@@ -137,14 +147,14 @@ METHOD(tls_t, is_server, bool,
METHOD(tls_t, get_server_id, identification_t*,
private_tnccs_dynamic_t *this)
{
- return this->server;
+ return this->server_id;
}
METHOD(tls_t, set_peer_id, void,
private_tnccs_dynamic_t *this, identification_t *id)
{
- DESTROY_IF(this->peer);
- this->peer = id->clone(id);
+ DESTROY_IF(this->peer_id);
+ this->peer_id = id->clone(id);
if (this->tls)
{
this->tls->set_peer_id(this->tls, id);
@@ -154,7 +164,7 @@ METHOD(tls_t, set_peer_id, void,
METHOD(tls_t, get_peer_id, identification_t*,
private_tnccs_dynamic_t *this)
{
- return this->peer;
+ return this->peer_id;
}
METHOD(tls_t, get_purpose, tls_purpose_t,
@@ -181,12 +191,26 @@ METHOD(tls_t, destroy, void,
if (ref_put(&this->ref))
{
DESTROY_IF(this->tls);
- this->server->destroy(this->server);
- this->peer->destroy(this->peer);
+ this->server_id->destroy(this->server_id);
+ this->peer_id->destroy(this->peer_id);
+ this->server_ip->destroy(this->server_ip);
+ this->peer_ip->destroy(this->peer_ip);
free(this);
}
}
+METHOD(tnccs_t, get_server_ip, host_t*,
+ private_tnccs_dynamic_t *this)
+{
+ return this->server_ip;
+}
+
+METHOD(tnccs_t, get_peer_ip, host_t*,
+ private_tnccs_dynamic_t *this)
+{
+ return this->peer_ip;
+}
+
METHOD(tnccs_t, get_transport, tnc_ift_type_t,
private_tnccs_dynamic_t *this)
{
@@ -229,9 +253,10 @@ METHOD(tnccs_t, get_ref, tnccs_t*,
/**
* See header
*/
-tnccs_t* tnccs_dynamic_create(bool is_server,
- identification_t *server, identification_t *peer,
- tnc_ift_type_t transport, tnccs_cb_t cb)
+tnccs_t* tnccs_dynamic_create(bool is_server, identification_t *server_id,
+ identification_t *peer_id, host_t *server_ip,
+ host_t *peer_ip, tnc_ift_type_t transport,
+ tnccs_cb_t cb)
{
private_tnccs_dynamic_t *this;
@@ -249,6 +274,8 @@ tnccs_t* tnccs_dynamic_create(bool is_server,
.get_eap_msk = _get_eap_msk,
.destroy = _destroy,
},
+ .get_server_ip = _get_server_ip,
+ .get_peer_ip = _get_peer_ip,
.get_transport = _get_transport,
.set_transport = _set_transport,
.get_auth_type = _get_auth_type,
@@ -256,8 +283,10 @@ tnccs_t* tnccs_dynamic_create(bool is_server,
.get_pdp_server = _get_pdp_server,
.get_ref = _get_ref,
},
- .server = server->clone(server),
- .peer = peer->clone(peer),
+ .server_id = server_id->clone(server_id),
+ .peer_id = peer_id->clone(peer_id),
+ .server_ip = server_ip->clone(server_ip),
+ .peer_ip = peer_ip->clone(peer_ip),
.transport = transport,
.callback = cb,
.ref = 1,
diff --git a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h
index cbdc80b83..2e1141780 100644
--- a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h
+++ b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2013 Andreas Steffen
+ * Copyright (C) 2011-2015 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -29,14 +29,17 @@
* Create an instance of a dynamic TNC IF-TNCCS protocol handler.
*
* @param is_server TRUE to act as TNC Server, FALSE for TNC Client
- * @param server Server identity
- * @param peer Client identity
+ * @param server_id Server identity
+ * @param peer_id Client identity
+ * @param server_ip Server IP address
+ * @param peer_ip Client IP address
* @param transport Underlying IF-T transport protocol
* @param cb Callback function if TNC Server, NULL if TNC Client
* @return dynamic TNC IF-TNCCS protocol stack
*/
-tnccs_t* tnccs_dynamic_create(bool is_server,
- identification_t *server, identification_t *peer,
- tnc_ift_type_t transport, tnccs_cb_t cb);
+tnccs_t* tnccs_dynamic_create(bool is_server, identification_t *server_id,
+ identification_t *peer_id, host_t *server_ip,
+ host_t *peer_ip, tnc_ift_type_t transport,
+ tnccs_cb_t cb);
#endif /** TNCCS_DYNAMIC_H_ @}*/
diff --git a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h
index b518e1278..97dd0df43 100644
--- a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h
+++ b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h
@@ -15,7 +15,7 @@
/**
* @defgroup tnccs_dynamic tnccs_dynamic
- * @ingroup cplugins
+ * @ingroup tplugins
*
* @defgroup tnccs_dynamic_plugin tnccs_dynamic_plugin
* @{ @ingroup tnccs_dynamic
diff --git a/src/libtnccs/tnc/imc/imc.h b/src/libtnccs/tnc/imc/imc.h
index 3ff7d5194..6d13f6bc5 100644
--- a/src/libtnccs/tnc/imc/imc.h
+++ b/src/libtnccs/tnc/imc/imc.h
@@ -15,7 +15,7 @@
/**
* @defgroup imc imc
- * @ingroup tnc
+ * @ingroup libtnccs
*
* @defgroup imct imc
* @{ @ingroup imc
diff --git a/src/libtnccs/tnc/imv/imv.h b/src/libtnccs/tnc/imv/imv.h
index 3716532d6..fbc26a1e7 100644
--- a/src/libtnccs/tnc/imv/imv.h
+++ b/src/libtnccs/tnc/imv/imv.h
@@ -15,7 +15,7 @@
/**
* @defgroup imv imv
- * @ingroup tnc
+ * @ingroup libtnccs
*
* @defgroup imvt imv
* @{ @ingroup imv
diff --git a/src/libtnccs/tnc/tnc.h b/src/libtnccs/tnc/tnc.h
index e5a4a2959..7bf8c84b7 100644
--- a/src/libtnccs/tnc/tnc.h
+++ b/src/libtnccs/tnc/tnc.h
@@ -14,9 +14,12 @@
*/
/**
- * @defgroup tnc tnc
+ * @defgroup libtnccs libtnccs
*
- * @addtogroup tnc
+ * @defgroup tplugins plugins
+ * @ingroup libtnccs
+ *
+ * @addtogroup libtnccs
* @{
*/
diff --git a/src/libtnccs/tnc/tnccs/tnccs.h b/src/libtnccs/tnc/tnccs/tnccs.h
index eefd5565d..8ff295bcc 100644
--- a/src/libtnccs/tnc/tnccs/tnccs.h
+++ b/src/libtnccs/tnc/tnccs/tnccs.h
@@ -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
@@ -15,7 +15,7 @@
/**
* @defgroup tnccs tnccs
- * @ingroup tnc
+ * @ingroup libtnccs
*
* @defgroup tnccst tnccs
* @{ @ingroup tnccs
@@ -87,6 +87,20 @@ struct tnccs_t {
tls_t tls;
/**
+ * Get server IP address
+ *
+ * @return Server IP address
+ */
+ host_t* (*get_server_ip)(tnccs_t *this);
+
+ /**
+ * Get peer IP address
+ *
+ * @return Peer IP address
+ */
+ host_t* (*get_peer_ip)(tnccs_t *this);
+
+ /**
* Get underlying TNC IF-T transport protocol
*
* @return TNC IF-T transport protocol
@@ -135,15 +149,19 @@ struct tnccs_t {
* Constructor definition for a pluggable TNCCS protocol implementation.
*
* @param is_server TRUE if TNC Server, FALSE if TNC Client
- * @param server Server identity
- * @param peer Client identity
+ * @param server_id Server identity
+ * @param peer_id Client identity
+ * @param server_ip Server IP address
+ * @param peer_ip Client IP address
* @param transport Underlying TNC IF-T transport protocol used
* @param cb Callback function if TNC Server, NULL if TNC Client
* @return implementation of the tnccs_t interface
*/
typedef tnccs_t *(*tnccs_constructor_t)(bool is_server,
- identification_t *server,
- identification_t *peer,
+ identification_t *server_id,
+ identification_t *peer_id,
+ host_t *server_ip,
+ host_t *peer_ip,
tnc_ift_type_t transport,
tnccs_cb_t cb);
diff --git a/src/libtnccs/tnc/tnccs/tnccs_manager.h b/src/libtnccs/tnc/tnccs/tnccs_manager.h
index 791336ee1..b5c85f3c0 100644
--- a/src/libtnccs/tnc/tnccs/tnccs_manager.h
+++ b/src/libtnccs/tnc/tnccs/tnccs_manager.h
@@ -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
@@ -56,16 +56,19 @@ struct tnccs_manager_t {
*
* @param type type of the TNCCS protocol
* @param is_server TRUE if TNC Server, FALSE if TNC Client
- * @param server Server identity
- * @param peer Client identity
+ * @param server_id Server identity
+ * @param peer_id Client identity
+ * @param server_ip Server IP address
+ * @param peer_ip Client IP address
* @param transport Underlying TNC IF-T transport protocol used
* @param cb Callback function if TNC Server, NULL if TNC Client
* @return TNCCS protocol instance, NULL if no constructor found
*/
tnccs_t* (*create_instance)(tnccs_manager_t *this, tnccs_type_t type,
- bool is_server, identification_t *server,
- identification_t *peer,
- tnc_ift_type_t transport, tnccs_cb_t cb);
+ bool is_server, identification_t *server_id,
+ identification_t *peer_id, host_t *server_ip,
+ host_t *peer_ip, tnc_ift_type_t transport,
+ tnccs_cb_t cb);
/**
* Create a TNCCS connection and assign a unique connection ID as well a
diff --git a/src/libtncif/Makefile.in b/src/libtncif/Makefile.in
index efa06b927..010fadc42 100644
--- a/src/libtncif/Makefile.in
+++ b/src/libtncif/Makefile.in
@@ -193,6 +193,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@
@@ -253,10 +254,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@
@@ -330,6 +333,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/libtncif/tncif_names.c b/src/libtncif/tncif_names.c
index ac948c8ba..b348c548e 100644
--- a/src/libtncif/tncif_names.c
+++ b/src/libtncif/tncif_names.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 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
@@ -46,6 +46,18 @@ ENUM(TNC_IMV_Evaluation_Result_names,
"don't know"
);
+ENUM(TNC_Identity_names,
+ TNC_ID_UNKNOWN,
+ TNC_ID_X500_DN,
+ "unknown",
+ "IPv4 address",
+ "IPv6 address",
+ "FQDN",
+ "email address",
+ "username",
+ "X.500 DN"
+);
+
ENUM(TNC_Subject_names,
TNC_SUBJECT_UNKNOWN,
TNC_SUBJECT_USER,
diff --git a/src/libtncif/tncif_names.h b/src/libtncif/tncif_names.h
index 75458f960..64dd14fc2 100644
--- a/src/libtncif/tncif_names.h
+++ b/src/libtncif/tncif_names.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2011-2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -30,6 +31,7 @@
extern enum_name_t *TNC_Connection_State_names;
extern enum_name_t *TNC_IMV_Action_Recommendation_names;
extern enum_name_t *TNC_IMV_Evaluation_Result_names;
+extern enum_name_t *TNC_Identity_names;
extern enum_name_t *TNC_Subject_names;
extern enum_name_t *TNC_Authentication_names;
diff --git a/src/manager/Makefile.in b/src/manager/Makefile.in
index 79ee9c7b8..500220a3a 100644
--- a/src/manager/Makefile.in
+++ b/src/manager/Makefile.in
@@ -245,6 +245,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@
@@ -305,10 +306,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@
@@ -382,6 +385,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/medsrv/Makefile.in b/src/medsrv/Makefile.in
index 3de9153cf..7265457f1 100644
--- a/src/medsrv/Makefile.in
+++ b/src/medsrv/Makefile.in
@@ -234,6 +234,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@
@@ -294,10 +295,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@
@@ -371,6 +374,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/pki/Makefile.am b/src/pki/Makefile.am
index 266802cf7..ab407e021 100644
--- a/src/pki/Makefile.am
+++ b/src/pki/Makefile.am
@@ -13,6 +13,7 @@ pki_SOURCES = pki.c pki.h command.c command.h \
commands/signcrl.c \
commands/acert.c \
commands/pkcs7.c \
+ commands/pkcs12.c \
commands/verify.c
pki_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
diff --git a/src/pki/Makefile.in b/src/pki/Makefile.in
index 5f7a1bc26..4205469fc 100644
--- a/src/pki/Makefile.in
+++ b/src/pki/Makefile.in
@@ -108,7 +108,7 @@ am_pki_OBJECTS = pki.$(OBJEXT) command.$(OBJEXT) \
commands/req.$(OBJEXT) commands/self.$(OBJEXT) \
commands/print.$(OBJEXT) commands/signcrl.$(OBJEXT) \
commands/acert.$(OBJEXT) commands/pkcs7.$(OBJEXT) \
- commands/verify.$(OBJEXT)
+ commands/pkcs12.$(OBJEXT) commands/verify.$(OBJEXT)
pki_OBJECTS = $(am_pki_OBJECTS)
pki_DEPENDENCIES = $(top_builddir)/src/libstrongswan/libstrongswan.la
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -243,6 +243,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@
@@ -303,10 +304,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@
@@ -380,6 +383,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@
@@ -450,6 +455,7 @@ pki_SOURCES = pki.c pki.h command.c command.h \
commands/signcrl.c \
commands/acert.c \
commands/pkcs7.c \
+ commands/pkcs12.c \
commands/verify.c
pki_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
@@ -566,6 +572,8 @@ commands/acert.$(OBJEXT): commands/$(am__dirstamp) \
commands/$(DEPDIR)/$(am__dirstamp)
commands/pkcs7.$(OBJEXT): commands/$(am__dirstamp) \
commands/$(DEPDIR)/$(am__dirstamp)
+commands/pkcs12.$(OBJEXT): commands/$(am__dirstamp) \
+ commands/$(DEPDIR)/$(am__dirstamp)
commands/verify.$(OBJEXT): commands/$(am__dirstamp) \
commands/$(DEPDIR)/$(am__dirstamp)
@@ -586,6 +594,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/gen.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/issue.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/keyid.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/pkcs12.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/pkcs7.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/print.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/pub.Po@am__quote@
diff --git a/src/pki/command.h b/src/pki/command.h
index 9cf036bf2..d49adda09 100644
--- a/src/pki/command.h
+++ b/src/pki/command.h
@@ -24,7 +24,7 @@
/**
* Maximum number of commands (+1).
*/
-#define MAX_COMMANDS 12
+#define MAX_COMMANDS 13
/**
* Maximum number of options in a command (+3)
diff --git a/src/pki/commands/acert.c b/src/pki/commands/acert.c
index 185aa40b4..7099977f2 100644
--- a/src/pki/commands/acert.c
+++ b/src/pki/commands/acert.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -31,7 +32,7 @@
static int acert()
{
cred_encoding_type_t form = CERT_ASN1_DER;
- hash_algorithm_t digest = HASH_SHA1;
+ hash_algorithm_t digest = HASH_UNKNOWN;
certificate_t *ac = NULL, *cert = NULL, *issuer =NULL;
private_key_t *private = NULL;
public_key_t *public = NULL;
@@ -161,6 +162,10 @@ static int acert()
error = "loading issuer private key failed";
goto end;
}
+ if (digest == HASH_UNKNOWN)
+ {
+ digest = get_default_digest(private);
+ }
if (!private->belongs_to(private, public))
{
error = "issuer private key does not match issuer certificate";
@@ -286,7 +291,7 @@ static void __attribute__ ((constructor))reg()
{"not-before", 'F', 1, "date/time the validity of the AC starts"},
{"not-after", 'T', 1, "date/time the validity of the AC ends"},
{"dateform", 'D', 1, "strptime(3) input format, default: %d.%m.%y %T"},
- {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
{"outform", 'f', 1, "encoding of generated cert, default: der"},
}
});
diff --git a/src/pki/commands/gen.c b/src/pki/commands/gen.c
index ce28a0971..8b11854ad 100644
--- a/src/pki/commands/gen.c
+++ b/src/pki/commands/gen.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2014-2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -43,6 +44,10 @@ static int gen()
{
type = KEY_ECDSA;
}
+ else if (streq(arg, "bliss"))
+ {
+ type = KEY_BLISS;
+ }
else
{
return command_usage("invalid key type");
@@ -96,6 +101,9 @@ static int gen()
case KEY_ECDSA:
size = 384;
break;
+ case KEY_BLISS:
+ size = 1;
+ break;
default:
break;
}
@@ -151,12 +159,12 @@ static void __attribute__ ((constructor))reg()
{
command_register((command_t) {
gen, 'g', "gen", "generate a new private key",
- {" [--type rsa|ecdsa] [--size bits] [--safe-primes]",
+ {" [--type rsa|ecdsa|bliss] [--size bits] [--safe-primes]",
"[--shares n] [--threshold l] [--outform der|pem]"},
{
{"help", 'h', 0, "show usage information"},
{"type", 't', 1, "type of key, default: rsa"},
- {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384"},
+ {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384, bliss 1"},
{"safe-primes", 'p', 0, "generate rsa safe primes"},
{"shares", 'n', 1, "number of private rsa key shares"},
{"threshold", 'l', 1, "minimum number of participating rsa key shares"},
diff --git a/src/pki/commands/issue.c b/src/pki/commands/issue.c
index aaa2c2ff7..6a2d09d78 100644
--- a/src/pki/commands/issue.c
+++ b/src/pki/commands/issue.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -59,7 +60,7 @@ static void destroy_cdp(x509_cdp_t *this)
static int issue()
{
cred_encoding_type_t form = CERT_ASN1_DER;
- hash_algorithm_t digest = HASH_SHA1;
+ hash_algorithm_t digest = HASH_UNKNOWN;
certificate_t *cert_req = NULL, *cert = NULL, *ca =NULL;
private_key_t *private = NULL;
public_key_t *public = NULL;
@@ -287,6 +288,7 @@ static int issue()
}
break;
}
+
if (!cacert)
{
error = "--cacert is required";
@@ -355,6 +357,10 @@ static int issue()
error = "loading CA private key failed";
goto end;
}
+ if (digest == HASH_UNKNOWN)
+ {
+ digest = get_default_digest(private);
+ }
if (!private->belongs_to(private, public))
{
error = "CA private key does not match CA certificate";
@@ -589,7 +595,7 @@ static void __attribute__ ((constructor))reg()
{"crl", 'u', 1, "CRL distribution point URI to include"},
{"crlissuer", 'I', 1, "CRL Issuer for CRL at distribution point"},
{"ocsp", 'o', 1, "OCSP AuthorityInfoAccess URI to include"},
- {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
{"outform", 'f', 1, "encoding of generated cert, default: der"},
}
});
diff --git a/src/pki/commands/keyid.c b/src/pki/commands/keyid.c
index c3ac0c288..3bc62e74d 100644
--- a/src/pki/commands/keyid.c
+++ b/src/pki/commands/keyid.c
@@ -52,6 +52,11 @@ static int keyid()
type = CRED_PRIVATE_KEY;
subtype = KEY_ECDSA;
}
+ else if (streq(arg, "bliss-priv"))
+ {
+ type = CRED_PRIVATE_KEY;
+ subtype = KEY_BLISS;
+ }
else if (streq(arg, "pub"))
{
type = CRED_PUBLIC_KEY;
@@ -164,7 +169,7 @@ static void __attribute__ ((constructor))reg()
command_register((command_t)
{ keyid, 'k', "keyid",
"calculate key identifiers of a key/certificate",
- {"[--in file] [--type rsa-priv|ecdsa-priv|pub|pkcs10|x509]"},
+ {"[--in file] [--type rsa-priv|ecdsa-priv|bliss-priv|pub|pkcs10|x509]"},
{
{"help", 'h', 0, "show usage information"},
{"in", 'i', 1, "input file, default: stdin"},
diff --git a/src/pki/commands/pkcs12.c b/src/pki/commands/pkcs12.c
new file mode 100644
index 000000000..dcd1496ba
--- /dev/null
+++ b/src/pki/commands/pkcs12.c
@@ -0,0 +1,247 @@
+/*
+ * 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 <errno.h>
+
+#include "pki.h"
+
+#include <credentials/certificates/x509.h>
+#include <credentials/containers/pkcs12.h>
+
+/**
+ * Show info about PKCS#12 container
+ */
+static int show(pkcs12_t *pkcs12)
+{
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ private_key_t *key;
+ int index = 1;
+
+ printf("Certificates:\n");
+ enumerator = pkcs12->create_cert_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ x509_t *x509 = (x509_t*)cert;
+
+ if (x509->get_flags(x509) & X509_CA)
+ {
+ printf("[%2d] \"%Y\" (CA)\n", index++, cert->get_subject(cert));
+ }
+ else
+ {
+ printf("[%2d] \"%Y\"\n", index++, cert->get_subject(cert));
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ printf("Private keys:\n");
+ enumerator = pkcs12->create_key_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &key))
+ {
+ printf("[%2d] %N %d bits\n", index++, key_type_names,
+ key->get_type(key), key->get_keysize(key));
+ }
+ enumerator->destroy(enumerator);
+ return 0;
+}
+
+static int export(pkcs12_t *pkcs12, int index, char *outform)
+{
+ cred_encoding_type_t form;
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ private_key_t *key;
+ chunk_t encoding;
+ int i = 1;
+
+ enumerator = pkcs12->create_cert_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ if (i++ == index)
+ {
+ form = CERT_ASN1_DER;
+ if (outform && !get_form(outform, &form, CRED_CERTIFICATE))
+ {
+ enumerator->destroy(enumerator);
+ return command_usage("invalid output format");
+ }
+ if (cert->get_encoding(cert, form, &encoding))
+ {
+ set_file_mode(stdout, form);
+ if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1)
+ {
+ free(encoding.ptr);
+ enumerator->destroy(enumerator);
+ return 0;
+ }
+ free(encoding.ptr);
+ }
+ fprintf(stderr, "certificate export failed\n");
+ enumerator->destroy(enumerator);
+ return 1;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = pkcs12->create_key_enumerator(pkcs12);
+ while (enumerator->enumerate(enumerator, &key))
+ {
+ if (i++ == index)
+ {
+ form = PRIVKEY_ASN1_DER;
+ if (outform && !get_form(outform, &form, CRED_PRIVATE_KEY))
+ {
+ enumerator->destroy(enumerator);
+ return command_usage("invalid output format");
+ }
+ if (key->get_encoding(key, form, &encoding))
+ {
+ set_file_mode(stdout, form);
+ if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1)
+ {
+ free(encoding.ptr);
+ enumerator->destroy(enumerator);
+ return 0;
+ }
+ free(encoding.ptr);
+ }
+ fprintf(stderr, "private key export failed\n");
+ enumerator->destroy(enumerator);
+ return 0;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ fprintf(stderr, "invalid index %d\n", index);
+ return 1;
+}
+
+
+/**
+ * Handle PKCs#12 containers
+ */
+static int pkcs12()
+{
+ char *arg, *file = NULL, *outform = NULL;
+ pkcs12_t *p12 = NULL;
+ int res = 1, index = 0;
+ enum {
+ OP_NONE,
+ OP_LIST,
+ OP_EXPORT,
+ } op = OP_NONE;
+
+ while (TRUE)
+ {
+ switch (command_getopt(&arg))
+ {
+ case 'h':
+ return command_usage(NULL);
+ case 'i':
+ file = arg;
+ continue;
+ case 'l':
+ if (op != OP_NONE)
+ {
+ goto invalid;
+ }
+ op = OP_LIST;
+ continue;
+ case 'e':
+ if (op != OP_NONE)
+ {
+ goto invalid;
+ }
+ op = OP_EXPORT;
+ index = atoi(arg);
+ continue;
+ case 'f':
+ outform = arg;
+ continue;
+ case EOF:
+ break;
+ default:
+ invalid:
+ return command_usage("invalid --pkcs12 option");
+ }
+ break;
+ }
+
+ if (file)
+ {
+ p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
+ BUILD_FROM_FILE, file, BUILD_END);
+ }
+ else
+ {
+ chunk_t chunk;
+
+ set_file_mode(stdin, CERT_ASN1_DER);
+ if (!chunk_from_fd(0, &chunk))
+ {
+ fprintf(stderr, "reading input failed: %s\n", strerror(errno));
+ return 1;
+ }
+ p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
+ BUILD_BLOB, chunk, BUILD_END);
+ free(chunk.ptr);
+ }
+
+ if (!p12)
+ {
+ fprintf(stderr, "reading input failed!\n");
+ goto end;
+ }
+
+ switch (op)
+ {
+ case OP_LIST:
+ res = show(p12);
+ break;
+ case OP_EXPORT:
+ res = export(p12, index, outform);
+ break;
+ default:
+ p12->container.destroy(&p12->container);
+ return command_usage(NULL);
+ }
+
+end:
+ if (p12)
+ {
+ p12->container.destroy(&p12->container);
+ }
+ return res;
+}
+
+/**
+ * Register the command.
+ */
+static void __attribute__ ((constructor))reg()
+{
+ command_register((command_t) {
+ pkcs12, 'u', "pkcs12", "PKCS#12 functions",
+ {"--export index|--list [--in file]",
+ "[--outform der|pem]"},
+ {
+ {"help", 'h', 0, "show usage information"},
+ {"in", 'i', 1, "input file, default: stdin"},
+ {"list", 'l', 0, "list certificates and keys"},
+ {"export", 'e', 1, "export the credential with the given index"},
+ {"outform", 'f', 1, "encoding of exported credentials, default: der"},
+ }
+ });
+}
diff --git a/src/pki/commands/print.c b/src/pki/commands/print.c
index fb07169bf..fa69de133 100644
--- a/src/pki/commands/print.c
+++ b/src/pki/commands/print.c
@@ -32,9 +32,12 @@
static void print_pubkey(public_key_t *key)
{
chunk_t chunk;
+ key_type_t type;
+
+ type = key->get_type(key);
+ printf("pubkey: %N %d bits%s\n", key_type_names, type,
+ key->get_keysize(key), (type == KEY_BLISS) ? " strength" : "");
- printf("pubkey: %N %d bits\n", key_type_names, key->get_type(key),
- key->get_keysize(key));
if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &chunk))
{
printf("keyid: %#B\n", &chunk);
@@ -66,6 +69,22 @@ static void print_key(private_key_t *key)
}
/**
+ * Get a prefix for a named constraint identity type
+ */
+static char* get_type_pfx(identification_t *id)
+{
+ switch (id->get_type(id))
+ {
+ case ID_RFC822_ADDR:
+ return "email:";
+ case ID_FQDN:
+ return "dns:";
+ default:
+ return "";
+ }
+}
+
+/**
* Print X509 specific certificate information
*/
static void print_x509(x509_t *x509)
@@ -202,7 +221,7 @@ static void print_x509(x509_t *x509)
printf("Permitted NameConstraints:\n");
first = FALSE;
}
- printf(" %Y\n", id);
+ printf(" %s%Y\n", get_type_pfx(id), id);
}
enumerator->destroy(enumerator);
first = TRUE;
@@ -214,7 +233,7 @@ static void print_x509(x509_t *x509)
printf("Excluded NameConstraints:\n");
first = FALSE;
}
- printf(" %Y\n", id);
+ printf(" %s%Y\n", get_type_pfx(id), id);
}
enumerator->destroy(enumerator);
@@ -580,6 +599,11 @@ static int print()
type = CRED_PRIVATE_KEY;
subtype = KEY_ECDSA;
}
+ else if (streq(arg, "bliss-priv"))
+ {
+ type = CRED_PRIVATE_KEY;
+ subtype = KEY_BLISS;
+ }
else
{
return command_usage( "invalid input type");
@@ -652,7 +676,7 @@ static void __attribute__ ((constructor))reg()
command_register((command_t)
{ print, 'a', "print",
"print a credential in a human readable form",
- {"[--in file] [--type rsa-priv|ecdsa-priv|pub|x509|crl|ac]"},
+ {"[--in file] [--type rsa-priv|ecdsa-priv|bliss-priv|pub|x509|crl|ac]"},
{
{"help", 'h', 0, "show usage information"},
{"in", 'i', 1, "input file, default: stdin"},
diff --git a/src/pki/commands/pub.c b/src/pki/commands/pub.c
index b8d2f701d..ccc3c4251 100644
--- a/src/pki/commands/pub.c
+++ b/src/pki/commands/pub.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -53,6 +54,11 @@ static int pub()
type = CRED_PRIVATE_KEY;
subtype = KEY_ECDSA;
}
+ else if (streq(arg, "bliss"))
+ {
+ type = CRED_PRIVATE_KEY;
+ subtype = KEY_BLISS;
+ }
else if (streq(arg, "pub"))
{
type = CRED_PUBLIC_KEY;
@@ -183,7 +189,7 @@ static void __attribute__ ((constructor))reg()
command_register((command_t) {
pub, 'p', "pub",
"extract the public key from a private key/certificate",
- {"[--in file|--keyid hex] [--type rsa|ecdsa|pub|pkcs10|x509]",
+ {"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|pub|pkcs10|x509]",
"[--outform der|pem|dnskey|sshkey]"},
{
{"help", 'h', 0, "show usage information"},
diff --git a/src/pki/commands/req.c b/src/pki/commands/req.c
index 023683569..da991b505 100644
--- a/src/pki/commands/req.c
+++ b/src/pki/commands/req.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Copyright (C) 2009 Andreas Steffen
+ * Copyright (C) 2009-2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* HSR Hochschule fuer Technik Rapperswil
*
@@ -30,7 +31,7 @@ static int req()
{
cred_encoding_type_t form = CERT_ASN1_DER;
key_type_t type = KEY_RSA;
- hash_algorithm_t digest = HASH_SHA1;
+ hash_algorithm_t digest = HASH_UNKNOWN;
certificate_t *cert = NULL;
private_key_t *private = NULL;
char *file = NULL, *dn = NULL, *error = NULL;
@@ -57,6 +58,10 @@ static int req()
{
type = KEY_ECDSA;
}
+ else if (streq(arg, "bliss"))
+ {
+ type = KEY_BLISS;
+ }
else
{
error = "invalid input type";
@@ -134,6 +139,10 @@ static int req()
error = "parsing private key failed";
goto end;
}
+ if (digest == HASH_UNKNOWN)
+ {
+ digest = get_default_digest(private);
+ }
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST,
BUILD_SIGNING_KEY, private,
BUILD_SUBJECT, id,
@@ -185,7 +194,7 @@ static void __attribute__ ((constructor))reg()
command_register((command_t) {
req, 'r', "req",
"create a PKCS#10 certificate request",
- {" [--in file] [--type rsa|ecdsa] --dn distinguished-name",
+ {" [--in file] [--type rsa|ecdsa|bliss] --dn distinguished-name",
"[--san subjectAltName]+ [--password challengePassword]",
"[--digest md5|sha1|sha224|sha256|sha384|sha512] [--outform der|pem]"},
{
@@ -195,7 +204,7 @@ static void __attribute__ ((constructor))reg()
{"dn", 'd', 1, "subject distinguished name"},
{"san", 'a', 1, "subjectAltName to include in cert request"},
{"password",'p', 1, "challengePassword to include in cert request"},
- {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
{"outform", 'f', 1, "encoding of generated request, default: der"},
}
});
diff --git a/src/pki/commands/self.c b/src/pki/commands/self.c
index daefcdc10..a785c2a0c 100644
--- a/src/pki/commands/self.c
+++ b/src/pki/commands/self.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2015 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -49,7 +50,7 @@ static int self()
{
cred_encoding_type_t form = CERT_ASN1_DER;
key_type_t type = KEY_RSA;
- hash_algorithm_t digest = HASH_SHA1;
+ hash_algorithm_t digest = HASH_UNKNOWN;
certificate_t *cert = NULL;
private_key_t *private = NULL;
public_key_t *public = NULL;
@@ -57,7 +58,8 @@ static int self()
identification_t *id = NULL;
linked_list_t *san, *ocsp, *permitted, *excluded, *policies, *mappings;
int pathlen = X509_NO_CONSTRAINT, inhibit_any = X509_NO_CONSTRAINT;
- int inhibit_mapping = X509_NO_CONSTRAINT, require_explicit = X509_NO_CONSTRAINT;
+ int inhibit_mapping = X509_NO_CONSTRAINT;
+ int require_explicit = X509_NO_CONSTRAINT;
chunk_t serial = chunk_empty;
chunk_t encoding = chunk_empty;
time_t not_before, not_after, lifetime = 1095 * 24 * 60 * 60;
@@ -88,6 +90,10 @@ static int self()
{
type = KEY_ECDSA;
}
+ else if (streq(arg, "bliss"))
+ {
+ type = KEY_BLISS;
+ }
else
{
error = "invalid input type";
@@ -308,6 +314,10 @@ static int self()
error = "loading private key failed";
goto end;
}
+ if (digest == HASH_UNKNOWN)
+ {
+ digest = get_default_digest(private);
+ }
public = private->get_public_key(private);
if (!public)
{
@@ -407,7 +417,7 @@ static void __attribute__ ((constructor))reg()
command_register((command_t) {
self, 's', "self",
"create a self signed certificate",
- {" [--in file|--keyid hex] [--type rsa|ecdsa]",
+ {" [--in file|--keyid hex] [--type rsa|ecdsa|bliss]",
" --dn distinguished-name [--san subjectAltName]+",
"[--lifetime days] [--serial hex] [--ca] [--ocsp uri]+",
"[--flag serverAuth|clientAuth|crlSign|ocspSigning|msSmartcardLogon]+",
@@ -441,7 +451,7 @@ static void __attribute__ ((constructor))reg()
{"policy-any", 'A', 1, "inhibitAnyPolicy constraint"},
{"flag", 'e', 1, "include extendedKeyUsage flag"},
{"ocsp", 'o', 1, "OCSP AuthorityInfoAccess URI to include"},
- {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
{"outform", 'f', 1, "encoding of generated cert, default: der"},
}
});
diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c
index e5f49efe2..720dfd8a9 100644
--- a/src/pki/commands/signcrl.c
+++ b/src/pki/commands/signcrl.c
@@ -117,7 +117,7 @@ static int sign_crl()
certificate_t *ca = NULL, *crl = NULL;
crl_t *lastcrl = NULL;
x509_t *x509;
- hash_algorithm_t digest = HASH_SHA1;
+ hash_algorithm_t digest = HASH_UNKNOWN;
char *arg, *cacert = NULL, *cakey = NULL, *lastupdate = NULL, *error = NULL;
char *basecrl = NULL;
char serial[512], *keyid = NULL;
@@ -330,6 +330,10 @@ static int sign_crl()
error = "loading CA private key failed";
goto error;
}
+ if (digest == HASH_UNKNOWN)
+ {
+ digest = get_default_digest(private);
+ }
if (!private->belongs_to(private, public))
{
error = "CA private key does not match CA certificate";
@@ -465,7 +469,7 @@ static void __attribute__ ((constructor))reg()
{"serial", 's', 1, "hex encoded certificate serial number to revoke"},
{"reason", 'r', 1, "reason for certificate revocation"},
{"date", 'd', 1, "revocation date as unix timestamp, default: now"},
- {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"digest", 'g', 1, "digest for signature creation, default: key-specific"},
{"outform", 'f', 1, "encoding of generated crl, default: der"},
}
});
diff --git a/src/pki/man/Makefile.in b/src/pki/man/Makefile.in
index c288015de..45355bacd 100644
--- a/src/pki/man/Makefile.in
+++ b/src/pki/man/Makefile.in
@@ -81,10 +81,11 @@ subdir = src/pki/man
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(srcdir)/pki.1.in $(srcdir)/pki---gen.1.in \
$(srcdir)/pki---issue.1.in $(srcdir)/pki---keyid.1.in \
- $(srcdir)/pki---pkcs7.1.in $(srcdir)/pki---print.1.in \
- $(srcdir)/pki---pub.1.in $(srcdir)/pki---req.1.in \
- $(srcdir)/pki---self.1.in $(srcdir)/pki---signcrl.1.in \
- $(srcdir)/pki---acert.1.in $(srcdir)/pki---verify.1.in
+ $(srcdir)/pki---pkcs7.1.in $(srcdir)/pki---pkcs12.1.in \
+ $(srcdir)/pki---print.1.in $(srcdir)/pki---pub.1.in \
+ $(srcdir)/pki---req.1.in $(srcdir)/pki---self.1.in \
+ $(srcdir)/pki---signcrl.1.in $(srcdir)/pki---acert.1.in \
+ $(srcdir)/pki---verify.1.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/ltoptions.m4 \
@@ -101,8 +102,9 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES = pki.1 pki---gen.1 pki---issue.1 pki---keyid.1 \
- pki---pkcs7.1 pki---print.1 pki---pub.1 pki---req.1 \
- pki---self.1 pki---signcrl.1 pki---acert.1 pki---verify.1
+ pki---pkcs7.1 pki---pkcs12.1 pki---print.1 pki---pub.1 \
+ pki---req.1 pki---self.1 pki---signcrl.1 pki---acert.1 \
+ pki---verify.1
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -181,6 +183,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@
@@ -241,10 +244,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@
@@ -318,6 +323,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@
@@ -434,6 +441,8 @@ pki---keyid.1: $(top_builddir)/config.status $(srcdir)/pki---keyid.1.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
pki---pkcs7.1: $(top_builddir)/config.status $(srcdir)/pki---pkcs7.1.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+pki---pkcs12.1: $(top_builddir)/config.status $(srcdir)/pki---pkcs12.1.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
pki---print.1: $(top_builddir)/config.status $(srcdir)/pki---print.1.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
pki---pub.1: $(top_builddir)/config.status $(srcdir)/pki---pub.1.in
diff --git a/src/pki/man/pki---acert.1.in b/src/pki/man/pki---acert.1.in
index ec1d8be6e..d7460fd1f 100644
--- a/src/pki/man/pki---acert.1.in
+++ b/src/pki/man/pki---acert.1.in
@@ -99,8 +99,8 @@ Serial number in hex. It is randomly allocated by default.
.TP
.BI "\-g, \-\-digest " digest
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
+determined based on the type and size of the signature key.
.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
diff --git a/src/pki/man/pki---issue.1.in b/src/pki/man/pki---issue.1.in
index 375cb2fe4..3a89059c8 100644
--- a/src/pki/man/pki---issue.1.in
+++ b/src/pki/man/pki---issue.1.in
@@ -122,8 +122,8 @@ Add extendedKeyUsage flag. One of \fIserverAuth\fR, \fIclientAuth\fR,
.TP
.BI "\-g, \-\-digest " digest
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
+determined based on the type and size of the signature key.
.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
@@ -147,10 +147,22 @@ times.
Set path length constraint.
.TP
.BI "\-n, \-\-nc-permitted " name
-Add permitted NameConstraint extension to certificate.
+Add permitted NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
.TP
.BI "\-N, \-\-nc-excluded " name
-Add excluded NameConstraint extension to certificate.
+Add excluded NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
.TP
.BI "\-M, \-\-policy-mapping " issuer-oid:subject-oid
Add policyMapping from issuer to subject OID.
diff --git a/src/pki/man/pki---pkcs12.1.in b/src/pki/man/pki---pkcs12.1.in
new file mode 100644
index 000000000..470a66389
--- /dev/null
+++ b/src/pki/man/pki---pkcs12.1.in
@@ -0,0 +1,62 @@
+.TH "PKI \-\-PKCS12" 1 "2014-10-17" "@PACKAGE_VERSION@" "strongSwan"
+.
+.SH "NAME"
+.
+pki \-\-pkcs12 \- Provides PKCS#12 functions
+.
+.SH "SYNOPSIS"
+.
+.SY pki\ \-\-pkcs12
+.BR \-\-list
+.OP \-\-in file
+.OP \-\-debug level
+.YS
+.
+.SY pki\ \-\-pkcs12
+.BI \-\-export\~ index
+.OP \-\-in file
+.OP \-\-outform encoding
+.OP \-\-debug level
+.YS
+.
+.SY pki\ \-\-pkcs12
+.BI \-\-options\~ file
+.YS
+.
+.SY "pki \-\-pkcs12"
+.B \-h
+|
+.B \-\-help
+.YS
+.
+.SH "DESCRIPTION"
+.
+This sub-command of
+.BR pki (1)
+provides functions to work with PKCS#12 containers.
+.
+.SH "OPTIONS"
+.
+.TP
+.B "\-h, \-\-help"
+Print usage information with a summary of the available options.
+.TP
+.BI "\-v, \-\-debug " level
+Set debug level, default: 1.
+.TP
+.BI "\-+, \-\-options " file
+Read command line options from \fIfile\fR.
+.TP
+.BI "\-l, \-\-list"
+List certificates and keys contained in a PKCS#12 container.
+.TP
+.BI "\-e, \-\-export " index
+Export the credential with the given \fIindex\fR. Use \fI\-\-list\fR to
+determine the index of certificates and keys.
+.TP
+.BI "\-i, \-\-in " file
+PKCS#12 input file. If not given the input is read from \fISTDIN\fR.
+.
+.SH "SEE ALSO"
+.
+.BR pki (1) \ No newline at end of file
diff --git a/src/pki/man/pki---req.1.in b/src/pki/man/pki---req.1.in
index ab144ce2a..a6f6a480a 100644
--- a/src/pki/man/pki---req.1.in
+++ b/src/pki/man/pki---req.1.in
@@ -62,8 +62,8 @@ The challengePassword to include in the certificate request.
.TP
.BI "\-g, \-\-digest " digest
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
+determined based on the type and size of the signature key.
.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
diff --git a/src/pki/man/pki---self.1.in b/src/pki/man/pki---self.1.in
index 5e6e78bd0..53f53f816 100644
--- a/src/pki/man/pki---self.1.in
+++ b/src/pki/man/pki---self.1.in
@@ -109,8 +109,8 @@ Add extendedKeyUsage flag. One of \fIserverAuth\fR, \fIclientAuth\fR,
.TP
.BI "\-g, \-\-digest " digest
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
+determined based on the type and size of the signature key.
.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
@@ -127,10 +127,22 @@ times.
Set path length constraint.
.TP
.BI "\-n, \-\-nc-permitted " name
-Add permitted NameConstraint extension to certificate.
+Add permitted NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
.TP
.BI "\-N, \-\-nc-excluded " name
-Add excluded NameConstraint extension to certificate.
+Add excluded NameConstraint extension to certificate. For DNS or email
+constraints, the identity type is not always detectable by the given name. Use
+the
+.B dns:
+or
+.B email:
+prefix to force a constraint type.
.TP
.BI "\-M, \-\-policy-mapping " issuer-oid:subject-oid
Add policyMapping from issuer to subject OID.
diff --git a/src/pki/man/pki---signcrl.1.in b/src/pki/man/pki---signcrl.1.in
index bd6cba547..b930bfa3c 100644
--- a/src/pki/man/pki---signcrl.1.in
+++ b/src/pki/man/pki---signcrl.1.in
@@ -98,8 +98,8 @@ Freshest delta CRL URI to include in CRL. Can be used multiple times.
.TP
.BI "\-g, \-\-digest " digest
Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR,
-\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to
-\fIsha1\fR.
+\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is
+determined based on the type and size of the signature key.
.TP
.BI "\-f, \-\-outform " encoding
Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or
diff --git a/src/pki/pki.c b/src/pki/pki.c
index 434287de6..472704945 100644
--- a/src/pki/pki.c
+++ b/src/pki/pki.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012-2014 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -22,6 +23,7 @@
#include <fcntl.h>
#include <utils/debug.h>
+#include <credentials/sets/mem_cred.h>
#include <credentials/sets/callback_cred.h>
/**
@@ -235,12 +237,40 @@ void set_file_mode(FILE *stream, cred_encoding_type_t enc)
#endif
}
+/*
+ * Described in header
+ */
+hash_algorithm_t get_default_digest(private_key_t *private)
+{
+ enumerator_t *enumerator;
+ signature_scheme_t scheme;
+ hash_algorithm_t alg = HASH_UNKNOWN;
+
+ enumerator = signature_schemes_for_key(private->get_type(private),
+ private->get_keysize(private));
+ if (enumerator->enumerate(enumerator, &scheme))
+ {
+ alg = hasher_from_signature_scheme(scheme);
+ }
+ enumerator->destroy(enumerator);
+
+ /* default to SHA-256 */
+ return alg == HASH_UNKNOWN ? HASH_SHA256 : alg;
+}
+
/**
* Callback credential set pki uses
*/
static callback_cred_t *cb_set;
/**
+ * Credential set to cache entered secrets
+ */
+static mem_cred_t *cb_creds;
+
+static shared_key_type_t prompted;
+
+/**
* Callback function to receive credentials
*/
static shared_key_t* cb(void *data, shared_key_type_t type,
@@ -248,7 +278,12 @@ static shared_key_t* cb(void *data, shared_key_type_t type,
id_match_t *match_me, id_match_t *match_other)
{
char buf[64], *label, *secret = NULL;
+ shared_key_t *shared;
+ if (prompted == type)
+ {
+ return NULL;
+ }
switch (type)
{
case SHARED_PIN:
@@ -266,6 +301,7 @@ static shared_key_t* cb(void *data, shared_key_type_t type,
#endif
if (secret && strlen(secret))
{
+ prompted = type;
if (match_me)
{
*match_me = ID_MATCH_PERFECT;
@@ -274,8 +310,10 @@ static shared_key_t* cb(void *data, shared_key_type_t type,
{
*match_other = ID_MATCH_NONE;
}
- return shared_key_create(type,
- chunk_clone(chunk_create(secret, strlen(secret))));
+ shared = shared_key_create(type, chunk_clone(chunk_from_str(secret)));
+ /* cache password in case it is required more than once */
+ cb_creds->add_shared(cb_creds, shared, NULL);
+ return shared->get_ref(shared);
}
return NULL;
}
@@ -287,6 +325,8 @@ static void add_callback()
{
cb_set = callback_cred_create_shared(cb, NULL);
lib->credmgr->add_set(lib->credmgr, &cb_set->set);
+ cb_creds = mem_cred_create();
+ lib->credmgr->add_set(lib->credmgr, &cb_creds->set);
}
/**
@@ -294,6 +334,8 @@ static void add_callback()
*/
static void remove_callback()
{
+ lib->credmgr->remove_set(lib->credmgr, &cb_creds->set);
+ cb_creds->destroy(cb_creds);
lib->credmgr->remove_set(lib->credmgr, &cb_set->set);
cb_set->destroy(cb_set);
}
diff --git a/src/pki/pki.h b/src/pki/pki.h
index 1f0827733..017e61df6 100644
--- a/src/pki/pki.h
+++ b/src/pki/pki.h
@@ -55,4 +55,12 @@ bool calculate_lifetime(char *format, char *nbstr, char *nastr, time_t span,
*/
void set_file_mode(FILE *stream, cred_encoding_type_t enc);
+/**
+ * Select default digest for signatures with the given key
+ *
+ * @param private private key
+ * @return hash algorithm
+ */
+hash_algorithm_t get_default_digest(private_key_t *private);
+
#endif /** PKI_H_ @}*/
diff --git a/src/pool/Makefile.am b/src/pool/Makefile.am
index b8d662e57..5ae624b88 100644
--- a/src/pool/Makefile.am
+++ b/src/pool/Makefile.am
@@ -11,11 +11,13 @@ pool.o : $(top_builddir)/config.status
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
-DPLUGINS=\""${pool_plugins}\""
pool_LDADD = \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
- $(top_builddir)/src/libhydra/libhydra.la
+ $(top_builddir)/src/libhydra/libhydra.la \
+ $(top_builddir)/src/libcharon/libcharon.la
endif USE_ATTR_SQL
diff --git a/src/pool/Makefile.in b/src/pool/Makefile.in
index 4f753a0bb..b9557547a 100644
--- a/src/pool/Makefile.in
+++ b/src/pool/Makefile.in
@@ -109,7 +109,8 @@ am__pool_SOURCES_DIST = pool.c pool_attributes.c pool_attributes.h \
@USE_ATTR_SQL_TRUE@ pool_usage.$(OBJEXT)
pool_OBJECTS = $(am_pool_OBJECTS)
@USE_ATTR_SQL_TRUE@pool_DEPENDENCIES = $(top_builddir)/src/libstrongswan/libstrongswan.la \
-@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libhydra/libhydra.la
+@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libhydra/libhydra.la \
+@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libcharon/libcharon.la
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
@@ -228,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@
@@ -288,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@
@@ -365,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@
@@ -430,11 +436,13 @@ xml_LIBS = @xml_LIBS@
@USE_ATTR_SQL_TRUE@AM_CPPFLAGS = \
@USE_ATTR_SQL_TRUE@ -I$(top_srcdir)/src/libstrongswan \
@USE_ATTR_SQL_TRUE@ -I$(top_srcdir)/src/libhydra \
+@USE_ATTR_SQL_TRUE@ -I$(top_srcdir)/src/libcharon \
@USE_ATTR_SQL_TRUE@ -DPLUGINS=\""${pool_plugins}\""
@USE_ATTR_SQL_TRUE@pool_LDADD = \
@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libstrongswan/libstrongswan.la \
-@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libhydra/libhydra.la
+@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libhydra/libhydra.la \
+@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libcharon/libcharon.la
templatesdir = $(pkgdatadir)/templates/database/sql
dist_templates_DATA = mysql.sql sqlite.sql
diff --git a/src/pt-tls-client/Makefile.in b/src/pt-tls-client/Makefile.in
index 7ee25c007..a02db98f2 100644
--- a/src/pt-tls-client/Makefile.in
+++ b/src/pt-tls-client/Makefile.in
@@ -198,6 +198,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@
@@ -258,10 +259,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@
@@ -335,6 +338,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/pt-tls-client/pt-tls-client.c b/src/pt-tls-client/pt-tls-client.c
index a8d45b54f..3a179af17 100644
--- a/src/pt-tls-client/pt-tls-client.c
+++ b/src/pt-tls-client/pt-tls-client.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010-2013 Martin Willi, revosec AG
- * Copyright (C) 2013-2014 Andreas Steffen
+ * Copyright (C) 2013-2015 Andreas Steffen
* HSR Hochschule für Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -54,32 +54,44 @@ static int client(char *address, u_int16_t port, char *identity)
{
pt_tls_client_t *assessment;
tls_t *tnccs;
- identification_t *server, *client;
- host_t *host;
+ identification_t *server_id, *client_id;
+ host_t *server_ip, *client_ip;
status_t status;
- host = host_create_from_dns(address, AF_UNSPEC, port);
- if (!host)
+ server_ip = host_create_from_dns(address, AF_UNSPEC, port);
+ if (!server_ip)
{
return 1;
}
- server = identification_create_from_string(address);
- client = identification_create_from_string(identity);
+
+ client_ip = host_create_any(server_ip->get_family(server_ip));
+ if (!client_ip)
+ {
+ server_ip->destroy(server_ip);
+ return 1;
+ }
+ server_id = identification_create_from_string(address);
+ client_id = identification_create_from_string(identity);
+
tnccs = (tls_t*)tnc->tnccs->create_instance(tnc->tnccs, TNCCS_2_0, FALSE,
- server, client, TNC_IFT_TLS_2_0, NULL);
+ server_id, client_id, server_ip, client_ip,
+ TNC_IFT_TLS_2_0, NULL);
+ client_ip->destroy(client_ip);
+
if (!tnccs)
{
fprintf(stderr, "loading TNCCS failed: %s\n", PLUGINS);
- host->destroy(host);
- server->destroy(server);
- client->destroy(client);
+ server_ip->destroy(server_ip);
+ server_id->destroy(server_id);
+ client_id->destroy(client_id);
return 1;
}
- assessment = pt_tls_client_create(host, server, client);
+ assessment = pt_tls_client_create(server_ip, server_id, client_id);
status = assessment->run_assessment(assessment, (tnccs_t*)tnccs);
assessment->destroy(assessment);
tnccs->destroy(tnccs);
- return status;
+
+ return (status != SUCCESS);
}
@@ -258,6 +270,7 @@ int main(int argc, char *argv[])
{"port", required_argument, NULL, 'p' },
{"cert", required_argument, NULL, 'x' },
{"key", required_argument, NULL, 'k' },
+ {"mutual", no_argument, NULL, 'm' },
{"quiet", no_argument, NULL, 'q' },
{"debug", required_argument, NULL, 'd' },
{"optionsfrom", required_argument, NULL, '+' },
@@ -299,6 +312,10 @@ int main(int argc, char *argv[])
case 'p': /* --port <port> */
port = atoi(optarg);
continue;
+ case 'm': /* --mutual */
+ lib->settings->set_bool(lib->settings,
+ "%s.plugins.tnccs-20.mutual", TRUE, lib->ns);
+ continue;
case 'q': /* --quiet */
log_to_stderr = FALSE;
continue;
diff --git a/src/scepclient/Makefile.in b/src/scepclient/Makefile.in
index 6a947efa6..bcc70cb1b 100644
--- a/src/scepclient/Makefile.in
+++ b/src/scepclient/Makefile.in
@@ -225,6 +225,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@
@@ -285,10 +286,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@
@@ -362,6 +365,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/starter/Makefile.in b/src/starter/Makefile.in
index 88d362f6c..ee68adc21 100644
--- a/src/starter/Makefile.in
+++ b/src/starter/Makefile.in
@@ -271,6 +271,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@
@@ -331,10 +332,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@
@@ -408,6 +411,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/starter/cmp.c b/src/starter/cmp.c
index cea864a4a..aee55d94c 100644
--- a/src/starter/cmp.c
+++ b/src/starter/cmp.c
@@ -45,7 +45,7 @@ bool starter_cmp_conn(starter_conn_t *c1, starter_conn_t *c2)
VARCMP(mark_in.value);
VARCMP(mark_in.mask);
VARCMP(mark_out.value);
- VARCMP(mark_in.mask);
+ VARCMP(mark_out.mask);
VARCMP(tfc);
VARCMP(sa_keying_tries);
diff --git a/src/starter/parser/lexer.c b/src/starter/parser/lexer.c
index 157b89c31..cebf5a06c 100644
--- a/src/starter/parser/lexer.c
+++ b/src/starter/parser/lexer.c
@@ -456,8 +456,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
yyg->yy_c_buf_p = yy_cp;
/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
-#define YY_NUM_RULES 28
-#define YY_END_OF_BUFFER 29
+#define YY_NUM_RULES 29
+#define YY_END_OF_BUFFER 30
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -465,34 +465,35 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static yyconst flex_int16_t yy_accept[81] =
+static yyconst flex_int16_t yy_accept[83] =
{ 0,
- 0, 0, 0, 0, 0, 0, 29, 12, 3, 5,
+ 0, 0, 0, 0, 0, 0, 30, 12, 3, 5,
11, 4, 6, 12, 12, 2, 12, 12, 17, 13,
- 14, 15, 27, 19, 18, 20, 12, 3, 4, 4,
- 0, 12, 2, 0, 9, 12, 12, 17, 16, 27,
- 26, 24, 25, 21, 22, 23, 12, 0, 12, 12,
- 12, 0, 12, 8, 12, 12, 0, 12, 12, 12,
- 0, 12, 12, 12, 0, 0, 12, 0, 0, 0,
- 12, 0, 1, 10, 10, 0, 0, 0, 7, 0
+ 14, 15, 28, 19, 18, 20, 12, 3, 4, 4,
+ 0, 12, 2, 0, 9, 12, 12, 17, 16, 28,
+ 27, 26, 27, 24, 25, 21, 22, 23, 12, 0,
+ 12, 12, 12, 0, 12, 8, 12, 12, 0, 12,
+ 12, 12, 0, 12, 12, 12, 0, 0, 12, 0,
+ 0, 0, 12, 0, 1, 10, 10, 0, 0, 0,
+ 7, 0
} ;
static yyconst flex_int32_t yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 5, 1, 6, 7, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 4, 1, 5, 6, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 8, 1, 1, 9, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 7, 1, 1, 8, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 9, 1, 1, 1, 1, 10, 11, 12, 13,
+ 1, 10, 1, 1, 1, 1, 11, 12, 13, 14,
- 14, 15, 16, 1, 17, 1, 1, 18, 1, 19,
- 20, 21, 1, 22, 23, 24, 25, 26, 1, 1,
- 1, 1, 1, 1, 27, 1, 1, 1, 1, 1,
+ 15, 16, 17, 1, 18, 1, 1, 19, 1, 20,
+ 21, 22, 1, 23, 24, 25, 26, 27, 1, 1,
+ 1, 1, 1, 1, 28, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -509,106 +510,110 @@ static yyconst flex_int32_t yy_ec[256] =
1, 1, 1, 1, 1
} ;
-static yyconst flex_int32_t yy_meta[28] =
+static yyconst flex_int32_t yy_meta[29] =
{ 0,
- 1, 2, 3, 2, 4, 2, 5, 1, 6, 1,
+ 1, 2, 3, 1, 2, 4, 2, 5, 1, 6,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1
+ 1, 1, 1, 1, 1, 1, 1, 1
} ;
-static yyconst flex_int16_t yy_base[92] =
+static yyconst flex_int16_t yy_base[94] =
{ 0,
- 0, 16, 41, 49, 6, 7, 141, 0, 23, 172,
- 172, 0, 172, 134, 120, 30, 20, 120, 0, 172,
- 172, 33, 0, 172, 172, 50, 0, 60, 0, 0,
- 0, 118, 69, 115, 0, 109, 105, 0, 172, 0,
- 172, 172, 172, 172, 172, 172, 76, 71, 16, 69,
- 66, 67, 72, 0, 71, 74, 69, 69, 64, 69,
- 62, 77, 61, 55, 60, 54, 94, 66, 64, 49,
- 100, 46, 172, 172, 74, 24, 16, 5, 172, 172,
- 107, 113, 119, 125, 131, 137, 142, 147, 153, 159,
- 165
+ 0, 17, 43, 52, 7, 26, 102, 0, 9, 189,
+ 189, 0, 189, 93, 79, 36, 10, 83, 0, 189,
+ 189, 59, 0, 189, 189, 85, 0, 32, 0, 0,
+ 0, 83, 65, 80, 0, 74, 70, 0, 189, 0,
+ 189, 189, 88, 189, 189, 189, 189, 189, 71, 63,
+ 31, 61, 58, 59, 64, 0, 63, 66, 61, 61,
+ 56, 60, 53, 64, 41, 10, 40, 32, 109, 66,
+ 49, 27, 116, 37, 189, 189, 71, 8, 2, 5,
+ 189, 189, 124, 130, 136, 142, 148, 154, 159, 164,
+ 170, 176, 182
} ;
-static yyconst flex_int16_t yy_def[92] =
+static yyconst flex_int16_t yy_def[94] =
{ 0,
- 81, 81, 82, 82, 83, 83, 80, 84, 80, 80,
- 80, 85, 80, 84, 84, 80, 84, 84, 86, 80,
- 80, 80, 87, 80, 80, 88, 84, 80, 85, 85,
- 84, 84, 80, 80, 84, 84, 84, 86, 80, 87,
- 80, 80, 80, 80, 80, 80, 84, 80, 84, 84,
- 84, 80, 84, 84, 84, 84, 80, 84, 84, 84,
- 80, 84, 84, 84, 80, 80, 89, 90, 91, 80,
- 89, 91, 80, 80, 90, 80, 80, 80, 80, 0,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80
+ 83, 83, 84, 84, 85, 85, 82, 86, 82, 82,
+ 82, 87, 82, 86, 86, 82, 86, 86, 88, 82,
+ 82, 82, 89, 82, 82, 90, 86, 82, 87, 87,
+ 86, 86, 82, 82, 86, 86, 86, 88, 82, 89,
+ 82, 82, 82, 82, 82, 82, 82, 82, 86, 82,
+ 86, 86, 86, 82, 86, 86, 86, 86, 82, 86,
+ 86, 86, 82, 86, 86, 86, 82, 82, 91, 92,
+ 93, 82, 91, 93, 82, 82, 92, 82, 82, 82,
+ 82, 0, 82, 82, 82, 82, 82, 82, 82, 82,
+ 82, 82, 82
} ;
-static yyconst flex_int16_t yy_nxt[200] =
+static yyconst flex_int16_t yy_nxt[218] =
{ 0,
- 80, 9, 10, 9, 11, 12, 13, 14, 24, 24,
- 25, 25, 80, 80, 26, 26, 15, 16, 10, 16,
- 11, 12, 13, 14, 28, 79, 28, 17, 29, 35,
- 53, 33, 15, 33, 54, 29, 39, 39, 39, 36,
- 78, 18, 20, 20, 20, 21, 20, 77, 73, 22,
- 20, 20, 20, 21, 20, 34, 68, 22, 68, 39,
- 42, 28, 76, 28, 43, 29, 73, 75, 44, 75,
- 33, 45, 33, 46, 29, 75, 70, 75, 69, 67,
- 66, 65, 64, 63, 62, 61, 60, 59, 58, 57,
- 56, 55, 52, 51, 34, 72, 73, 72, 72, 72,
-
- 72, 72, 73, 72, 72, 72, 72, 8, 8, 8,
- 8, 8, 8, 19, 19, 19, 19, 19, 19, 23,
- 23, 23, 23, 23, 23, 27, 50, 49, 48, 47,
- 27, 30, 30, 37, 30, 30, 30, 38, 32, 31,
- 80, 38, 40, 40, 80, 80, 40, 41, 41, 41,
- 41, 41, 41, 71, 71, 71, 71, 71, 71, 74,
- 74, 74, 74, 80, 74, 72, 72, 72, 72, 72,
- 72, 7, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80
-
+ 82, 9, 10, 82, 9, 11, 12, 13, 14, 24,
+ 28, 70, 25, 28, 70, 29, 26, 15, 16, 10,
+ 35, 16, 11, 12, 13, 14, 81, 80, 24, 17,
+ 36, 25, 79, 28, 15, 26, 28, 33, 29, 75,
+ 33, 78, 29, 18, 20, 20, 55, 20, 21, 20,
+ 56, 75, 22, 20, 20, 72, 20, 21, 20, 71,
+ 69, 22, 34, 39, 39, 39, 33, 77, 68, 33,
+ 77, 29, 77, 67, 66, 77, 65, 64, 63, 62,
+ 61, 60, 59, 58, 57, 54, 39, 42, 43, 53,
+ 42, 34, 52, 51, 50, 49, 44, 37, 32, 31,
+
+ 45, 82, 82, 82, 46, 82, 82, 47, 82, 48,
+ 74, 75, 82, 74, 74, 74, 74, 74, 75, 82,
+ 74, 74, 74, 74, 8, 8, 8, 8, 8, 8,
+ 19, 19, 19, 19, 19, 19, 23, 23, 23, 23,
+ 23, 23, 27, 82, 82, 82, 82, 27, 30, 30,
+ 82, 30, 30, 30, 38, 82, 82, 82, 38, 40,
+ 40, 82, 82, 40, 41, 41, 41, 41, 41, 41,
+ 73, 73, 73, 73, 73, 73, 76, 76, 76, 76,
+ 82, 76, 74, 74, 74, 74, 74, 74, 7, 82,
+ 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
+
+ 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
+ 82, 82, 82, 82, 82, 82, 82
} ;
-static yyconst flex_int16_t yy_chk[200] =
+static yyconst flex_int16_t yy_chk[218] =
{ 0,
- 0, 1, 1, 1, 1, 1, 1, 1, 5, 6,
- 5, 6, 0, 0, 5, 6, 1, 2, 2, 2,
- 2, 2, 2, 2, 9, 78, 9, 2, 9, 17,
- 49, 16, 2, 16, 49, 16, 22, 22, 22, 17,
- 77, 2, 3, 3, 3, 3, 3, 76, 72, 3,
- 4, 4, 4, 4, 4, 16, 64, 4, 64, 22,
- 26, 28, 70, 28, 26, 28, 69, 68, 26, 68,
- 33, 26, 33, 26, 33, 75, 66, 75, 65, 63,
- 62, 61, 60, 59, 58, 57, 56, 55, 53, 52,
- 51, 50, 48, 47, 33, 67, 67, 67, 67, 67,
-
- 67, 71, 71, 71, 71, 71, 71, 81, 81, 81,
- 81, 81, 81, 82, 82, 82, 82, 82, 82, 83,
- 83, 83, 83, 83, 83, 84, 37, 36, 34, 32,
- 84, 85, 85, 18, 85, 85, 85, 86, 15, 14,
- 7, 86, 87, 87, 0, 0, 87, 88, 88, 88,
- 88, 88, 88, 89, 89, 89, 89, 89, 89, 90,
- 90, 90, 90, 0, 90, 91, 91, 91, 91, 91,
- 91, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
- 80, 80, 80, 80, 80, 80, 80, 80, 80
-
+ 0, 1, 1, 0, 1, 1, 1, 1, 1, 5,
+ 9, 66, 5, 9, 66, 9, 5, 1, 2, 2,
+ 17, 2, 2, 2, 2, 2, 80, 79, 6, 2,
+ 17, 6, 78, 28, 2, 6, 28, 16, 28, 74,
+ 16, 72, 16, 2, 3, 3, 51, 3, 3, 3,
+ 51, 71, 3, 4, 4, 68, 4, 4, 4, 67,
+ 65, 4, 16, 22, 22, 22, 33, 70, 64, 33,
+ 70, 33, 77, 63, 62, 77, 61, 60, 59, 58,
+ 57, 55, 54, 53, 52, 50, 22, 26, 26, 49,
+ 43, 33, 37, 36, 34, 32, 26, 18, 15, 14,
+
+ 26, 7, 0, 0, 26, 0, 0, 26, 0, 26,
+ 69, 69, 0, 69, 69, 69, 69, 73, 73, 0,
+ 73, 73, 73, 73, 83, 83, 83, 83, 83, 83,
+ 84, 84, 84, 84, 84, 84, 85, 85, 85, 85,
+ 85, 85, 86, 0, 0, 0, 0, 86, 87, 87,
+ 0, 87, 87, 87, 88, 0, 0, 0, 88, 89,
+ 89, 0, 0, 89, 90, 90, 90, 90, 90, 90,
+ 91, 91, 91, 91, 91, 91, 92, 92, 92, 92,
+ 0, 92, 93, 93, 93, 93, 93, 93, 82, 82,
+ 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
+
+ 82, 82, 82, 82, 82, 82, 82, 82, 82, 82,
+ 82, 82, 82, 82, 82, 82, 82
} ;
/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[29] =
+static yyconst flex_int32_t yy_rule_can_match_eol[30] =
{ 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1,
- 1, 0, 0, 0, 0, 0, 1, 0, 0, };
+ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, };
-static yyconst flex_int16_t yy_rule_linenum[28] =
+static yyconst flex_int16_t yy_rule_linenum[29] =
{ 0,
60, 61, 62, 63, 65, 67, 68, 69, 70, 72,
77, 82, 90, 109, 112, 115, 118, 124, 126, 127,
- 150, 151, 152, 153, 154, 155, 158
+ 150, 151, 152, 153, 154, 155, 156, 157
} ;
/* The intent behind this definition is that it'll catch
@@ -657,7 +662,7 @@ static void include_files(parser_helper_t *ctx);
/* state used to scan quoted strings */
-#line 661 "parser/lexer.c"
+#line 666 "parser/lexer.c"
#define INITIAL 0
#define inc 1
@@ -972,7 +977,7 @@ YY_DECL
#line 58 "parser/lexer.l"
-#line 976 "parser/lexer.c"
+#line 981 "parser/lexer.c"
yylval = yylval_param;
@@ -1038,13 +1043,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 81 )
+ if ( yy_current_state >= 83 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 172 );
+ while ( yy_base[yy_current_state] != 189 );
yy_find_action:
/* %% [10.0] code to find the action number goes here */
@@ -1079,13 +1084,13 @@ do_action: /* This label is used only to access EOF actions. */
{
if ( yy_act == 0 )
fprintf( stderr, "--scanner backing up\n" );
- else if ( yy_act < 28 )
+ else if ( yy_act < 29 )
fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
(long)yy_rule_linenum[yy_act], yytext );
- else if ( yy_act == 28 )
+ else if ( yy_act == 29 )
fprintf( stderr, "--accepting default rule (\"%s\")\n",
yytext );
- else if ( yy_act == 29 )
+ else if ( yy_act == 30 )
fprintf( stderr, "--(end of buffer or a NUL)\n" );
else
fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -1300,20 +1305,23 @@ case 26:
/* rule 26 can match eol */
YY_RULE_SETUP
#line 155 "parser/lexer.l"
-{
- yyextra->string_add(yyextra, yytext+1);
- }
+/* merge lines that end with EOL characters */
YY_BREAK
case 27:
YY_RULE_SETUP
-#line 158 "parser/lexer.l"
+#line 156 "parser/lexer.l"
+yyextra->string_add(yyextra, yytext+1);
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 157 "parser/lexer.l"
{
yyextra->string_add(yyextra, yytext);
}
YY_BREAK
case YY_STATE_EOF(INITIAL):
-#line 163 "parser/lexer.l"
+#line 162 "parser/lexer.l"
{
conf_parser_pop_buffer_state(yyscanner);
if (!conf_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER)
@@ -1322,12 +1330,12 @@ case YY_STATE_EOF(INITIAL):
}
}
YY_BREAK
-case 28:
+case 29:
YY_RULE_SETUP
-#line 171 "parser/lexer.l"
+#line 170 "parser/lexer.l"
YY_FATAL_ERROR( "flex scanner jammed" );
YY_BREAK
-#line 1331 "parser/lexer.c"
+#line 1339 "parser/lexer.c"
case YY_END_OF_BUFFER:
{
@@ -1641,7 +1649,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 81 )
+ if ( yy_current_state >= 83 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1675,11 +1683,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 81 )
+ if ( yy_current_state >= 83 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 80);
+ yy_is_jam = (yy_current_state == 82);
return yy_is_jam ? 0 : yy_current_state;
}
@@ -2697,7 +2705,7 @@ void conf_parser_free (void * ptr , yyscan_t yyscanner)
/* %ok-for-header */
-#line 171 "parser/lexer.l"
+#line 170 "parser/lexer.l"
diff --git a/src/starter/parser/lexer.l b/src/starter/parser/lexer.l
index a88cbe809..d967e745b 100644
--- a/src/starter/parser/lexer.l
+++ b/src/starter/parser/lexer.l
@@ -152,9 +152,8 @@ static void include_files(parser_helper_t *ctx);
\\t yyextra->string_add(yyextra, "\t");
\\b yyextra->string_add(yyextra, "\b");
\\f yyextra->string_add(yyextra, "\f");
- \\(.|\n) {
- yyextra->string_add(yyextra, yytext+1);
- }
+ \\\r?\n /* merge lines that end with EOL characters */
+ \\. yyextra->string_add(yyextra, yytext+1);
[^\\\n"]+ {
yyextra->string_add(yyextra, yytext);
}
diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c
index 1e305db8b..6e1f1605d 100644
--- a/src/starter/starterstroke.c
+++ b/src/starter/starterstroke.c
@@ -35,10 +35,16 @@ static char* push_string(stroke_msg_t *msg, char *string)
{
unsigned long string_start = msg->length;
- if (string == NULL || msg->length + strlen(string) >= sizeof(stroke_msg_t))
+ if (string == NULL)
{
return NULL;
}
+ else if ((size_t)msg->length + strlen(string) >= sizeof(stroke_msg_t))
+ {
+ /* set invalid length to fail during message send */
+ msg->length = ~0;
+ return NULL;
+ }
else
{
msg->length += strlen(string) + 1;
@@ -53,6 +59,12 @@ static int send_stroke_msg (stroke_msg_t *msg)
char *uri, buffer[64];
int count;
+ if (msg->length > sizeof(stroke_msg_t))
+ {
+ DBG1(DBG_APP, "stroke message exceeds buffer size");
+ return -1;
+ }
+
/* starter is not called from commandline, and therefore absolutely silent */
msg->output_verbosity = -1;
diff --git a/src/starter/tests/Makefile.in b/src/starter/tests/Makefile.in
index d42a0d286..b26125501 100644
--- a/src/starter/tests/Makefile.in
+++ b/src/starter/tests/Makefile.in
@@ -223,6 +223,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@
@@ -283,10 +284,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@
@@ -360,6 +363,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/stroke/Makefile.in b/src/stroke/Makefile.in
index 9c041dfbf..c32ebf905 100644
--- a/src/stroke/Makefile.in
+++ b/src/stroke/Makefile.in
@@ -197,6 +197,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@
@@ -257,10 +258,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@
@@ -334,6 +337,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/stroke/stroke_msg.h b/src/stroke/stroke_msg.h
index 60886cf7f..c2b923f6d 100644
--- a/src/stroke/stroke_msg.h
+++ b/src/stroke/stroke_msg.h
@@ -32,7 +32,7 @@
*/
#define STROKE_SOCKET IPSEC_PIDDIR "/charon.ctl"
-#define STROKE_BUF_LEN 2048
+#define STROKE_BUF_LEN 4096
typedef enum list_flag_t list_flag_t;
diff --git a/src/swanctl/Makefile.am b/src/swanctl/Makefile.am
index b84d70587..f4f9fdf7e 100644
--- a/src/swanctl/Makefile.am
+++ b/src/swanctl/Makefile.am
@@ -65,4 +65,5 @@ install-data-local: swanctl.conf
test -e "$(DESTDIR)$(swanctldir)/rsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/rsa" || true
test -e "$(DESTDIR)$(swanctldir)/ecdsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/ecdsa" || true
test -e "$(DESTDIR)$(swanctldir)/pkcs8" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs8" || true
+ test -e "$(DESTDIR)$(swanctldir)/pkcs12" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs12" || true
test -e "$(DESTDIR)$(swanctldir)/swanctl.conf" || $(INSTALL) -m 640 $(srcdir)/swanctl.conf $(DESTDIR)$(swanctldir)/swanctl.conf || true
diff --git a/src/swanctl/Makefile.in b/src/swanctl/Makefile.in
index 649e6d8ae..f981bb1f3 100644
--- a/src/swanctl/Makefile.in
+++ b/src/swanctl/Makefile.in
@@ -238,6 +238,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@
@@ -298,10 +299,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@
@@ -375,6 +378,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@
@@ -991,6 +996,7 @@ install-data-local: swanctl.conf
test -e "$(DESTDIR)$(swanctldir)/rsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/rsa" || true
test -e "$(DESTDIR)$(swanctldir)/ecdsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/ecdsa" || true
test -e "$(DESTDIR)$(swanctldir)/pkcs8" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs8" || true
+ test -e "$(DESTDIR)$(swanctldir)/pkcs12" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs12" || true
test -e "$(DESTDIR)$(swanctldir)/swanctl.conf" || $(INSTALL) -m 640 $(srcdir)/swanctl.conf $(DESTDIR)$(swanctldir)/swanctl.conf || true
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/swanctl/commands/list_conns.c b/src/swanctl/commands/list_conns.c
index 31ab9c40a..019c88888 100644
--- a/src/swanctl/commands/list_conns.c
+++ b/src/swanctl/commands/list_conns.c
@@ -103,7 +103,7 @@ CALLBACK(conn_sn, int,
{
return vici_parse_cb(res, children_sn, NULL, NULL, NULL);
}
- if (streq(name, "local") || streq(name, "remote"))
+ if (strpfx(name, "local") || strpfx(name, "remote"))
{
hashtable_t *auth;
@@ -112,7 +112,8 @@ CALLBACK(conn_sn, int,
if (ret == 0)
{
printf(" %s %s authentication:\n",
- name, auth->get(auth, "class") ?: "unspecified");
+ strpfx(name, "local") ? "local" : "remote",
+ auth->get(auth, "class") ?: "unspecified");
if (auth->get(auth, "id"))
{
printf(" id: %s\n", auth->get(auth, "id"));
diff --git a/src/swanctl/commands/list_sas.c b/src/swanctl/commands/list_sas.c
index 35e7469a9..81e1b7cca 100644
--- a/src/swanctl/commands/list_sas.c
+++ b/src/swanctl/commands/list_sas.c
@@ -86,8 +86,8 @@ CALLBACK(child_sas, int,
ret = vici_parse_cb(res, NULL, sa_values, sa_list, child);
if (ret == 0)
{
- printf(" %s: #%s, %s, %s%s, %s:",
- name, child->get(child, "reqid"),
+ printf(" %s: #%s, reqid %s, %s, %s%s, %s:",
+ name, child->get(child, "uniqueid"), child->get(child, "reqid"),
child->get(child, "state"), child->get(child, "mode"),
child->get(child, "encap") ? "-in-UDP" : "",
child->get(child, "protocol"));
@@ -122,7 +122,7 @@ CALLBACK(child_sas, int,
}
if (child->get(child, "esn"))
{
- printf("/%s", child->get(child, "esn"));
+ printf("/ESN");
}
printf("\n");
diff --git a/src/swanctl/commands/load_conns.c b/src/swanctl/commands/load_conns.c
index de30d8eb4..6ee8b8785 100644
--- a/src/swanctl/commands/load_conns.c
+++ b/src/swanctl/commands/load_conns.c
@@ -93,11 +93,12 @@ static void add_list_key(vici_req_t *req, char *key, char *value)
/**
* Add a vici list of blobs from a comma separated file list
*/
-static void add_file_list_key(vici_req_t *req, char *key, char *value)
+static bool add_file_list_key(vici_req_t *req, char *key, char *value)
{
enumerator_t *enumerator;
chunk_t *map;
char *token, buf[PATH_MAX];
+ bool ret = TRUE;
vici_begin_list(req, key);
enumerator = enumerator_create_token(value, ",", " ");
@@ -127,21 +128,26 @@ static void add_file_list_key(vici_req_t *req, char *key, char *value)
}
else
{
- fprintf(stderr, "loading certificate '%s' failed: %s\n",
- token, strerror(errno));
+ fprintf(stderr, "loading %s certificate '%s' failed: %s\n",
+ key, token, strerror(errno));
+ ret = FALSE;
+ break;
}
}
enumerator->destroy(enumerator);
vici_end_list(req);
+
+ return ret;
}
/**
* Translate setting key/values from a section into vici key-values/lists
*/
-static void add_key_values(vici_req_t *req, settings_t *cfg, char *section)
+static bool add_key_values(vici_req_t *req, settings_t *cfg, char *section)
{
enumerator_t *enumerator;
char *key, *value;
+ bool ret = TRUE;
enumerator = cfg->create_key_value_enumerator(cfg, section);
while (enumerator->enumerate(enumerator, &key, &value))
@@ -152,34 +158,51 @@ static void add_key_values(vici_req_t *req, settings_t *cfg, char *section)
}
else if (is_file_list_key(key))
{
- add_file_list_key(req, key, value);
+ ret = add_file_list_key(req, key, value);
}
else
{
vici_add_key_valuef(req, key, "%s", value);
}
+ if (!ret)
+ {
+ break;
+ }
}
enumerator->destroy(enumerator);
+
+ return ret;
}
/**
* Translate a settings section to a vici section
*/
-static void add_sections(vici_req_t *req, settings_t *cfg, char *section)
+static bool add_sections(vici_req_t *req, settings_t *cfg, char *section)
{
enumerator_t *enumerator;
char *name, buf[256];
+ bool ret = TRUE;
enumerator = cfg->create_section_enumerator(cfg, section);
while (enumerator->enumerate(enumerator, &name))
{
vici_begin_section(req, name);
snprintf(buf, sizeof(buf), "%s.%s", section, name);
- add_key_values(req, cfg, buf);
- add_sections(req, cfg, buf);
+ ret = add_key_values(req, cfg, buf);
+ if (!ret)
+ {
+ break;
+ }
+ ret = add_sections(req, cfg, buf);
+ if (!ret)
+ {
+ break;
+ }
vici_end_section(req);
}
enumerator->destroy(enumerator);
+
+ return ret;
}
/**
@@ -198,8 +221,12 @@ static bool load_conn(vici_conn_t *conn, settings_t *cfg,
req = vici_begin("load-conn");
vici_begin_section(req, section);
- add_key_values(req, cfg, buf);
- add_sections(req, cfg, buf);
+ if (!add_key_values(req, cfg, buf) ||
+ !add_sections(req, cfg, buf))
+ {
+ vici_free_req(req);
+ return FALSE;
+ }
vici_end_section(req);
res = vici_submit(req, conn);
diff --git a/src/swanctl/commands/load_creds.c b/src/swanctl/commands/load_creds.c
index 86ee3c179..d2ebc22eb 100644
--- a/src/swanctl/commands/load_creds.c
+++ b/src/swanctl/commands/load_creds.c
@@ -25,6 +25,7 @@
#include <credentials/sets/mem_cred.h>
#include <credentials/sets/callback_cred.h>
+#include <credentials/containers/pkcs12.h>
/**
* Load a single certificate over vici
@@ -60,7 +61,7 @@ static bool load_cert(vici_conn_t *conn, command_format_options_t format,
}
else
{
- printf("loaded %s certificate '%s'\n", type, dir);
+ printf("loaded %s certificate from '%s'\n", type, dir);
}
vici_free_res(res);
return ret;
@@ -113,7 +114,14 @@ static bool load_key(vici_conn_t *conn, command_format_options_t format,
req = vici_begin("load-key");
- vici_add_key_valuef(req, "type", "%s", type);
+ if (streq(type, "pkcs8"))
+ { /* as used by vici */
+ vici_add_key_valuef(req, "type", "any");
+ }
+ else
+ {
+ vici_add_key_valuef(req, "type", "%s", type);
+ }
vici_add_key_value(req, "data", data.ptr, data.len);
res = vici_submit(req, conn);
@@ -135,20 +143,59 @@ static bool load_key(vici_conn_t *conn, command_format_options_t format,
}
else
{
- printf("loaded %s key '%s'\n", type, dir);
+ printf("loaded %s key from '%s'\n", type, dir);
}
vici_free_res(res);
return ret;
}
/**
+ * Load a private key of any type to vici
+ */
+static bool load_key_anytype(vici_conn_t *conn, command_format_options_t format,
+ char *path, private_key_t *private)
+{
+ bool loaded = FALSE;
+ chunk_t encoding;
+
+ if (!private->get_encoding(private, PRIVKEY_ASN1_DER, &encoding))
+ {
+ fprintf(stderr, "encoding private key from '%s' failed\n", path);
+ return FALSE;
+ }
+ switch (private->get_type(private))
+ {
+ case KEY_RSA:
+ loaded = load_key(conn, format, path, "rsa", encoding);
+ break;
+ case KEY_ECDSA:
+ loaded = load_key(conn, format, path, "ecdsa", encoding);
+ break;
+ default:
+ fprintf(stderr, "unsupported key type in '%s'\n", path);
+ break;
+ }
+ chunk_clear(&encoding);
+ return loaded;
+}
+
+/**
+ * Data passed to password callback
+ */
+typedef struct {
+ char prompt[128];
+ mem_cred_t *cache;
+} cb_data_t;
+
+/**
* Callback function to prompt for private key passwords
*/
CALLBACK(password_cb, shared_key_t*,
- char *prompt, shared_key_type_t type,
+ cb_data_t *data, shared_key_type_t type,
identification_t *me, identification_t *other,
id_match_t *match_me, id_match_t *match_other)
{
+ shared_key_t *shared;
char *pwd = NULL;
if (type != SHARED_PRIVATE_KEY_PASS)
@@ -156,7 +203,7 @@ CALLBACK(password_cb, shared_key_t*,
return NULL;
}
#ifdef HAVE_GETPASS
- pwd = getpass(prompt);
+ pwd = getpass(data->prompt);
#endif
if (!pwd || strlen(pwd) == 0)
{
@@ -170,65 +217,94 @@ CALLBACK(password_cb, shared_key_t*,
{
*match_other = ID_MATCH_PERFECT;
}
- return shared_key_create(type, chunk_clone(chunk_from_str(pwd)));
+ shared = shared_key_create(type, chunk_clone(chunk_from_str(pwd)));
+ /* cache secret if it is required more than once (PKCS#12) */
+ data->cache->add_shared(data->cache, shared, NULL);
+ return shared->get_ref(shared);
}
/**
- * Try to parse a potentially encrypted private key using password prompt
+ * Determine credential type and subtype from a type string
*/
-static private_key_t* decrypt_key(char *name, char *type, chunk_t encoding)
+static bool determine_credtype(char *type, credential_type_t *credtype,
+ int *subtype)
{
- key_type_t kt = KEY_ANY;
- private_key_t *private;
- callback_cred_t *cb;
- char buf[128];
+ struct {
+ char *type;
+ credential_type_t credtype;
+ int subtype;
+ } map[] = {
+ { "pkcs8", CRED_PRIVATE_KEY, KEY_ANY, },
+ { "rsa", CRED_PRIVATE_KEY, KEY_RSA, },
+ { "ecdsa", CRED_PRIVATE_KEY, KEY_ECDSA, },
+ { "pkcs12", CRED_CONTAINER, CONTAINER_PKCS12, },
+ };
+ int i;
- if (streq(type, "rsa"))
+ for (i = 0; i < countof(map); i++)
{
- kt = KEY_RSA;
+ if (streq(map[i].type, type))
+ {
+ *credtype = map[i].credtype;
+ *subtype = map[i].subtype;
+ return TRUE;
+ }
}
- else if (streq(type, "ecdsa"))
+ return FALSE;
+}
+
+/**
+ * Try to parse a potentially encrypted credential using password prompt
+ */
+static void* decrypt(char *name, char *type, chunk_t encoding)
+{
+ credential_type_t credtype;
+ int subtype;
+ void *cred;
+ callback_cred_t *cb;
+ cb_data_t data;
+
+ if (!determine_credtype(type, &credtype, &subtype))
{
- kt = KEY_ECDSA;
+ return NULL;
}
- snprintf(buf, sizeof(buf), "Password for '%s': ", name);
+ snprintf(data.prompt, sizeof(data.prompt), "Password for %s file '%s': ",
+ type, name);
- cb = callback_cred_create_shared(password_cb, buf);
+ data.cache = mem_cred_create();
+ lib->credmgr->add_set(lib->credmgr, &data.cache->set);
+ cb = callback_cred_create_shared(password_cb, &data);
lib->credmgr->add_set(lib->credmgr, &cb->set);
- private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, kt,
- BUILD_BLOB_PEM, encoding, BUILD_END);
+ cred = lib->creds->create(lib->creds, credtype, subtype,
+ BUILD_BLOB_PEM, encoding, BUILD_END);
+ lib->credmgr->remove_set(lib->credmgr, &data.cache->set);
+ data.cache->destroy(data.cache);
lib->credmgr->remove_set(lib->credmgr, &cb->set);
cb->destroy(cb);
- return private;
+ return cred;
}
/**
- * Try to parse a potentially encrypted private key using configured secret
+ * Try to parse a potentially encrypted credential using configured secret
*/
-static private_key_t* decrypt_key_with_config(settings_t *cfg, char *name,
- char *type, chunk_t encoding)
-{ key_type_t kt = KEY_ANY;
+static void* decrypt_with_config(settings_t *cfg, char *name, char *type,
+ chunk_t encoding)
+{
+ credential_type_t credtype;
+ int subtype;
enumerator_t *enumerator, *secrets;
char *section, *key, *value, *file, buf[128];
shared_key_t *shared;
- private_key_t *private = NULL;
+ void *cred = NULL;
mem_cred_t *mem = NULL;
- if (streq(type, "rsa"))
- {
- kt = KEY_RSA;
- }
- else if (streq(type, "ecdsa"))
- {
- kt = KEY_ECDSA;
- }
- else
+ if (!determine_credtype(type, &credtype, &subtype))
{
- type = "pkcs8";
+ return NULL;
}
/* load all secrets for this key type */
@@ -265,12 +341,12 @@ static private_key_t* decrypt_key_with_config(settings_t *cfg, char *name,
{
lib->credmgr->add_local_set(lib->credmgr, &mem->set, FALSE);
- private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, kt,
- BUILD_BLOB_PEM, encoding, BUILD_END);
+ cred = lib->creds->create(lib->creds, credtype, subtype,
+ BUILD_BLOB_PEM, encoding, BUILD_END);
lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
- if (!private)
+ if (!cred)
{
fprintf(stderr, "configured decryption secret for '%s' invalid\n",
name);
@@ -279,7 +355,7 @@ static private_key_t* decrypt_key_with_config(settings_t *cfg, char *name,
mem->destroy(mem);
}
- return private;
+ return cred;
}
/**
@@ -292,30 +368,15 @@ static bool load_encrypted_key(vici_conn_t *conn,
{
private_key_t *private;
bool loaded = FALSE;
- chunk_t encoding;
- private = decrypt_key_with_config(cfg, rel, type, data);
+ private = decrypt_with_config(cfg, rel, type, data);
if (!private && !noprompt)
{
- private = decrypt_key(rel, type, data);
+ private = decrypt(rel, type, data);
}
if (private)
{
- if (private->get_encoding(private, PRIVKEY_ASN1_DER, &encoding))
- {
- switch (private->get_type(private))
- {
- case KEY_RSA:
- loaded = load_key(conn, format, path, "rsa", encoding);
- break;
- case KEY_ECDSA:
- loaded = load_key(conn, format, path, "ecdsa", encoding);
- break;
- default:
- break;
- }
- chunk_clear(&encoding);
- }
+ loaded = load_key_anytype(conn, format, path, private);
private->destroy(private);
}
return loaded;
@@ -361,6 +422,114 @@ static void load_keys(vici_conn_t *conn, command_format_options_t format,
}
/**
+ * Load credentials from a PKCS#12 container over vici
+ */
+static bool load_pkcs12(vici_conn_t *conn, command_format_options_t format,
+ char *path, pkcs12_t *p12)
+{
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ private_key_t *private;
+ chunk_t encoding;
+ bool loaded = TRUE;
+
+ enumerator = p12->create_cert_enumerator(p12);
+ while (loaded && enumerator->enumerate(enumerator, &cert))
+ {
+ loaded = FALSE;
+ if (cert->get_encoding(cert, CERT_ASN1_DER, &encoding))
+ {
+ loaded = load_cert(conn, format, path, "x509", encoding);
+ if (loaded)
+ {
+ fprintf(stderr, " %Y\n", cert->get_subject(cert));
+ }
+ free(encoding.ptr);
+ }
+ else
+ {
+ fprintf(stderr, "encoding certificate from '%s' failed\n", path);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ enumerator = p12->create_key_enumerator(p12);
+ while (loaded && enumerator->enumerate(enumerator, &private))
+ {
+ loaded = load_key_anytype(conn, format, path, private);
+ }
+ enumerator->destroy(enumerator);
+
+ return loaded;
+}
+
+/**
+ * Try to decrypt and load credentials from a container
+ */
+static bool load_encrypted_container(vici_conn_t *conn,
+ command_format_options_t format, settings_t *cfg, char *rel,
+ char *path, char *type, bool noprompt, chunk_t data)
+{
+ container_t *container;
+ bool loaded = FALSE;
+
+ container = decrypt_with_config(cfg, rel, type, data);
+ if (!container && !noprompt)
+ {
+ container = decrypt(rel, type, data);
+ }
+ if (container)
+ {
+ switch (container->get_type(container))
+ {
+ case CONTAINER_PKCS12:
+ loaded = load_pkcs12(conn, format, path, (pkcs12_t*)container);
+ break;
+ default:
+ break;
+ }
+ container->destroy(container);
+ }
+ return loaded;
+}
+
+/**
+ * Load credential containers from a directory
+ */
+static void load_containers(vici_conn_t *conn, command_format_options_t format,
+ bool noprompt, settings_t *cfg, char *type, char *dir)
+{
+ enumerator_t *enumerator;
+ struct stat st;
+ chunk_t *map;
+ char *path, *rel;
+
+ enumerator = enumerator_create_directory(dir);
+ if (enumerator)
+ {
+ while (enumerator->enumerate(enumerator, &rel, &path, &st))
+ {
+ if (S_ISREG(st.st_mode))
+ {
+ map = chunk_map(path, FALSE);
+ if (map)
+ {
+ load_encrypted_container(conn, format, cfg, rel, path,
+ type, noprompt, *map);
+ chunk_unmap(map);
+ }
+ else
+ {
+ fprintf(stderr, "mapping '%s' failed: %s, skipped\n",
+ path, strerror(errno));
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+}
+
+/**
* Load a single secret over VICI
*/
static bool load_secret(vici_conn_t *conn, settings_t *cfg,
@@ -380,6 +549,7 @@ static bool load_secret(vici_conn_t *conn, settings_t *cfg,
"rsa",
"ecdsa",
"pkcs8",
+ "pkcs12",
};
for (i = 0; i < countof(types); i++)
@@ -510,7 +680,9 @@ int load_creds_cfg(vici_conn_t *conn, command_format_options_t format,
load_keys(conn, format, noprompt, cfg, "rsa", SWANCTL_RSADIR);
load_keys(conn, format, noprompt, cfg, "ecdsa", SWANCTL_ECDSADIR);
- load_keys(conn, format, noprompt, cfg, "any", SWANCTL_PKCS8DIR);
+ load_keys(conn, format, noprompt, cfg, "pkcs8", SWANCTL_PKCS8DIR);
+
+ load_containers(conn, format, noprompt, cfg, "pkcs12", SWANCTL_PKCS12DIR);
enumerator = cfg->create_section_enumerator(cfg, "secrets");
while (enumerator->enumerate(enumerator, &section))
diff --git a/src/swanctl/swanctl.conf b/src/swanctl/swanctl.conf
index 0808cf58b..faafecc44 100644
--- a/src/swanctl/swanctl.conf
+++ b/src/swanctl/swanctl.conf
@@ -286,6 +286,18 @@
# }
+ # PKCS#12 decryption passphrase for a container in the pkcs12 folder.
+ # pkcs12<suffix> {
+
+ # File name in the pkcs12 folder for which this passphrase should be
+ # used.
+ # file =
+
+ # Value of decryption passphrase for PKCS#12 container.
+ # secret =
+
+ # }
+
# }
# Section defining named pools.
@@ -294,7 +306,7 @@
# Section defining a single pool with a unique name.
# <name> {
- # Subnet defining addresses allocated in pool.
+ # Addresses allocated in pool.
# addrs =
# Comma separated list of additional attributes from type <attr>.
diff --git a/src/swanctl/swanctl.conf.5.main b/src/swanctl/swanctl.conf.5.main
index 8943b62db..a770b28b1 100644
--- a/src/swanctl/swanctl.conf.5.main
+++ b/src/swanctl/swanctl.conf.5.main
@@ -251,7 +251,12 @@ performs a reauthentication procedure instead.
With the default value IKE rekeying is scheduled every 4 hours, minus the
configured
.RB "" "rand_time" "."
-
+If a
+.RB "" "reauth_time" ""
+is configured,
+.RB "" "rekey_time" ""
+defaults to zero disabling rekeying; explicitly set both to enforce rekeying and
+reauthentication.
.TP
.BR connections.<conn>.over_time " [10% of rekey_time/reauth_time]"
@@ -363,6 +368,37 @@ IKE identity to use for authentication round. When using certificate
authentication, the IKE identity must be contained in the certificate, either as
subject or as subjectAltName.
+The identity can be an IP address, a fully\-qualified domain name, an email
+address or a Distinguished Name for which the ID type is determined
+automatically and the string is converted to the appropriate encoding. To
+enforce a specific identity type, a prefix may be used, followed by a colon (:).
+If the number sign (#) follows the colon, the remaining data is interpreted as
+hex encoding, otherwise the string is used as\-is as the identification data.
+Note that this implies that no conversion is performed for non\-string
+identities. For example,
+.RI "" "ipv4:10.0.0.1" ""
+does not create a valid ID_IPV4_ADDR
+IKE identity, as it does not get converted to binary 0x0a000001. Instead, one
+could use
+.RI "" "ipv4:#0a000001" ""
+to get a valid identity, but just using the implicit
+type with automatic conversion is usually simpler. The same applies to the ASN1
+encoded types. The following prefixes are known:
+.RI "" "ipv4" ","
+.RI "" "ipv6" ","
+.RI "" "rfc822" ","
+.RI "" "email" ","
+.RI "" "userfqdn" ","
+.RI "" "fqdn" ","
+.RI "" "dns" ","
+.RI "" "asn1dn" ","
+.RI "" "asn1gn" ""
+and
+.RI "" "keyid" "."
+Custom type
+prefixes may be specified by surrounding the numerical type value by curly
+brackets.
+
.TP
.BR connections.<conn>.local<suffix>.eap_id " [id]"
Client EAP\-Identity to use in EAP\-Identity exchange and the EAP method.
@@ -397,9 +433,10 @@ omitted.
.TP
.BR connections.<conn>.remote<suffix>.id " [%any]"
-IKE identity to expect for authentication round. When using certificate
-authentication, the IKE identity must be contained in the certificate, either as
-subject or as subjectAltName.
+IKE identity to expect for authentication round. Refer to the
+.RI "" "local" ""
+.RI "" "id" ""
+section for details.
.TP
.BR connections.<conn>.remote<suffix>.groups " []"
@@ -725,9 +762,11 @@ uses dynamic reqids, allocated incrementally.
.TP
.BR connections.<conn>.children.<child>.mark_in " [0/0x00000000]"
-Netfilter mark and mask for input traffic. On Linux Netfilter may apply marks to
-each packet coming from a tunnel having that option set. The mark may then be
-used by Netfilter to match rules.
+Netfilter mark and mask for input traffic. On Linux Netfilter may require marks
+on each packet to match an SA having that option set. This allows Netfilter
+rules to select specific tunnels for incoming traffic. The special value
+.RI "" "%unique" ""
+sets a unique mark on each CHILD_SA instance.
An additional mask may be appended to the mark, separated by _/_. The default
mask if omitted is 0xffffffff.
@@ -736,7 +775,9 @@ mask if omitted is 0xffffffff.
.BR connections.<conn>.children.<child>.mark_out " [0/0x00000000]"
Netfilter mark and mask for output traffic. On Linux Netfilter may require marks
on each packet to match a policy having that option set. This allows Netfilter
-rules to select specific tunnels for outgoing traffic.
+rules to select specific tunnels for outgoing traffic. The special value
+.RI "" "%unique" ""
+sets a unique mark on each CHILD_SA instance.
An additional mask may be appended to the mark, separated by _/_. The default
mask if omitted is 0xffffffff.
@@ -925,6 +966,23 @@ folder for which this passphrase should be used.
Value of decryption passphrase for PKCS#8 key.
.TP
+.B secrets.pkcs12<suffix>
+.br
+PKCS#12 decryption passphrase for a container in the
+.RI "" "pkcs12" ""
+folder.
+
+.TP
+.BR secrets.pkcs12<suffix>.file " []"
+File name in the
+.RI "" "pkcs12" ""
+folder for which this passphrase should be used.
+
+.TP
+.BR secrets.pkcs12<suffix>.secret " []"
+Value of decryption passphrase for PKCS#12 container.
+
+.TP
.B pools
.br
Section defining named pools. Named pools may be referenced by connections with
@@ -939,9 +997,9 @@ Section defining a single pool with a unique name.
.TP
.BR pools.<name>.addrs " []"
-Subnet defining addresses allocated in pool. Accepts a single CIDR subnet
-defining the pool to allocate addresses from. Pools must be unique and
-non\-overlapping.
+Subnet or range defining addresses allocated in pool. Accepts a single CIDR
+subnet defining the pool to allocate addresses from, or an address range
+(<from>\-<to>). Pools must be unique and non\-overlapping.
.TP
.BR pools.<name>.<attr> " []"
diff --git a/src/swanctl/swanctl.h b/src/swanctl/swanctl.h
index bd7e00378..cb570cd34 100644
--- a/src/swanctl/swanctl.h
+++ b/src/swanctl/swanctl.h
@@ -66,4 +66,9 @@
*/
#define SWANCTL_PKCS8DIR SWANCTLDIR "/pkcs8"
+/**
+ * Directory for PKCS#12 containers
+ */
+#define SWANCTL_PKCS12DIR SWANCTLDIR "/pkcs12"
+
#endif /** SWANCTL_H_ @}*/
diff --git a/src/swanctl/swanctl.opt b/src/swanctl/swanctl.opt
index f1e47a9e4..b6ef17546 100644
--- a/src/swanctl/swanctl.opt
+++ b/src/swanctl/swanctl.opt
@@ -220,7 +220,9 @@ connections.<conn>.rekey_time = 4h
IKEv1 performs a reauthentication procedure instead.
With the default value IKE rekeying is scheduled every 4 hours, minus the
- configured **rand_time**.
+ configured **rand_time**. If a **reauth_time** is configured, **rekey_time**
+ defaults to zero disabling rekeying; explicitly set both to enforce
+ rekeying and reauthentication.
connections.<conn>.over_time = 10% of rekey_time/reauth_time
Hard IKE_SA lifetime if rekey/reauth does not complete, as time.
@@ -303,6 +305,22 @@ connections.<conn>.local<suffix>.id =
authentication, the IKE identity must be contained in the certificate,
either as subject or as subjectAltName.
+ The identity can be an IP address, a fully-qualified domain name, an email
+ address or a Distinguished Name for which the ID type is determined
+ automatically and the string is converted to the appropriate encoding. To
+ enforce a specific identity type, a prefix may be used, followed by a colon
+ (:). If the number sign (#) follows the colon, the remaining data is
+ interpreted as hex encoding, otherwise the string is used as-is as the
+ identification data. Note that this implies that no conversion is performed
+ for non-string identities. For example, _ipv4:10.0.0.1_ does not create a
+ valid ID_IPV4_ADDR IKE identity, as it does not get converted to binary
+ 0x0a000001. Instead, one could use _ipv4:#0a000001_ to get a valid identity,
+ but just using the implicit type with automatic conversion is usually
+ simpler. The same applies to the ASN1 encoded types. The following prefixes
+ are known: _ipv4_, _ipv6_, _rfc822_, _email_, _userfqdn_, _fqdn_, _dns_,
+ _asn1dn_, _asn1gn_ and _keyid_. Custom type prefixes may be specified by
+ surrounding the numerical type value by curly brackets.
+
connections.<conn>.local<suffix>.eap_id = id
Client EAP-Identity to use in EAP-Identity exchange and the EAP method.
@@ -335,9 +353,8 @@ connections.<conn>.remote<suffix> {}
connections.<conn>.remote<suffix>.id = %any
IKE identity to expect for authentication round.
- IKE identity to expect for authentication round. When using certificate
- authentication, the IKE identity must be contained in the certificate,
- either as subject or as subjectAltName.
+ IKE identity to expect for authentication round. Refer to the _local_ _id_
+ section for details.
connections.<conn>.remote<suffix>.groups =
Authorization group memberships to require.
@@ -607,9 +624,10 @@ connections.<conn>.children.<child>.reqid = 0
connections.<conn>.children.<child>.mark_in = 0/0x00000000
Netfilter mark and mask for input traffic.
- Netfilter mark and mask for input traffic. On Linux Netfilter may apply
- marks to each packet coming from a tunnel having that option set. The
- mark may then be used by Netfilter to match rules.
+ Netfilter mark and mask for input traffic. On Linux Netfilter may require
+ marks on each packet to match an SA having that option set. This allows
+ Netfilter rules to select specific tunnels for incoming traffic. The
+ special value _%unique_ sets a unique mark on each CHILD_SA instance.
An additional mask may be appended to the mark, separated by _/_. The
default mask if omitted is 0xffffffff.
@@ -619,7 +637,8 @@ connections.<conn>.children.<child>.mark_out = 0/0x00000000
Netfilter mark and mask for output traffic. On Linux Netfilter may require
marks on each packet to match a policy having that option set. This allows
- Netfilter rules to select specific tunnels for outgoing traffic.
+ Netfilter rules to select specific tunnels for outgoing traffic. The
+ special value _%unique_ sets a unique mark on each CHILD_SA instance.
An additional mask may be appended to the mark, separated by _/_. The
default mask if omitted is 0xffffffff.
@@ -756,6 +775,15 @@ secrets.pkcs8<suffix>.file =
secrets.pkcs8<suffix>.secret
Value of decryption passphrase for PKCS#8 key.
+secrets.pkcs12<suffix> { # }
+ PKCS#12 decryption passphrase for a container in the _pkcs12_ folder.
+
+secrets.pkcs12<suffix>.file =
+ File name in the _pkcs12_ folder for which this passphrase should be used.
+
+secrets.pkcs12<suffix>.secret
+ Value of decryption passphrase for PKCS#12 container.
+
pools { # }
Section defining named pools.
@@ -767,11 +795,11 @@ pools.<name> { # }
Section defining a single pool with a unique name.
pools.<name>.addrs =
- Subnet defining addresses allocated in pool.
+ Addresses allocated in pool.
- Subnet defining addresses allocated in pool. Accepts a single CIDR subnet
- defining the pool to allocate addresses from. Pools must be unique and
- non-overlapping.
+ Subnet or range defining addresses allocated in pool. Accepts a single CIDR
+ subnet defining the pool to allocate addresses from, or an address range
+ (<from>-<to>). Pools must be unique and non-overlapping.
pools.<name>.<attr> =
Comma separated list of additional attributes from type <attr>.