summaryrefslogtreecommitdiff
path: root/src/libcharon
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2010-11-28 12:11:49 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2010-11-28 12:11:49 +0000
commit7b8b352039efd78338a7bf451a0550644ec8a8da (patch)
tree62e0548df49dfb3ddacc8cac4309fa10f7b42610 /src/libcharon
parent9587b8e553eda7b1b6fd48c77ebe4592e1e3532a (diff)
downloadvyos-strongswan-7b8b352039efd78338a7bf451a0550644ec8a8da.tar.gz
vyos-strongswan-7b8b352039efd78338a7bf451a0550644ec8a8da.zip
New upstream version.
Diffstat (limited to 'src/libcharon')
-rw-r--r--src/libcharon/Android.mk16
-rw-r--r--src/libcharon/Makefile.am151
-rw-r--r--src/libcharon/Makefile.in484
-rw-r--r--src/libcharon/bus/bus.c3
-rw-r--r--src/libcharon/bus/listeners/file_logger.c35
-rw-r--r--src/libcharon/bus/listeners/file_logger.h3
-rw-r--r--src/libcharon/bus/listeners/sys_logger.c28
-rw-r--r--src/libcharon/bus/listeners/sys_logger.h3
-rw-r--r--src/libcharon/config/child_cfg.c9
-rw-r--r--src/libcharon/config/child_cfg.h53
-rw-r--r--src/libcharon/config/proposal.c205
-rw-r--r--src/libcharon/config/proposal.h10
-rw-r--r--src/libcharon/daemon.c44
-rw-r--r--src/libcharon/daemon.h32
-rw-r--r--src/libcharon/encoding/generator.c80
-rw-r--r--src/libcharon/encoding/generator.h26
-rw-r--r--src/libcharon/encoding/message.c973
-rw-r--r--src/libcharon/encoding/message.h48
-rw-r--r--src/libcharon/encoding/payloads/delete_payload.c213
-rw-r--r--src/libcharon/encoding/payloads/delete_payload.h9
-rw-r--r--src/libcharon/encoding/payloads/encryption_payload.c610
-rw-r--r--src/libcharon/encoding/payloads/encryption_payload.h118
-rw-r--r--src/libcharon/encoding/payloads/notify_payload.c56
-rw-r--r--src/libcharon/encoding/payloads/notify_payload.h24
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.c321
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.h33
-rw-r--r--src/libcharon/encoding/payloads/sa_payload.c277
-rw-r--r--src/libcharon/encoding/payloads/sa_payload.h22
-rw-r--r--src/libcharon/kernel/kernel_handler.c163
-rw-r--r--src/libcharon/kernel/kernel_handler.h50
-rw-r--r--src/libcharon/kernel/kernel_interface.c388
-rw-r--r--src/libcharon/kernel/kernel_interface.h408
-rw-r--r--src/libcharon/kernel/kernel_ipsec.h292
-rw-r--r--src/libcharon/kernel/kernel_net.h143
-rw-r--r--src/libcharon/network/receiver.c29
-rw-r--r--src/libcharon/network/sender.c2
-rw-r--r--src/libcharon/network/socket.h21
-rw-r--r--src/libcharon/network/socket_manager.c63
-rw-r--r--src/libcharon/network/socket_manager.h14
-rw-r--r--src/libcharon/plugins/addrblock/Makefile.in20
-rw-r--r--src/libcharon/plugins/addrblock/addrblock_plugin.c6
-rw-r--r--src/libcharon/plugins/android/Makefile.in20
-rw-r--r--src/libcharon/plugins/android/android_plugin.c6
-rw-r--r--src/libcharon/plugins/android/android_service.c4
-rw-r--r--src/libcharon/plugins/dhcp/Makefile.in20
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_plugin.c6
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_socket.c25
-rw-r--r--src/libcharon/plugins/eap_aka/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_gtc/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_identity/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_identity/eap_identity.c115
-rw-r--r--src/libcharon/plugins/eap_identity/eap_identity.h2
-rw-r--r--src/libcharon/plugins/eap_identity/eap_identity_plugin.c15
-rw-r--r--src/libcharon/plugins/eap_md5/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_md5/eap_md5.c120
-rw-r--r--src/libcharon/plugins/eap_md5/eap_md5.h2
-rw-r--r--src/libcharon/plugins/eap_md5/eap_md5_plugin.c15
-rw-r--r--src/libcharon/plugins/eap_mschapv2/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c10
-rw-r--r--src/libcharon/plugins/eap_radius/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius.c91
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius.h2
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_plugin.c6
-rw-r--r--src/libcharon/plugins/eap_radius/radius_server.h1
-rw-r--r--src/libcharon/plugins/eap_sim/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_sim_file/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/Makefile.in20
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c6
-rw-r--r--src/libcharon/plugins/eap_tls/Makefile.am17
-rw-r--r--src/libcharon/plugins/eap_tls/Makefile.in605
-rw-r--r--src/libcharon/plugins/eap_tls/eap_tls.c155
-rw-r--r--src/libcharon/plugins/eap_tls/eap_tls.h59
-rw-r--r--src/libcharon/plugins/eap_tls/eap_tls_plugin.c52
-rw-r--r--src/libcharon/plugins/eap_tls/eap_tls_plugin.h (renamed from src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.h)27
-rw-r--r--src/libcharon/plugins/eap_tnc/Makefile.am17
-rw-r--r--src/libcharon/plugins/eap_tnc/Makefile.in605
-rw-r--r--src/libcharon/plugins/eap_tnc/eap_tnc.c156
-rw-r--r--src/libcharon/plugins/eap_tnc/eap_tnc.h57
-rw-r--r--src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c51
-rw-r--r--src/libcharon/plugins/eap_tnc/eap_tnc_plugin.h (renamed from src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.h)20
-rw-r--r--src/libcharon/plugins/eap_ttls/Makefile.am21
-rw-r--r--src/libcharon/plugins/eap_ttls/Makefile.in615
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls.c165
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls.h59
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_avp.c187
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_avp.h68
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_peer.c316
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_peer.h47
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c52
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_plugin.h47
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_server.c365
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_server.h47
-rw-r--r--src/libcharon/plugins/farp/Makefile.in20
-rw-r--r--src/libcharon/plugins/farp/farp_plugin.c6
-rw-r--r--src/libcharon/plugins/farp/farp_spoofer.c2
-rw-r--r--src/libcharon/plugins/ha/Makefile.in20
-rw-r--r--src/libcharon/plugins/ha/ha_cache.c2
-rw-r--r--src/libcharon/plugins/ha/ha_ctl.c12
-rw-r--r--src/libcharon/plugins/ha/ha_dispatcher.c6
-rw-r--r--src/libcharon/plugins/ha/ha_kernel.c5
-rw-r--r--src/libcharon/plugins/ha/ha_plugin.c6
-rw-r--r--src/libcharon/plugins/ha/ha_segments.c8
-rw-r--r--src/libcharon/plugins/ha/ha_socket.c2
-rw-r--r--src/libcharon/plugins/kernel_klips/Makefile.am17
-rw-r--r--src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c2660
-rw-r--r--src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.h46
-rw-r--r--src/libcharon/plugins/kernel_klips/kernel_klips_plugin.c56
-rw-r--r--src/libcharon/plugins/kernel_klips/pfkeyv2.h322
-rw-r--r--src/libcharon/plugins/kernel_netlink/Makefile.am20
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c2265
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h46
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c1506
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h46
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c59
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c306
-rw-r--r--src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h77
-rw-r--r--src/libcharon/plugins/kernel_pfkey/Makefile.am17
-rw-r--r--src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c2210
-rw-r--r--src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h46
-rw-r--r--src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c56
-rw-r--r--src/libcharon/plugins/kernel_pfroute/Makefile.am17
-rw-r--r--src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c729
-rw-r--r--src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h46
-rw-r--r--src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c58
-rw-r--r--src/libcharon/plugins/led/Makefile.am16
-rw-r--r--src/libcharon/plugins/led/Makefile.in (renamed from src/libcharon/plugins/kernel_klips/Makefile.in)69
-rw-r--r--src/libcharon/plugins/led/led_listener.c241
-rw-r--r--src/libcharon/plugins/led/led_listener.h49
-rw-r--r--src/libcharon/plugins/led/led_plugin.c67
-rw-r--r--src/libcharon/plugins/led/led_plugin.h (renamed from src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.h)22
-rw-r--r--src/libcharon/plugins/load_tester/Makefile.in20
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_ipsec.c15
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_listener.c2
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_plugin.c7
-rw-r--r--src/libcharon/plugins/maemo/Makefile.am23
-rw-r--r--src/libcharon/plugins/maemo/Makefile.in631
-rw-r--r--src/libcharon/plugins/maemo/maemo_plugin.c70
-rw-r--r--src/libcharon/plugins/maemo/maemo_plugin.h (renamed from src/libcharon/plugins/kernel_klips/kernel_klips_plugin.h)20
-rw-r--r--src/libcharon/plugins/maemo/maemo_service.c510
-rw-r--r--src/libcharon/plugins/maemo/maemo_service.h49
-rw-r--r--src/libcharon/plugins/maemo/org.strongswan.charon.service4
-rw-r--r--src/libcharon/plugins/medcli/Makefile.in20
-rw-r--r--src/libcharon/plugins/medcli/medcli_config.c30
-rw-r--r--src/libcharon/plugins/medsrv/Makefile.in20
-rw-r--r--src/libcharon/plugins/nm/Makefile.in20
-rw-r--r--src/libcharon/plugins/nm/nm_creds.c97
-rw-r--r--src/libcharon/plugins/nm/nm_creds.h17
-rw-r--r--src/libcharon/plugins/nm/nm_plugin.c2
-rw-r--r--src/libcharon/plugins/nm/nm_service.c108
-rw-r--r--src/libcharon/plugins/smp/Makefile.in20
-rw-r--r--src/libcharon/plugins/smp/smp.c4
-rw-r--r--src/libcharon/plugins/socket_default/Makefile.in20
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_plugin.c25
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_socket.c35
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_socket.h4
-rw-r--r--src/libcharon/plugins/socket_dynamic/Makefile.in20
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c25
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c35
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.h4
-rw-r--r--src/libcharon/plugins/socket_raw/Makefile.in20
-rw-r--r--src/libcharon/plugins/socket_raw/socket_raw_plugin.c25
-rw-r--r--src/libcharon/plugins/socket_raw/socket_raw_socket.c42
-rw-r--r--src/libcharon/plugins/socket_raw/socket_raw_socket.h4
-rw-r--r--src/libcharon/plugins/sql/Makefile.am3
-rw-r--r--src/libcharon/plugins/sql/Makefile.in23
-rw-r--r--src/libcharon/plugins/stroke/Makefile.in20
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c25
-rw-r--r--src/libcharon/plugins/stroke/stroke_control.c2
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.c715
-rw-r--r--src/libcharon/plugins/stroke/stroke_list.c41
-rw-r--r--src/libcharon/plugins/stroke/stroke_socket.c59
-rw-r--r--src/libcharon/plugins/tnc_imc/Makefile.am19
-rw-r--r--src/libcharon/plugins/tnc_imc/Makefile.in (renamed from src/libcharon/plugins/kernel_pfroute/Makefile.in)73
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c57
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_plugin.h42
-rw-r--r--src/libcharon/plugins/tnc_imv/Makefile.am19
-rw-r--r--src/libcharon/plugins/tnc_imv/Makefile.in (renamed from src/libcharon/plugins/kernel_pfkey/Makefile.in)73
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c54
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_plugin.h42
-rw-r--r--src/libcharon/plugins/tnccs_11/Makefile.am21
-rw-r--r--src/libcharon/plugins/tnccs_11/Makefile.in (renamed from src/libcharon/plugins/kernel_netlink/Makefile.in)88
-rw-r--r--src/libcharon/plugins/tnccs_11/tnccs_11.c328
-rw-r--r--src/libcharon/plugins/tnccs_11/tnccs_11.h36
-rw-r--r--src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c47
-rw-r--r--src/libcharon/plugins/tnccs_11/tnccs_11_plugin.h42
-rw-r--r--src/libcharon/plugins/tnccs_20/Makefile.am21
-rw-r--r--src/libcharon/plugins/tnccs_20/Makefile.in607
-rw-r--r--src/libcharon/plugins/tnccs_20/tnccs_20.c103
-rw-r--r--src/libcharon/plugins/tnccs_20/tnccs_20.h36
-rw-r--r--src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c47
-rw-r--r--src/libcharon/plugins/tnccs_20/tnccs_20_plugin.h42
-rw-r--r--src/libcharon/plugins/uci/Makefile.in20
-rw-r--r--src/libcharon/plugins/uci/uci_control.c2
-rw-r--r--src/libcharon/plugins/unit_tester/Makefile.in20
-rw-r--r--src/libcharon/plugins/unit_tester/tests/test_cert.c4
-rw-r--r--src/libcharon/plugins/unit_tester/tests/test_rsa_gen.c6
-rw-r--r--src/libcharon/plugins/updown/Makefile.in20
-rw-r--r--src/libcharon/plugins/updown/updown_listener.c5
-rw-r--r--src/libcharon/processing/jobs/acquire_job.h2
-rw-r--r--src/libcharon/processing/jobs/callback_job.c271
-rw-r--r--src/libcharon/processing/jobs/callback_job.h118
-rw-r--r--src/libcharon/processing/jobs/delete_child_sa_job.h2
-rw-r--r--src/libcharon/processing/jobs/delete_ike_sa_job.h2
-rw-r--r--src/libcharon/processing/jobs/inactivity_job.c10
-rw-r--r--src/libcharon/processing/jobs/inactivity_job.h2
-rw-r--r--src/libcharon/processing/jobs/initiate_mediation_job.h2
-rw-r--r--src/libcharon/processing/jobs/job.h52
-rw-r--r--src/libcharon/processing/jobs/mediation_job.h2
-rw-r--r--src/libcharon/processing/jobs/migrate_job.h2
-rw-r--r--src/libcharon/processing/jobs/process_message_job.h2
-rw-r--r--src/libcharon/processing/jobs/rekey_child_sa_job.h2
-rw-r--r--src/libcharon/processing/jobs/rekey_ike_sa_job.h2
-rw-r--r--src/libcharon/processing/jobs/retransmit_job.h2
-rw-r--r--src/libcharon/processing/jobs/roam_job.h2
-rw-r--r--src/libcharon/processing/jobs/send_dpd_job.h2
-rw-r--r--src/libcharon/processing/jobs/send_keepalive_job.h2
-rw-r--r--src/libcharon/processing/jobs/update_sa_job.h2
-rw-r--r--src/libcharon/processing/processor.c273
-rw-r--r--src/libcharon/processing/processor.h94
-rw-r--r--src/libcharon/processing/scheduler.c358
-rw-r--r--src/libcharon/processing/scheduler.h130
-rw-r--r--src/libcharon/sa/authenticators/eap/eap_manager.c54
-rw-r--r--src/libcharon/sa/authenticators/eap/eap_method.c47
-rw-r--r--src/libcharon/sa/authenticators/eap/eap_method.h30
-rw-r--r--src/libcharon/sa/authenticators/eap_authenticator.c122
-rw-r--r--src/libcharon/sa/authenticators/pubkey_authenticator.c6
-rw-r--r--src/libcharon/sa/child_sa.c532
-rw-r--r--src/libcharon/sa/connect_manager.c14
-rw-r--r--src/libcharon/sa/ike_sa.c237
-rw-r--r--src/libcharon/sa/ike_sa.h8
-rw-r--r--src/libcharon/sa/ike_sa_manager.c5
-rw-r--r--src/libcharon/sa/ike_sa_manager.h2
-rw-r--r--src/libcharon/sa/keymat.c348
-rw-r--r--src/libcharon/sa/keymat.h15
-rw-r--r--src/libcharon/sa/mediation_manager.c2
-rw-r--r--src/libcharon/sa/task_manager.c21
-rw-r--r--src/libcharon/sa/tasks/child_create.c4
-rw-r--r--src/libcharon/sa/tasks/child_delete.c17
-rw-r--r--src/libcharon/sa/tasks/child_rekey.c31
-rw-r--r--src/libcharon/sa/tasks/ike_auth.c12
-rw-r--r--src/libcharon/sa/tasks/ike_init.c2
-rw-r--r--src/libcharon/sa/tasks/ike_me.c10
-rw-r--r--src/libcharon/sa/tasks/ike_mobike.c215
-rw-r--r--src/libcharon/sa/tasks/ike_mobike.h5
-rw-r--r--src/libcharon/sa/tasks/ike_natd.c41
-rw-r--r--src/libcharon/sa/tasks/ike_rekey.c83
-rw-r--r--src/libcharon/sa/tasks/ike_vendor.c14
-rw-r--r--src/libcharon/sa/trap_manager.c5
-rw-r--r--src/libcharon/tnccs/tnccs.c (renamed from src/libcharon/kernel/kernel_ipsec.c)21
-rw-r--r--src/libcharon/tnccs/tnccs.h52
-rw-r--r--src/libcharon/tnccs/tnccs_manager.c148
-rw-r--r--src/libcharon/tnccs/tnccs_manager.h74
255 files changed, 12049 insertions, 17333 deletions
diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk
index 3297654e9..21a2b8ee6 100644
--- a/src/libcharon/Android.mk
+++ b/src/libcharon/Android.mk
@@ -40,16 +40,12 @@ encoding/payloads/transform_substructure.c encoding/payloads/transform_substruct
encoding/payloads/ts_payload.c encoding/payloads/ts_payload.h \
encoding/payloads/unknown_payload.c encoding/payloads/unknown_payload.h \
encoding/payloads/vendor_id_payload.c encoding/payloads/vendor_id_payload.h \
-kernel/kernel_interface.c kernel/kernel_interface.h \
-kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
-kernel/kernel_net.h \
+kernel/kernel_handler.c kernel/kernel_handler.h \
network/packet.c network/packet.h \
network/receiver.c network/receiver.h \
network/sender.c network/sender.h \
network/socket_manager.c network/socket_manager.h network/socket.h \
-processing/jobs/job.h \
processing/jobs/acquire_job.c processing/jobs/acquire_job.h \
-processing/jobs/callback_job.c processing/jobs/callback_job.h \
processing/jobs/delete_child_sa_job.c processing/jobs/delete_child_sa_job.h \
processing/jobs/delete_ike_sa_job.c processing/jobs/delete_ike_sa_job.h \
processing/jobs/migrate_job.c processing/jobs/migrate_job.h \
@@ -62,8 +58,6 @@ processing/jobs/send_keepalive_job.c processing/jobs/send_keepalive_job.h \
processing/jobs/roam_job.c processing/jobs/roam_job.h \
processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \
processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \
-processing/scheduler.c processing/scheduler.h \
-processing/processor.c processing/processor.h \
sa/authenticators/authenticator.c sa/authenticators/authenticator.h \
sa/authenticators/eap_authenticator.c sa/authenticators/eap_authenticator.h \
sa/authenticators/eap/eap_method.c sa/authenticators/eap/eap_method.h \
@@ -94,7 +88,9 @@ sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \
sa/tasks/ike_reauth.c sa/tasks/ike_reauth.h \
sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \
sa/tasks/ike_vendor.c sa/tasks/ike_vendor.h \
-sa/tasks/task.c sa/tasks/task.h
+sa/tasks/task.c sa/tasks/task.h \
+tnccs/tnccs.c tnccs/tnccs.h \
+tnccs/tnccs_manager.h tnccs/tnccs_manager.c
# adding the plugin source files
@@ -141,10 +137,6 @@ LOCAL_SRC_FILES += $(addprefix ../libsimaka/, \
)
endif
-LOCAL_SRC_FILES += $(call add_plugin, kernel-netlink)
-
-LOCAL_SRC_FILES += $(call add_plugin, kernel-pfkey)
-
LOCAL_SRC_FILES += $(call add_plugin, load-tester)
LOCAL_SRC_FILES += $(call add_plugin, socket-default)
diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am
index 44501c0d0..2b7646327 100644
--- a/src/libcharon/Makefile.am
+++ b/src/libcharon/Makefile.am
@@ -38,16 +38,12 @@ encoding/payloads/transform_substructure.c encoding/payloads/transform_substruct
encoding/payloads/ts_payload.c encoding/payloads/ts_payload.h \
encoding/payloads/unknown_payload.c encoding/payloads/unknown_payload.h \
encoding/payloads/vendor_id_payload.c encoding/payloads/vendor_id_payload.h \
-kernel/kernel_interface.c kernel/kernel_interface.h \
-kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
-kernel/kernel_net.h \
+kernel/kernel_handler.c kernel/kernel_handler.h \
network/packet.c network/packet.h \
network/receiver.c network/receiver.h \
network/sender.c network/sender.h \
network/socket_manager.c network/socket_manager.h network/socket.h \
-processing/jobs/job.h \
processing/jobs/acquire_job.c processing/jobs/acquire_job.h \
-processing/jobs/callback_job.c processing/jobs/callback_job.h \
processing/jobs/delete_child_sa_job.c processing/jobs/delete_child_sa_job.h \
processing/jobs/delete_ike_sa_job.c processing/jobs/delete_ike_sa_job.h \
processing/jobs/migrate_job.c processing/jobs/migrate_job.h \
@@ -60,8 +56,6 @@ processing/jobs/send_keepalive_job.c processing/jobs/send_keepalive_job.h \
processing/jobs/roam_job.c processing/jobs/roam_job.h \
processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \
processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \
-processing/scheduler.c processing/scheduler.h \
-processing/processor.c processing/processor.h \
sa/authenticators/authenticator.c sa/authenticators/authenticator.h \
sa/authenticators/eap_authenticator.c sa/authenticators/eap_authenticator.h \
sa/authenticators/eap/eap_method.c sa/authenticators/eap/eap_method.h \
@@ -92,7 +86,9 @@ sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \
sa/tasks/ike_reauth.c sa/tasks/ike_reauth.h \
sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \
sa/tasks/ike_vendor.c sa/tasks/ike_vendor.h \
-sa/tasks/task.c sa/tasks/task.h
+sa/tasks/task.c sa/tasks/task.h \
+tnccs/tnccs.c tnccs/tnccs.h \
+tnccs/tnccs_manager.h tnccs/tnccs_manager.c
daemon.lo : $(top_builddir)/config.status
@@ -104,7 +100,8 @@ INCLUDES = \
AM_CFLAGS = \
-DIPSEC_DIR=\"${ipsecdir}\" \
- -DIPSEC_PIDDIR=\"${piddir}\"
+ -DIPSEC_PIDDIR=\"${piddir}\" \
+ -DPLUGINS=\""${libcharon_plugins}\""
libcharon_la_LIBADD = -lm $(PTHREADLIB) $(DLLIB) $(SOCKLIB)
@@ -135,51 +132,15 @@ else
SUBDIRS = .
endif
-PLUGINS = ${libstrongswan_plugins} ${libhydra_plugins}
-
if USE_LOAD_TESTER
SUBDIRS += plugins/load_tester
- PLUGINS += load-tester
if MONOLITHIC
libcharon_la_LIBADD += plugins/load_tester/libstrongswan-load-tester.la
endif
endif
-if USE_KERNEL_PFKEY
- SUBDIRS += plugins/kernel_pfkey
- PLUGINS += kernel-pfkey
-if MONOLITHIC
- libcharon_la_LIBADD += plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la
-endif
-endif
-
-if USE_KERNEL_PFROUTE
- SUBDIRS += plugins/kernel_pfroute
- PLUGINS += kernel-pfroute
-if MONOLITHIC
- libcharon_la_LIBADD += plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la
-endif
-endif
-
-if USE_KERNEL_KLIPS
- SUBDIRS += plugins/kernel_klips
- PLUGINS += kernel-klips
-if MONOLITHIC
- libcharon_la_LIBADD += plugins/kernel_klips/libstrongswan-kernel-klips.la
-endif
-endif
-
-if USE_KERNEL_NETLINK
- SUBDIRS += plugins/kernel_netlink
- PLUGINS += kernel-netlink
-if MONOLITHIC
- libcharon_la_LIBADD += plugins/kernel_netlink/libstrongswan-kernel-netlink.la
-endif
-endif
-
if USE_SOCKET_DEFAULT
SUBDIRS += plugins/socket_default
- PLUGINS += socket-default
if MONOLITHIC
libcharon_la_LIBADD += plugins/socket_default/libstrongswan-socket-default.la
endif
@@ -187,7 +148,6 @@ endif
if USE_SOCKET_RAW
SUBDIRS += plugins/socket_raw
- PLUGINS += socket-raw
if MONOLITHIC
libcharon_la_LIBADD += plugins/socket_raw/libstrongswan-socket-raw.la
endif
@@ -195,7 +155,6 @@ endif
if USE_SOCKET_DYNAMIC
SUBDIRS += plugins/socket_dynamic
- PLUGINS += socket-dynamic
if MONOLITHIC
libcharon_la_LIBADD += plugins/socket_dynamic/libstrongswan-socket-dynamic.la
endif
@@ -203,7 +162,6 @@ endif
if USE_FARP
SUBDIRS += plugins/farp
- PLUGINS += farp
if MONOLITHIC
libcharon_la_LIBADD += plugins/farp/libstrongswan-farp.la
endif
@@ -211,7 +169,6 @@ endif
if USE_STROKE
SUBDIRS += plugins/stroke
- PLUGINS += stroke
if MONOLITHIC
libcharon_la_LIBADD += plugins/stroke/libstrongswan-stroke.la
endif
@@ -219,7 +176,6 @@ endif
if USE_SMP
SUBDIRS += plugins/smp
- PLUGINS += smp
if MONOLITHIC
libcharon_la_LIBADD += plugins/smp/libstrongswan-smp.la
endif
@@ -227,7 +183,6 @@ endif
if USE_SQL
SUBDIRS += plugins/sql
- PLUGINS += sql
if MONOLITHIC
libcharon_la_LIBADD += plugins/sql/libstrongswan-sql.la
endif
@@ -235,7 +190,6 @@ endif
if USE_UPDOWN
SUBDIRS += plugins/updown
- PLUGINS += updown
if MONOLITHIC
libcharon_la_LIBADD += plugins/updown/libstrongswan-updown.la
endif
@@ -243,7 +197,6 @@ endif
if USE_EAP_IDENTITY
SUBDIRS += plugins/eap_identity
- PLUGINS += eap-identity
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_identity/libstrongswan-eap-identity.la
endif
@@ -251,7 +204,6 @@ endif
if USE_EAP_SIM
SUBDIRS += plugins/eap_sim
- PLUGINS += eap-sim
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_sim/libstrongswan-eap-sim.la
endif
@@ -259,7 +211,6 @@ endif
if USE_EAP_SIM_FILE
SUBDIRS += plugins/eap_sim_file
- PLUGINS += eap-sim-file
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_sim_file/libstrongswan-eap-sim-file.la
endif
@@ -267,7 +218,6 @@ endif
if USE_EAP_SIMAKA_SQL
SUBDIRS += plugins/eap_simaka_sql
- PLUGINS += eap-simaka-sql
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la
endif
@@ -275,7 +225,6 @@ endif
if USE_EAP_SIMAKA_PSEUDONYM
SUBDIRS += plugins/eap_simaka_pseudonym
- PLUGINS += eap-simaka-pseudonym
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la
endif
@@ -283,7 +232,6 @@ endif
if USE_EAP_SIMAKA_REAUTH
SUBDIRS += plugins/eap_simaka_reauth
- PLUGINS += eap-simaka-reauth
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la
endif
@@ -291,7 +239,6 @@ endif
if USE_EAP_AKA
SUBDIRS += plugins/eap_aka
- PLUGINS += eap-aka
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_aka/libstrongswan-eap-aka.la
endif
@@ -299,7 +246,6 @@ endif
if USE_EAP_AKA_3GPP2
SUBDIRS += plugins/eap_aka_3gpp2
- PLUGINS += eap-aka-3gpp2
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la
endif
@@ -314,7 +260,6 @@ endif
if USE_EAP_MD5
SUBDIRS += plugins/eap_md5
- PLUGINS += eap-md5
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_md5/libstrongswan-eap-md5.la
endif
@@ -322,7 +267,6 @@ endif
if USE_EAP_GTC
SUBDIRS += plugins/eap_gtc
- PLUGINS += eap-gtc
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_gtc/libstrongswan-eap-gtc.la
endif
@@ -330,7 +274,6 @@ endif
if USE_EAP_MSCHAPV2
SUBDIRS += plugins/eap_mschapv2
- PLUGINS += eap-mschapv2
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la
endif
@@ -338,15 +281,69 @@ endif
if USE_EAP_RADIUS
SUBDIRS += plugins/eap_radius
- PLUGINS += eap-radius
if MONOLITHIC
libcharon_la_LIBADD += plugins/eap_radius/libstrongswan-eap-radius.la
endif
endif
+if USE_EAP_TLS
+ SUBDIRS += plugins/eap_tls
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/eap_tls/libstrongswan-eap-tls.la
+endif
+endif
+
+if USE_EAP_TTLS
+ SUBDIRS += plugins/eap_ttls
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/eap_ttls/libstrongswan-eap-ttls.la
+endif
+endif
+
+if USE_EAP_TNC
+ SUBDIRS += plugins/eap_tnc
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/eap_tnc/libstrongswan-eap-tnc.la
+endif
+endif
+
+if USE_TLS
+if MONOLITHIC
+ # otherwise this library is linked to eap_tls
+ libcharon_la_LIBADD += $(top_builddir)/src/libtls/libtls.la
+endif
+endif
+
+if USE_TNC_IMC
+ SUBDIRS += plugins/tnc_imc
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/tnc_imc/libstrongswan-tnc_imc.la
+endif
+endif
+
+if USE_TNC_IMV
+ SUBDIRS += plugins/tnc_imv
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/tnc_imv/libstrongswan-tnc_imv.la
+endif
+endif
+
+if USE_TNCCS_11
+ SUBDIRS += plugins/tnccs_11
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/tnccs_11/libstrongswan-tnccs-11.la
+endif
+endif
+
+if USE_TNCCS_20
+ SUBDIRS += plugins/tnccs_20
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/tnccs_20/libstrongswan-tnccs-20.la
+endif
+endif
+
if USE_MEDSRV
SUBDIRS += plugins/medsrv
- PLUGINS += medsrv
if MONOLITHIC
libcharon_la_LIBADD += plugins/medsrv/libstrongswan-medsrv.la
endif
@@ -354,7 +351,6 @@ endif
if USE_MEDCLI
SUBDIRS += plugins/medcli
- PLUGINS += medcli
if MONOLITHIC
libcharon_la_LIBADD += plugins/medcli/libstrongswan-medcli.la
endif
@@ -362,7 +358,6 @@ endif
if USE_NM
SUBDIRS += plugins/nm
- PLUGINS += nm
if MONOLITHIC
libcharon_la_LIBADD += plugins/nm/libstrongswan-nm.la
endif
@@ -370,7 +365,6 @@ endif
if USE_DHCP
SUBDIRS += plugins/dhcp
- PLUGINS += dhcp
if MONOLITHIC
libcharon_la_LIBADD += plugins/dhcp/libstrongswan-dhcp.la
endif
@@ -378,23 +372,34 @@ endif
if USE_ANDROID
SUBDIRS += plugins/android
- PLUGINS += android
if MONOLITHIC
libcharon_la_LIBADD += plugins/android/libstrongswan-android.la
endif
endif
+if USE_MAEMO
+ SUBDIRS += plugins/maemo
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/maemo/libstrongswan-maemo.la
+endif
+endif
+
if USE_HA
SUBDIRS += plugins/ha
- PLUGINS += ha
if MONOLITHIC
libcharon_la_LIBADD += plugins/ha/libstrongswan-ha.la
endif
endif
+if USE_LED
+ SUBDIRS += plugins/led
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/led/libstrongswan-led.la
+endif
+endif
+
if USE_UCI
SUBDIRS += plugins/uci
- PLUGINS += uci
if MONOLITHIC
libcharon_la_LIBADD += plugins/uci/libstrongswan-uci.la
endif
@@ -402,7 +407,6 @@ endif
if USE_ADDRBLOCK
SUBDIRS += plugins/addrblock
- PLUGINS += addrblock
if MONOLITHIC
libcharon_la_LIBADD += plugins/uci/libstrongswan-addrblock.la
endif
@@ -410,11 +414,8 @@ endif
if USE_UNIT_TESTS
SUBDIRS += plugins/unit_tester
- PLUGINS += unit-tester
if MONOLITHIC
libcharon_la_LIBADD += plugins/unit_tester/libstrongswan-unit-tester.la
endif
endif
-AM_CFLAGS += -DPLUGINS=\""${PLUGINS}\""
-
diff --git a/src/libcharon/Makefile.in b/src/libcharon/Makefile.in
index 8e58b0e2e..8a7a99ddd 100644
--- a/src/libcharon/Makefile.in
+++ b/src/libcharon/Makefile.in
@@ -46,108 +46,85 @@ host_triplet = @host@
@USE_LIBCAP_TRUE@am__append_2 = -lcap
@USE_LOAD_TESTER_TRUE@am__append_3 = plugins/load_tester
-@USE_LOAD_TESTER_TRUE@am__append_4 = load-tester
-@MONOLITHIC_TRUE@@USE_LOAD_TESTER_TRUE@am__append_5 = plugins/load_tester/libstrongswan-load-tester.la
-@USE_KERNEL_PFKEY_TRUE@am__append_6 = plugins/kernel_pfkey
-@USE_KERNEL_PFKEY_TRUE@am__append_7 = kernel-pfkey
-@MONOLITHIC_TRUE@@USE_KERNEL_PFKEY_TRUE@am__append_8 = plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la
-@USE_KERNEL_PFROUTE_TRUE@am__append_9 = plugins/kernel_pfroute
-@USE_KERNEL_PFROUTE_TRUE@am__append_10 = kernel-pfroute
-@MONOLITHIC_TRUE@@USE_KERNEL_PFROUTE_TRUE@am__append_11 = plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la
-@USE_KERNEL_KLIPS_TRUE@am__append_12 = plugins/kernel_klips
-@USE_KERNEL_KLIPS_TRUE@am__append_13 = kernel-klips
-@MONOLITHIC_TRUE@@USE_KERNEL_KLIPS_TRUE@am__append_14 = plugins/kernel_klips/libstrongswan-kernel-klips.la
-@USE_KERNEL_NETLINK_TRUE@am__append_15 = plugins/kernel_netlink
-@USE_KERNEL_NETLINK_TRUE@am__append_16 = kernel-netlink
-@MONOLITHIC_TRUE@@USE_KERNEL_NETLINK_TRUE@am__append_17 = plugins/kernel_netlink/libstrongswan-kernel-netlink.la
-@USE_SOCKET_DEFAULT_TRUE@am__append_18 = plugins/socket_default
-@USE_SOCKET_DEFAULT_TRUE@am__append_19 = socket-default
-@MONOLITHIC_TRUE@@USE_SOCKET_DEFAULT_TRUE@am__append_20 = plugins/socket_default/libstrongswan-socket-default.la
-@USE_SOCKET_RAW_TRUE@am__append_21 = plugins/socket_raw
-@USE_SOCKET_RAW_TRUE@am__append_22 = socket-raw
-@MONOLITHIC_TRUE@@USE_SOCKET_RAW_TRUE@am__append_23 = plugins/socket_raw/libstrongswan-socket-raw.la
-@USE_SOCKET_DYNAMIC_TRUE@am__append_24 = plugins/socket_dynamic
-@USE_SOCKET_DYNAMIC_TRUE@am__append_25 = socket-dynamic
-@MONOLITHIC_TRUE@@USE_SOCKET_DYNAMIC_TRUE@am__append_26 = plugins/socket_dynamic/libstrongswan-socket-dynamic.la
-@USE_FARP_TRUE@am__append_27 = plugins/farp
-@USE_FARP_TRUE@am__append_28 = farp
-@MONOLITHIC_TRUE@@USE_FARP_TRUE@am__append_29 = plugins/farp/libstrongswan-farp.la
-@USE_STROKE_TRUE@am__append_30 = plugins/stroke
-@USE_STROKE_TRUE@am__append_31 = stroke
-@MONOLITHIC_TRUE@@USE_STROKE_TRUE@am__append_32 = plugins/stroke/libstrongswan-stroke.la
-@USE_SMP_TRUE@am__append_33 = plugins/smp
-@USE_SMP_TRUE@am__append_34 = smp
-@MONOLITHIC_TRUE@@USE_SMP_TRUE@am__append_35 = plugins/smp/libstrongswan-smp.la
-@USE_SQL_TRUE@am__append_36 = plugins/sql
-@USE_SQL_TRUE@am__append_37 = sql
-@MONOLITHIC_TRUE@@USE_SQL_TRUE@am__append_38 = plugins/sql/libstrongswan-sql.la
-@USE_UPDOWN_TRUE@am__append_39 = plugins/updown
-@USE_UPDOWN_TRUE@am__append_40 = updown
-@MONOLITHIC_TRUE@@USE_UPDOWN_TRUE@am__append_41 = plugins/updown/libstrongswan-updown.la
-@USE_EAP_IDENTITY_TRUE@am__append_42 = plugins/eap_identity
-@USE_EAP_IDENTITY_TRUE@am__append_43 = eap-identity
-@MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE@am__append_44 = plugins/eap_identity/libstrongswan-eap-identity.la
-@USE_EAP_SIM_TRUE@am__append_45 = plugins/eap_sim
-@USE_EAP_SIM_TRUE@am__append_46 = eap-sim
-@MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE@am__append_47 = plugins/eap_sim/libstrongswan-eap-sim.la
-@USE_EAP_SIM_FILE_TRUE@am__append_48 = plugins/eap_sim_file
-@USE_EAP_SIM_FILE_TRUE@am__append_49 = eap-sim-file
-@MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE@am__append_50 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la
-@USE_EAP_SIMAKA_SQL_TRUE@am__append_51 = plugins/eap_simaka_sql
-@USE_EAP_SIMAKA_SQL_TRUE@am__append_52 = eap-simaka-sql
-@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE@am__append_53 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la
-@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_54 = plugins/eap_simaka_pseudonym
-@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_55 = eap-simaka-pseudonym
-@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_56 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la
-@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_57 = plugins/eap_simaka_reauth
-@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_58 = eap-simaka-reauth
-@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_59 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la
-@USE_EAP_AKA_TRUE@am__append_60 = plugins/eap_aka
-@USE_EAP_AKA_TRUE@am__append_61 = eap-aka
-@MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE@am__append_62 = plugins/eap_aka/libstrongswan-eap-aka.la
-@USE_EAP_AKA_3GPP2_TRUE@am__append_63 = plugins/eap_aka_3gpp2
-@USE_EAP_AKA_3GPP2_TRUE@am__append_64 = eap-aka-3gpp2
-@MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE@am__append_65 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la
-@MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@am__append_66 = $(top_builddir)/src/libsimaka/libsimaka.la
-@USE_EAP_MD5_TRUE@am__append_67 = plugins/eap_md5
-@USE_EAP_MD5_TRUE@am__append_68 = eap-md5
-@MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE@am__append_69 = plugins/eap_md5/libstrongswan-eap-md5.la
-@USE_EAP_GTC_TRUE@am__append_70 = plugins/eap_gtc
-@USE_EAP_GTC_TRUE@am__append_71 = eap-gtc
-@MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE@am__append_72 = plugins/eap_gtc/libstrongswan-eap-gtc.la
-@USE_EAP_MSCHAPV2_TRUE@am__append_73 = plugins/eap_mschapv2
-@USE_EAP_MSCHAPV2_TRUE@am__append_74 = eap-mschapv2
-@MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE@am__append_75 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la
-@USE_EAP_RADIUS_TRUE@am__append_76 = plugins/eap_radius
-@USE_EAP_RADIUS_TRUE@am__append_77 = eap-radius
-@MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE@am__append_78 = plugins/eap_radius/libstrongswan-eap-radius.la
-@USE_MEDSRV_TRUE@am__append_79 = plugins/medsrv
-@USE_MEDSRV_TRUE@am__append_80 = medsrv
-@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_81 = plugins/medsrv/libstrongswan-medsrv.la
-@USE_MEDCLI_TRUE@am__append_82 = plugins/medcli
-@USE_MEDCLI_TRUE@am__append_83 = medcli
-@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_84 = plugins/medcli/libstrongswan-medcli.la
-@USE_NM_TRUE@am__append_85 = plugins/nm
-@USE_NM_TRUE@am__append_86 = nm
-@MONOLITHIC_TRUE@@USE_NM_TRUE@am__append_87 = plugins/nm/libstrongswan-nm.la
-@USE_DHCP_TRUE@am__append_88 = plugins/dhcp
-@USE_DHCP_TRUE@am__append_89 = dhcp
-@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_90 = plugins/dhcp/libstrongswan-dhcp.la
-@USE_ANDROID_TRUE@am__append_91 = plugins/android
-@USE_ANDROID_TRUE@am__append_92 = android
-@MONOLITHIC_TRUE@@USE_ANDROID_TRUE@am__append_93 = plugins/android/libstrongswan-android.la
-@USE_HA_TRUE@am__append_94 = plugins/ha
-@USE_HA_TRUE@am__append_95 = ha
-@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_96 = plugins/ha/libstrongswan-ha.la
-@USE_UCI_TRUE@am__append_97 = plugins/uci
-@USE_UCI_TRUE@am__append_98 = uci
-@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_99 = plugins/uci/libstrongswan-uci.la
-@USE_ADDRBLOCK_TRUE@am__append_100 = plugins/addrblock
-@USE_ADDRBLOCK_TRUE@am__append_101 = addrblock
-@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_102 = plugins/uci/libstrongswan-addrblock.la
-@USE_UNIT_TESTS_TRUE@am__append_103 = plugins/unit_tester
-@USE_UNIT_TESTS_TRUE@am__append_104 = unit-tester
-@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_105 = plugins/unit_tester/libstrongswan-unit-tester.la
+@MONOLITHIC_TRUE@@USE_LOAD_TESTER_TRUE@am__append_4 = plugins/load_tester/libstrongswan-load-tester.la
+@USE_SOCKET_DEFAULT_TRUE@am__append_5 = plugins/socket_default
+@MONOLITHIC_TRUE@@USE_SOCKET_DEFAULT_TRUE@am__append_6 = plugins/socket_default/libstrongswan-socket-default.la
+@USE_SOCKET_RAW_TRUE@am__append_7 = plugins/socket_raw
+@MONOLITHIC_TRUE@@USE_SOCKET_RAW_TRUE@am__append_8 = plugins/socket_raw/libstrongswan-socket-raw.la
+@USE_SOCKET_DYNAMIC_TRUE@am__append_9 = plugins/socket_dynamic
+@MONOLITHIC_TRUE@@USE_SOCKET_DYNAMIC_TRUE@am__append_10 = plugins/socket_dynamic/libstrongswan-socket-dynamic.la
+@USE_FARP_TRUE@am__append_11 = plugins/farp
+@MONOLITHIC_TRUE@@USE_FARP_TRUE@am__append_12 = plugins/farp/libstrongswan-farp.la
+@USE_STROKE_TRUE@am__append_13 = plugins/stroke
+@MONOLITHIC_TRUE@@USE_STROKE_TRUE@am__append_14 = plugins/stroke/libstrongswan-stroke.la
+@USE_SMP_TRUE@am__append_15 = plugins/smp
+@MONOLITHIC_TRUE@@USE_SMP_TRUE@am__append_16 = plugins/smp/libstrongswan-smp.la
+@USE_SQL_TRUE@am__append_17 = plugins/sql
+@MONOLITHIC_TRUE@@USE_SQL_TRUE@am__append_18 = plugins/sql/libstrongswan-sql.la
+@USE_UPDOWN_TRUE@am__append_19 = plugins/updown
+@MONOLITHIC_TRUE@@USE_UPDOWN_TRUE@am__append_20 = plugins/updown/libstrongswan-updown.la
+@USE_EAP_IDENTITY_TRUE@am__append_21 = plugins/eap_identity
+@MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE@am__append_22 = plugins/eap_identity/libstrongswan-eap-identity.la
+@USE_EAP_SIM_TRUE@am__append_23 = plugins/eap_sim
+@MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE@am__append_24 = plugins/eap_sim/libstrongswan-eap-sim.la
+@USE_EAP_SIM_FILE_TRUE@am__append_25 = plugins/eap_sim_file
+@MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE@am__append_26 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la
+@USE_EAP_SIMAKA_SQL_TRUE@am__append_27 = plugins/eap_simaka_sql
+@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE@am__append_28 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la
+@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_29 = plugins/eap_simaka_pseudonym
+@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_30 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la
+@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_31 = plugins/eap_simaka_reauth
+@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_32 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la
+@USE_EAP_AKA_TRUE@am__append_33 = plugins/eap_aka
+@MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE@am__append_34 = plugins/eap_aka/libstrongswan-eap-aka.la
+@USE_EAP_AKA_3GPP2_TRUE@am__append_35 = plugins/eap_aka_3gpp2
+@MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE@am__append_36 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la
+@MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@am__append_37 = $(top_builddir)/src/libsimaka/libsimaka.la
+@USE_EAP_MD5_TRUE@am__append_38 = plugins/eap_md5
+@MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE@am__append_39 = plugins/eap_md5/libstrongswan-eap-md5.la
+@USE_EAP_GTC_TRUE@am__append_40 = plugins/eap_gtc
+@MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE@am__append_41 = plugins/eap_gtc/libstrongswan-eap-gtc.la
+@USE_EAP_MSCHAPV2_TRUE@am__append_42 = plugins/eap_mschapv2
+@MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE@am__append_43 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la
+@USE_EAP_RADIUS_TRUE@am__append_44 = plugins/eap_radius
+@MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE@am__append_45 = plugins/eap_radius/libstrongswan-eap-radius.la
+@USE_EAP_TLS_TRUE@am__append_46 = plugins/eap_tls
+@MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE@am__append_47 = plugins/eap_tls/libstrongswan-eap-tls.la
+@USE_EAP_TTLS_TRUE@am__append_48 = plugins/eap_ttls
+@MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE@am__append_49 = plugins/eap_ttls/libstrongswan-eap-ttls.la
+@USE_EAP_TNC_TRUE@am__append_50 = plugins/eap_tnc
+@MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE@am__append_51 = plugins/eap_tnc/libstrongswan-eap-tnc.la
+@MONOLITHIC_TRUE@@USE_TLS_TRUE@am__append_52 = $(top_builddir)/src/libtls/libtls.la
+@USE_TNC_IMC_TRUE@am__append_53 = plugins/tnc_imc
+@MONOLITHIC_TRUE@@USE_TNC_IMC_TRUE@am__append_54 = plugins/tnc_imc/libstrongswan-tnc_imc.la
+@USE_TNC_IMV_TRUE@am__append_55 = plugins/tnc_imv
+@MONOLITHIC_TRUE@@USE_TNC_IMV_TRUE@am__append_56 = plugins/tnc_imv/libstrongswan-tnc_imv.la
+@USE_TNCCS_11_TRUE@am__append_57 = plugins/tnccs_11
+@MONOLITHIC_TRUE@@USE_TNCCS_11_TRUE@am__append_58 = plugins/tnccs_11/libstrongswan-tnccs-11.la
+@USE_TNCCS_20_TRUE@am__append_59 = plugins/tnccs_20
+@MONOLITHIC_TRUE@@USE_TNCCS_20_TRUE@am__append_60 = plugins/tnccs_20/libstrongswan-tnccs-20.la
+@USE_MEDSRV_TRUE@am__append_61 = plugins/medsrv
+@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_62 = plugins/medsrv/libstrongswan-medsrv.la
+@USE_MEDCLI_TRUE@am__append_63 = plugins/medcli
+@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_64 = plugins/medcli/libstrongswan-medcli.la
+@USE_NM_TRUE@am__append_65 = plugins/nm
+@MONOLITHIC_TRUE@@USE_NM_TRUE@am__append_66 = plugins/nm/libstrongswan-nm.la
+@USE_DHCP_TRUE@am__append_67 = plugins/dhcp
+@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_68 = plugins/dhcp/libstrongswan-dhcp.la
+@USE_ANDROID_TRUE@am__append_69 = plugins/android
+@MONOLITHIC_TRUE@@USE_ANDROID_TRUE@am__append_70 = plugins/android/libstrongswan-android.la
+@USE_MAEMO_TRUE@am__append_71 = plugins/maemo
+@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_72 = plugins/maemo/libstrongswan-maemo.la
+@USE_HA_TRUE@am__append_73 = plugins/ha
+@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_74 = plugins/ha/libstrongswan-ha.la
+@USE_LED_TRUE@am__append_75 = plugins/led
+@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_76 = plugins/led/libstrongswan-led.la
+@USE_UCI_TRUE@am__append_77 = plugins/uci
+@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_78 = plugins/uci/libstrongswan-uci.la
+@USE_ADDRBLOCK_TRUE@am__append_79 = plugins/addrblock
+@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_80 = plugins/uci/libstrongswan-addrblock.la
+@USE_UNIT_TESTS_TRUE@am__append_81 = plugins/unit_tester
+@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_82 = plugins/unit_tester/libstrongswan-unit-tester.la
subdir = src/libcharon
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -158,6 +135,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -190,18 +168,20 @@ LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libcharon_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1) $(am__append_5) $(am__append_8) \
- $(am__append_11) $(am__append_14) $(am__append_17) \
- $(am__append_20) $(am__append_23) $(am__append_26) \
- $(am__append_29) $(am__append_32) $(am__append_35) \
- $(am__append_38) $(am__append_41) $(am__append_44) \
- $(am__append_47) $(am__append_50) $(am__append_53) \
- $(am__append_56) $(am__append_59) $(am__append_62) \
- $(am__append_65) $(am__append_66) $(am__append_69) \
- $(am__append_72) $(am__append_75) $(am__append_78) \
- $(am__append_81) $(am__append_84) $(am__append_87) \
- $(am__append_90) $(am__append_93) $(am__append_96) \
- $(am__append_99) $(am__append_102) $(am__append_105)
+ $(am__DEPENDENCIES_1) $(am__append_4) $(am__append_6) \
+ $(am__append_8) $(am__append_10) $(am__append_12) \
+ $(am__append_14) $(am__append_16) $(am__append_18) \
+ $(am__append_20) $(am__append_22) $(am__append_24) \
+ $(am__append_26) $(am__append_28) $(am__append_30) \
+ $(am__append_32) $(am__append_34) $(am__append_36) \
+ $(am__append_37) $(am__append_39) $(am__append_41) \
+ $(am__append_43) $(am__append_45) $(am__append_47) \
+ $(am__append_49) $(am__append_51) $(am__append_52) \
+ $(am__append_54) $(am__append_56) $(am__append_58) \
+ $(am__append_60) $(am__append_62) $(am__append_64) \
+ $(am__append_66) $(am__append_68) $(am__append_70) \
+ $(am__append_72) $(am__append_74) $(am__append_76) \
+ $(am__append_78) $(am__append_80) $(am__append_82)
am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
bus/listeners/listener.h bus/listeners/file_logger.c \
bus/listeners/file_logger.h bus/listeners/sys_logger.c \
@@ -249,16 +229,12 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
encoding/payloads/unknown_payload.c \
encoding/payloads/unknown_payload.h \
encoding/payloads/vendor_id_payload.c \
- encoding/payloads/vendor_id_payload.h \
- kernel/kernel_interface.c kernel/kernel_interface.h \
- kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
- kernel/kernel_net.h network/packet.c network/packet.h \
+ encoding/payloads/vendor_id_payload.h kernel/kernel_handler.c \
+ kernel/kernel_handler.h network/packet.c network/packet.h \
network/receiver.c network/receiver.h network/sender.c \
network/sender.h network/socket_manager.c \
network/socket_manager.h network/socket.h \
- processing/jobs/job.h processing/jobs/acquire_job.c \
- processing/jobs/acquire_job.h processing/jobs/callback_job.c \
- processing/jobs/callback_job.h \
+ processing/jobs/acquire_job.c processing/jobs/acquire_job.h \
processing/jobs/delete_child_sa_job.c \
processing/jobs/delete_child_sa_job.h \
processing/jobs/delete_ike_sa_job.c \
@@ -279,9 +255,8 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
processing/jobs/update_sa_job.c \
processing/jobs/update_sa_job.h \
processing/jobs/inactivity_job.c \
- processing/jobs/inactivity_job.h processing/scheduler.c \
- processing/scheduler.h processing/processor.c \
- processing/processor.h sa/authenticators/authenticator.c \
+ processing/jobs/inactivity_job.h \
+ sa/authenticators/authenticator.c \
sa/authenticators/authenticator.h \
sa/authenticators/eap_authenticator.c \
sa/authenticators/eap_authenticator.h \
@@ -313,7 +288,8 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
sa/tasks/ike_reauth.h sa/tasks/ike_auth_lifetime.c \
sa/tasks/ike_auth_lifetime.h sa/tasks/ike_vendor.c \
sa/tasks/ike_vendor.h sa/tasks/task.c sa/tasks/task.h \
- encoding/payloads/endpoint_notify.c \
+ tnccs/tnccs.c tnccs/tnccs.h tnccs/tnccs_manager.h \
+ tnccs/tnccs_manager.c encoding/payloads/endpoint_notify.c \
encoding/payloads/endpoint_notify.h \
processing/jobs/initiate_mediation_job.c \
processing/jobs/initiate_mediation_job.h \
@@ -334,22 +310,21 @@ am_libcharon_la_OBJECTS = bus.lo file_logger.lo sys_logger.lo \
notify_payload.lo payload.lo proposal_substructure.lo \
sa_payload.lo traffic_selector_substructure.lo \
transform_attribute.lo transform_substructure.lo ts_payload.lo \
- unknown_payload.lo vendor_id_payload.lo kernel_interface.lo \
- kernel_ipsec.lo packet.lo receiver.lo sender.lo \
- socket_manager.lo acquire_job.lo callback_job.lo \
- delete_child_sa_job.lo delete_ike_sa_job.lo migrate_job.lo \
- process_message_job.lo rekey_child_sa_job.lo \
+ unknown_payload.lo vendor_id_payload.lo kernel_handler.lo \
+ packet.lo receiver.lo sender.lo socket_manager.lo \
+ acquire_job.lo delete_child_sa_job.lo delete_ike_sa_job.lo \
+ migrate_job.lo process_message_job.lo rekey_child_sa_job.lo \
rekey_ike_sa_job.lo retransmit_job.lo send_dpd_job.lo \
send_keepalive_job.lo roam_job.lo update_sa_job.lo \
- inactivity_job.lo scheduler.lo processor.lo authenticator.lo \
- eap_authenticator.lo eap_method.lo eap_manager.lo \
- sim_manager.lo psk_authenticator.lo pubkey_authenticator.lo \
- child_sa.lo ike_sa.lo ike_sa_id.lo ike_sa_manager.lo \
- task_manager.lo keymat.lo trap_manager.lo child_create.lo \
- child_delete.lo child_rekey.lo ike_auth.lo ike_cert_pre.lo \
- ike_cert_post.lo ike_config.lo ike_delete.lo ike_dpd.lo \
- ike_init.lo ike_natd.lo ike_mobike.lo ike_rekey.lo \
- ike_reauth.lo ike_auth_lifetime.lo ike_vendor.lo task.lo \
+ inactivity_job.lo authenticator.lo eap_authenticator.lo \
+ eap_method.lo eap_manager.lo sim_manager.lo \
+ psk_authenticator.lo pubkey_authenticator.lo child_sa.lo \
+ ike_sa.lo ike_sa_id.lo ike_sa_manager.lo task_manager.lo \
+ keymat.lo trap_manager.lo child_create.lo child_delete.lo \
+ child_rekey.lo ike_auth.lo ike_cert_pre.lo ike_cert_post.lo \
+ ike_config.lo ike_delete.lo ike_dpd.lo ike_init.lo ike_natd.lo \
+ ike_mobike.lo ike_rekey.lo ike_reauth.lo ike_auth_lifetime.lo \
+ ike_vendor.lo task.lo tnccs.lo tnccs_manager.lo \
$(am__objects_1)
libcharon_la_OBJECTS = $(am_libcharon_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
@@ -381,18 +356,19 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
distdir
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = . plugins/load_tester plugins/kernel_pfkey \
- plugins/kernel_pfroute plugins/kernel_klips \
- plugins/kernel_netlink plugins/socket_default \
+DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \
plugins/socket_raw plugins/socket_dynamic plugins/farp \
plugins/stroke plugins/smp plugins/sql plugins/updown \
plugins/eap_identity plugins/eap_sim plugins/eap_sim_file \
plugins/eap_simaka_sql plugins/eap_simaka_pseudonym \
plugins/eap_simaka_reauth plugins/eap_aka \
plugins/eap_aka_3gpp2 plugins/eap_md5 plugins/eap_gtc \
- plugins/eap_mschapv2 plugins/eap_radius plugins/medsrv \
- plugins/medcli plugins/nm plugins/dhcp plugins/android \
- plugins/ha plugins/uci plugins/addrblock plugins/unit_tester
+ plugins/eap_mschapv2 plugins/eap_radius plugins/eap_tls \
+ plugins/eap_ttls plugins/eap_tnc plugins/tnc_imc \
+ plugins/tnc_imv plugins/tnccs_11 plugins/tnccs_20 \
+ plugins/medsrv plugins/medcli plugins/nm plugins/dhcp \
+ plugins/android plugins/maemo plugins/ha plugins/led \
+ plugins/uci plugins/addrblock plugins/unit_tester
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -484,6 +460,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -515,14 +493,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -537,24 +518,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -562,7 +550,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
@@ -622,16 +613,12 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \
encoding/payloads/unknown_payload.c \
encoding/payloads/unknown_payload.h \
encoding/payloads/vendor_id_payload.c \
- encoding/payloads/vendor_id_payload.h \
- kernel/kernel_interface.c kernel/kernel_interface.h \
- kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
- kernel/kernel_net.h network/packet.c network/packet.h \
+ encoding/payloads/vendor_id_payload.h kernel/kernel_handler.c \
+ kernel/kernel_handler.h network/packet.c network/packet.h \
network/receiver.c network/receiver.h network/sender.c \
network/sender.h network/socket_manager.c \
network/socket_manager.h network/socket.h \
- processing/jobs/job.h processing/jobs/acquire_job.c \
- processing/jobs/acquire_job.h processing/jobs/callback_job.c \
- processing/jobs/callback_job.h \
+ processing/jobs/acquire_job.c processing/jobs/acquire_job.h \
processing/jobs/delete_child_sa_job.c \
processing/jobs/delete_child_sa_job.h \
processing/jobs/delete_ike_sa_job.c \
@@ -652,9 +639,8 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \
processing/jobs/update_sa_job.c \
processing/jobs/update_sa_job.h \
processing/jobs/inactivity_job.c \
- processing/jobs/inactivity_job.h processing/scheduler.c \
- processing/scheduler.h processing/processor.c \
- processing/processor.h sa/authenticators/authenticator.c \
+ processing/jobs/inactivity_job.h \
+ sa/authenticators/authenticator.c \
sa/authenticators/authenticator.h \
sa/authenticators/eap_authenticator.c \
sa/authenticators/eap_authenticator.h \
@@ -686,78 +672,78 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \
sa/tasks/ike_reauth.h sa/tasks/ike_auth_lifetime.c \
sa/tasks/ike_auth_lifetime.h sa/tasks/ike_vendor.c \
sa/tasks/ike_vendor.h sa/tasks/task.c sa/tasks/task.h \
- $(am__append_1)
+ tnccs/tnccs.c tnccs/tnccs.h tnccs/tnccs_manager.h \
+ tnccs/tnccs_manager.c $(am__append_1)
INCLUDES = \
-I${linux_headers} \
-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon
-AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\" \
- -DPLUGINS=\""${PLUGINS}\""
+AM_CFLAGS = \
+ -DIPSEC_DIR=\"${ipsecdir}\" \
+ -DIPSEC_PIDDIR=\"${piddir}\" \
+ -DPLUGINS=\""${libcharon_plugins}\""
+
libcharon_la_LIBADD = -lm $(PTHREADLIB) $(DLLIB) $(SOCKLIB) \
- $(am__append_2) $(am__append_5) $(am__append_8) \
- $(am__append_11) $(am__append_14) $(am__append_17) \
- $(am__append_20) $(am__append_23) $(am__append_26) \
- $(am__append_29) $(am__append_32) $(am__append_35) \
- $(am__append_38) $(am__append_41) $(am__append_44) \
- $(am__append_47) $(am__append_50) $(am__append_53) \
- $(am__append_56) $(am__append_59) $(am__append_62) \
- $(am__append_65) $(am__append_66) $(am__append_69) \
- $(am__append_72) $(am__append_75) $(am__append_78) \
- $(am__append_81) $(am__append_84) $(am__append_87) \
- $(am__append_90) $(am__append_93) $(am__append_96) \
- $(am__append_99) $(am__append_102) $(am__append_105)
+ $(am__append_2) $(am__append_4) $(am__append_6) \
+ $(am__append_8) $(am__append_10) $(am__append_12) \
+ $(am__append_14) $(am__append_16) $(am__append_18) \
+ $(am__append_20) $(am__append_22) $(am__append_24) \
+ $(am__append_26) $(am__append_28) $(am__append_30) \
+ $(am__append_32) $(am__append_34) $(am__append_36) \
+ $(am__append_37) $(am__append_39) $(am__append_41) \
+ $(am__append_43) $(am__append_45) $(am__append_47) \
+ $(am__append_49) $(am__append_51) $(am__append_52) \
+ $(am__append_54) $(am__append_56) $(am__append_58) \
+ $(am__append_60) $(am__append_62) $(am__append_64) \
+ $(am__append_66) $(am__append_68) $(am__append_70) \
+ $(am__append_72) $(am__append_74) $(am__append_76) \
+ $(am__append_78) $(am__append_80) $(am__append_82)
EXTRA_DIST = Android.mk
-@MONOLITHIC_FALSE@SUBDIRS = . $(am__append_3) $(am__append_6) \
-@MONOLITHIC_FALSE@ $(am__append_9) $(am__append_12) \
-@MONOLITHIC_FALSE@ $(am__append_15) $(am__append_18) \
-@MONOLITHIC_FALSE@ $(am__append_21) $(am__append_24) \
-@MONOLITHIC_FALSE@ $(am__append_27) $(am__append_30) \
-@MONOLITHIC_FALSE@ $(am__append_33) $(am__append_36) \
-@MONOLITHIC_FALSE@ $(am__append_39) $(am__append_42) \
-@MONOLITHIC_FALSE@ $(am__append_45) $(am__append_48) \
-@MONOLITHIC_FALSE@ $(am__append_51) $(am__append_54) \
-@MONOLITHIC_FALSE@ $(am__append_57) $(am__append_60) \
-@MONOLITHIC_FALSE@ $(am__append_63) $(am__append_67) \
-@MONOLITHIC_FALSE@ $(am__append_70) $(am__append_73) \
-@MONOLITHIC_FALSE@ $(am__append_76) $(am__append_79) \
-@MONOLITHIC_FALSE@ $(am__append_82) $(am__append_85) \
-@MONOLITHIC_FALSE@ $(am__append_88) $(am__append_91) \
-@MONOLITHIC_FALSE@ $(am__append_94) $(am__append_97) \
-@MONOLITHIC_FALSE@ $(am__append_100) $(am__append_103)
+@MONOLITHIC_FALSE@SUBDIRS = . $(am__append_3) $(am__append_5) \
+@MONOLITHIC_FALSE@ $(am__append_7) $(am__append_9) \
+@MONOLITHIC_FALSE@ $(am__append_11) $(am__append_13) \
+@MONOLITHIC_FALSE@ $(am__append_15) $(am__append_17) \
+@MONOLITHIC_FALSE@ $(am__append_19) $(am__append_21) \
+@MONOLITHIC_FALSE@ $(am__append_23) $(am__append_25) \
+@MONOLITHIC_FALSE@ $(am__append_27) $(am__append_29) \
+@MONOLITHIC_FALSE@ $(am__append_31) $(am__append_33) \
+@MONOLITHIC_FALSE@ $(am__append_35) $(am__append_38) \
+@MONOLITHIC_FALSE@ $(am__append_40) $(am__append_42) \
+@MONOLITHIC_FALSE@ $(am__append_44) $(am__append_46) \
+@MONOLITHIC_FALSE@ $(am__append_48) $(am__append_50) \
+@MONOLITHIC_FALSE@ $(am__append_53) $(am__append_55) \
+@MONOLITHIC_FALSE@ $(am__append_57) $(am__append_59) \
+@MONOLITHIC_FALSE@ $(am__append_61) $(am__append_63) \
+@MONOLITHIC_FALSE@ $(am__append_65) $(am__append_67) \
+@MONOLITHIC_FALSE@ $(am__append_69) $(am__append_71) \
+@MONOLITHIC_FALSE@ $(am__append_73) $(am__append_75) \
+@MONOLITHIC_FALSE@ $(am__append_77) $(am__append_79) \
+@MONOLITHIC_FALSE@ $(am__append_81)
# build optional plugins
########################
-@MONOLITHIC_TRUE@SUBDIRS = $(am__append_3) $(am__append_6) \
-@MONOLITHIC_TRUE@ $(am__append_9) $(am__append_12) \
-@MONOLITHIC_TRUE@ $(am__append_15) $(am__append_18) \
-@MONOLITHIC_TRUE@ $(am__append_21) $(am__append_24) \
-@MONOLITHIC_TRUE@ $(am__append_27) $(am__append_30) \
-@MONOLITHIC_TRUE@ $(am__append_33) $(am__append_36) \
-@MONOLITHIC_TRUE@ $(am__append_39) $(am__append_42) \
-@MONOLITHIC_TRUE@ $(am__append_45) $(am__append_48) \
-@MONOLITHIC_TRUE@ $(am__append_51) $(am__append_54) \
-@MONOLITHIC_TRUE@ $(am__append_57) $(am__append_60) \
-@MONOLITHIC_TRUE@ $(am__append_63) $(am__append_67) \
-@MONOLITHIC_TRUE@ $(am__append_70) $(am__append_73) \
-@MONOLITHIC_TRUE@ $(am__append_76) $(am__append_79) \
-@MONOLITHIC_TRUE@ $(am__append_82) $(am__append_85) \
-@MONOLITHIC_TRUE@ $(am__append_88) $(am__append_91) \
-@MONOLITHIC_TRUE@ $(am__append_94) $(am__append_97) \
-@MONOLITHIC_TRUE@ $(am__append_100) $(am__append_103)
-PLUGINS = ${libstrongswan_plugins} ${libhydra_plugins} $(am__append_4) \
- $(am__append_7) $(am__append_10) $(am__append_13) \
- $(am__append_16) $(am__append_19) $(am__append_22) \
- $(am__append_25) $(am__append_28) $(am__append_31) \
- $(am__append_34) $(am__append_37) $(am__append_40) \
- $(am__append_43) $(am__append_46) $(am__append_49) \
- $(am__append_52) $(am__append_55) $(am__append_58) \
- $(am__append_61) $(am__append_64) $(am__append_68) \
- $(am__append_71) $(am__append_74) $(am__append_77) \
- $(am__append_80) $(am__append_83) $(am__append_86) \
- $(am__append_89) $(am__append_92) $(am__append_95) \
- $(am__append_98) $(am__append_101) $(am__append_104)
+@MONOLITHIC_TRUE@SUBDIRS = $(am__append_3) $(am__append_5) \
+@MONOLITHIC_TRUE@ $(am__append_7) $(am__append_9) \
+@MONOLITHIC_TRUE@ $(am__append_11) $(am__append_13) \
+@MONOLITHIC_TRUE@ $(am__append_15) $(am__append_17) \
+@MONOLITHIC_TRUE@ $(am__append_19) $(am__append_21) \
+@MONOLITHIC_TRUE@ $(am__append_23) $(am__append_25) \
+@MONOLITHIC_TRUE@ $(am__append_27) $(am__append_29) \
+@MONOLITHIC_TRUE@ $(am__append_31) $(am__append_33) \
+@MONOLITHIC_TRUE@ $(am__append_35) $(am__append_38) \
+@MONOLITHIC_TRUE@ $(am__append_40) $(am__append_42) \
+@MONOLITHIC_TRUE@ $(am__append_44) $(am__append_46) \
+@MONOLITHIC_TRUE@ $(am__append_48) $(am__append_50) \
+@MONOLITHIC_TRUE@ $(am__append_53) $(am__append_55) \
+@MONOLITHIC_TRUE@ $(am__append_57) $(am__append_59) \
+@MONOLITHIC_TRUE@ $(am__append_61) $(am__append_63) \
+@MONOLITHIC_TRUE@ $(am__append_65) $(am__append_67) \
+@MONOLITHIC_TRUE@ $(am__append_69) $(am__append_71) \
+@MONOLITHIC_TRUE@ $(am__append_73) $(am__append_75) \
+@MONOLITHIC_TRUE@ $(am__append_77) $(am__append_79) \
+@MONOLITHIC_TRUE@ $(am__append_81)
all: all-recursive
.SUFFIXES:
@@ -837,7 +823,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/authenticator.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend_manager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bus.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback_job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cert_payload.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certreq_payload.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/child_cfg.Plo@am__quote@
@@ -885,8 +870,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inactivity_job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/initiate_mediation_job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ke_payload.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_interface.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_ipsec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_handler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keymat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mediation_job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mediation_manager.Plo@am__quote@
@@ -899,7 +883,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/payload.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peer_cfg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/process_message_job.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/processor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proposal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proposal_substructure.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psk_authenticator.Plo@am__quote@
@@ -910,7 +893,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/retransmit_job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/roam_job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sa_payload.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scheduler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/send_dpd_job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/send_keepalive_job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sender.Plo@am__quote@
@@ -919,6 +901,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sys_logger.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/task_manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_manager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/traffic_selector_substructure.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform_attribute.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform_substructure.Plo@am__quote@
@@ -1194,19 +1178,12 @@ vendor_id_payload.lo: encoding/payloads/vendor_id_payload.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vendor_id_payload.lo `test -f 'encoding/payloads/vendor_id_payload.c' || echo '$(srcdir)/'`encoding/payloads/vendor_id_payload.c
-kernel_interface.lo: kernel/kernel_interface.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT kernel_interface.lo -MD -MP -MF $(DEPDIR)/kernel_interface.Tpo -c -o kernel_interface.lo `test -f 'kernel/kernel_interface.c' || echo '$(srcdir)/'`kernel/kernel_interface.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kernel_interface.Tpo $(DEPDIR)/kernel_interface.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kernel/kernel_interface.c' object='kernel_interface.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o kernel_interface.lo `test -f 'kernel/kernel_interface.c' || echo '$(srcdir)/'`kernel/kernel_interface.c
-
-kernel_ipsec.lo: kernel/kernel_ipsec.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT kernel_ipsec.lo -MD -MP -MF $(DEPDIR)/kernel_ipsec.Tpo -c -o kernel_ipsec.lo `test -f 'kernel/kernel_ipsec.c' || echo '$(srcdir)/'`kernel/kernel_ipsec.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kernel_ipsec.Tpo $(DEPDIR)/kernel_ipsec.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kernel/kernel_ipsec.c' object='kernel_ipsec.lo' libtool=yes @AMDEPBACKSLASH@
+kernel_handler.lo: kernel/kernel_handler.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT kernel_handler.lo -MD -MP -MF $(DEPDIR)/kernel_handler.Tpo -c -o kernel_handler.lo `test -f 'kernel/kernel_handler.c' || echo '$(srcdir)/'`kernel/kernel_handler.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kernel_handler.Tpo $(DEPDIR)/kernel_handler.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kernel/kernel_handler.c' object='kernel_handler.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o kernel_ipsec.lo `test -f 'kernel/kernel_ipsec.c' || echo '$(srcdir)/'`kernel/kernel_ipsec.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o kernel_handler.lo `test -f 'kernel/kernel_handler.c' || echo '$(srcdir)/'`kernel/kernel_handler.c
packet.lo: network/packet.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT packet.lo -MD -MP -MF $(DEPDIR)/packet.Tpo -c -o packet.lo `test -f 'network/packet.c' || echo '$(srcdir)/'`network/packet.c
@@ -1243,13 +1220,6 @@ acquire_job.lo: processing/jobs/acquire_job.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o acquire_job.lo `test -f 'processing/jobs/acquire_job.c' || echo '$(srcdir)/'`processing/jobs/acquire_job.c
-callback_job.lo: processing/jobs/callback_job.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT callback_job.lo -MD -MP -MF $(DEPDIR)/callback_job.Tpo -c -o callback_job.lo `test -f 'processing/jobs/callback_job.c' || echo '$(srcdir)/'`processing/jobs/callback_job.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/callback_job.Tpo $(DEPDIR)/callback_job.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='processing/jobs/callback_job.c' object='callback_job.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o callback_job.lo `test -f 'processing/jobs/callback_job.c' || echo '$(srcdir)/'`processing/jobs/callback_job.c
-
delete_child_sa_job.lo: processing/jobs/delete_child_sa_job.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT delete_child_sa_job.lo -MD -MP -MF $(DEPDIR)/delete_child_sa_job.Tpo -c -o delete_child_sa_job.lo `test -f 'processing/jobs/delete_child_sa_job.c' || echo '$(srcdir)/'`processing/jobs/delete_child_sa_job.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/delete_child_sa_job.Tpo $(DEPDIR)/delete_child_sa_job.Plo
@@ -1334,20 +1304,6 @@ inactivity_job.lo: processing/jobs/inactivity_job.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o inactivity_job.lo `test -f 'processing/jobs/inactivity_job.c' || echo '$(srcdir)/'`processing/jobs/inactivity_job.c
-scheduler.lo: processing/scheduler.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT scheduler.lo -MD -MP -MF $(DEPDIR)/scheduler.Tpo -c -o scheduler.lo `test -f 'processing/scheduler.c' || echo '$(srcdir)/'`processing/scheduler.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/scheduler.Tpo $(DEPDIR)/scheduler.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='processing/scheduler.c' object='scheduler.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o scheduler.lo `test -f 'processing/scheduler.c' || echo '$(srcdir)/'`processing/scheduler.c
-
-processor.lo: processing/processor.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT processor.lo -MD -MP -MF $(DEPDIR)/processor.Tpo -c -o processor.lo `test -f 'processing/processor.c' || echo '$(srcdir)/'`processing/processor.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/processor.Tpo $(DEPDIR)/processor.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='processing/processor.c' object='processor.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o processor.lo `test -f 'processing/processor.c' || echo '$(srcdir)/'`processing/processor.c
-
authenticator.lo: sa/authenticators/authenticator.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT authenticator.lo -MD -MP -MF $(DEPDIR)/authenticator.Tpo -c -o authenticator.lo `test -f 'sa/authenticators/authenticator.c' || echo '$(srcdir)/'`sa/authenticators/authenticator.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/authenticator.Tpo $(DEPDIR)/authenticator.Plo
@@ -1565,6 +1521,20 @@ task.lo: sa/tasks/task.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o task.lo `test -f 'sa/tasks/task.c' || echo '$(srcdir)/'`sa/tasks/task.c
+tnccs.lo: tnccs/tnccs.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs.lo -MD -MP -MF $(DEPDIR)/tnccs.Tpo -c -o tnccs.lo `test -f 'tnccs/tnccs.c' || echo '$(srcdir)/'`tnccs/tnccs.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs.Tpo $(DEPDIR)/tnccs.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnccs/tnccs.c' object='tnccs.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs.lo `test -f 'tnccs/tnccs.c' || echo '$(srcdir)/'`tnccs/tnccs.c
+
+tnccs_manager.lo: tnccs/tnccs_manager.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_manager.lo -MD -MP -MF $(DEPDIR)/tnccs_manager.Tpo -c -o tnccs_manager.lo `test -f 'tnccs/tnccs_manager.c' || echo '$(srcdir)/'`tnccs/tnccs_manager.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_manager.Tpo $(DEPDIR)/tnccs_manager.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnccs/tnccs_manager.c' object='tnccs_manager.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_manager.lo `test -f 'tnccs/tnccs_manager.c' || echo '$(srcdir)/'`tnccs/tnccs_manager.c
+
endpoint_notify.lo: encoding/payloads/endpoint_notify.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT endpoint_notify.lo -MD -MP -MF $(DEPDIR)/endpoint_notify.Tpo -c -o endpoint_notify.lo `test -f 'encoding/payloads/endpoint_notify.c' || echo '$(srcdir)/'`encoding/payloads/endpoint_notify.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/endpoint_notify.Tpo $(DEPDIR)/endpoint_notify.Plo
@@ -1934,6 +1904,8 @@ daemon.lo : $(top_builddir)/config.status
@MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@ # otherwise this library is linked to both the eap_aka and the eap_sim plugin
+@MONOLITHIC_TRUE@@USE_TLS_TRUE@ # otherwise this library is linked to eap_tls
+
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c
index 441009e5e..ab8d0fc48 100644
--- a/src/libcharon/bus/bus.c
+++ b/src/libcharon/bus/bus.c
@@ -17,7 +17,6 @@
#include <stdint.h>
-#include <daemon.h>
#include <threading/thread.h>
#include <threading/thread_value.h>
#include <threading/condvar.h>
@@ -163,7 +162,7 @@ METHOD(bus_t, listen_, void,
this->mutex->lock(this->mutex);
this->listeners->insert_last(this->listeners, data.entry);
- charon->processor->queue_job(charon->processor, job);
+ lib->processor->queue_job(lib->processor, job);
thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
thread_cleanup_push((thread_cleanup_t)listener_cleanup, &data);
old = thread_cancelability(TRUE);
diff --git a/src/libcharon/bus/listeners/file_logger.c b/src/libcharon/bus/listeners/file_logger.c
index 87db532f5..157436a7d 100644
--- a/src/libcharon/bus/listeners/file_logger.c
+++ b/src/libcharon/bus/listeners/file_logger.c
@@ -46,6 +46,11 @@ struct private_file_logger_t {
* strftime() format of time prefix, if any
*/
char *time_format;
+
+ /**
+ * Print the name/# of the IKE_SA?
+ */
+ bool ike_name;
};
/**
@@ -56,7 +61,7 @@ static bool log_(private_file_logger_t *this, debug_t group, level_t level,
{
if (level <= this->levels[group])
{
- char buffer[8192], timestr[128];
+ char buffer[8192], timestr[128], namestr[128] = "";
char *current = buffer, *next;
struct tm tm;
time_t t;
@@ -67,6 +72,23 @@ static bool log_(private_file_logger_t *this, debug_t group, level_t level,
localtime_r(&t, &tm);
strftime(timestr, sizeof(timestr), this->time_format, &tm);
}
+ if (this->ike_name && ike_sa)
+ {
+ if (ike_sa->get_peer_cfg(ike_sa))
+ {
+ snprintf(namestr, sizeof(namestr), " <%s|%d>",
+ ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
+ }
+ else
+ {
+ snprintf(namestr, sizeof(namestr), " <%d>",
+ ike_sa->get_unique_id(ike_sa));
+ }
+ }
+ else
+ {
+ namestr[0] = '\0';
+ }
/* write in memory buffer first */
vsnprintf(buffer, sizeof(buffer), format, args);
@@ -81,13 +103,13 @@ static bool log_(private_file_logger_t *this, debug_t group, level_t level,
}
if (this->time_format)
{
- fprintf(this->out, "%s %.2d[%N] %s\n",
- timestr, thread, debug_names, group, current);
+ fprintf(this->out, "%s %.2d[%N]%s %s\n",
+ timestr, thread, debug_names, group, namestr, current);
}
else
{
- fprintf(this->out, "%.2d[%N] %s\n",
- thread, debug_names, group, current);
+ fprintf(this->out, "%.2d[%N]%s %s\n",
+ thread, debug_names, group, namestr, current);
}
current = next;
}
@@ -129,7 +151,7 @@ static void destroy(private_file_logger_t *this)
/*
* Described in header.
*/
-file_logger_t *file_logger_create(FILE *out, char *time_format)
+file_logger_t *file_logger_create(FILE *out, char *time_format, bool ike_name)
{
private_file_logger_t *this = malloc_thing(private_file_logger_t);
@@ -142,6 +164,7 @@ file_logger_t *file_logger_create(FILE *out, char *time_format)
/* private variables */
this->out = out;
this->time_format = time_format;
+ this->ike_name = ike_name;
set_level(this, DBG_ANY, LEVEL_SILENT);
return &this->public;
diff --git a/src/libcharon/bus/listeners/file_logger.h b/src/libcharon/bus/listeners/file_logger.h
index e02a12c0c..d02f1701d 100644
--- a/src/libcharon/bus/listeners/file_logger.h
+++ b/src/libcharon/bus/listeners/file_logger.h
@@ -54,8 +54,9 @@ struct file_logger_t {
*
* @param out FILE to write to
* @param time_format format of timestamp prefix, as in strftime()
+ * @param ike_name TRUE to prefix the name of the IKE_SA
* @return file_logger_t object
*/
-file_logger_t *file_logger_create(FILE *out, char *time_format);
+file_logger_t *file_logger_create(FILE *out, char *time_format, bool ike_name);
#endif /** FILE_LOGGER_H_ @}*/
diff --git a/src/libcharon/bus/listeners/sys_logger.c b/src/libcharon/bus/listeners/sys_logger.c
index 5bc1d581a..fa394ba88 100644
--- a/src/libcharon/bus/listeners/sys_logger.c
+++ b/src/libcharon/bus/listeners/sys_logger.c
@@ -41,6 +41,11 @@ struct private_sys_logger_t {
* Maximum level to log, for each group
*/
level_t levels[DBG_MAX];
+
+ /**
+ * Print the name/# of the IKE_SA?
+ */
+ bool ike_name;
};
/**
@@ -51,12 +56,26 @@ static bool log_(private_sys_logger_t *this, debug_t group, level_t level,
{
if (level <= this->levels[group])
{
- char buffer[8192];
+ char buffer[8192], namestr[128] = "";
char *current = buffer, *next;
/* write in memory buffer first */
vsnprintf(buffer, sizeof(buffer), format, args);
+ if (this->ike_name && ike_sa)
+ {
+ if (ike_sa->get_peer_cfg(ike_sa))
+ {
+ snprintf(namestr, sizeof(namestr), " <%s|%d>",
+ ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa));
+ }
+ else
+ {
+ snprintf(namestr, sizeof(namestr), " <%d>",
+ ike_sa->get_unique_id(ike_sa));
+ }
+ }
+
/* do a syslog with every line */
while (current)
{
@@ -65,8 +84,8 @@ static bool log_(private_sys_logger_t *this, debug_t group, level_t level,
{
*(next++) = '\0';
}
- syslog(this->facility|LOG_INFO, "%.2d[%N] %s\n",
- thread, debug_names, group, current);
+ syslog(this->facility|LOG_INFO, "%.2d[%N]%s %s\n",
+ thread, debug_names, group, namestr, current);
current = next;
}
}
@@ -104,7 +123,7 @@ static void destroy(private_sys_logger_t *this)
/*
* Described in header.
*/
-sys_logger_t *sys_logger_create(int facility)
+sys_logger_t *sys_logger_create(int facility, bool ike_name)
{
private_sys_logger_t *this = malloc_thing(private_sys_logger_t);
@@ -116,6 +135,7 @@ sys_logger_t *sys_logger_create(int facility)
/* private variables */
this->facility = facility;
+ this->ike_name = ike_name;
set_level(this, DBG_ANY, LEVEL_SILENT);
return &this->public;
diff --git a/src/libcharon/bus/listeners/sys_logger.h b/src/libcharon/bus/listeners/sys_logger.h
index 58d4de529..d83715a6a 100644
--- a/src/libcharon/bus/listeners/sys_logger.h
+++ b/src/libcharon/bus/listeners/sys_logger.h
@@ -53,8 +53,9 @@ struct sys_logger_t {
* Constructor to create a sys_logger_t object.
*
* @param facility syslog facility to use
+ * @param ike_name TRUE to prefix the name of the IKE_SA
* @return sys_logger_t object
*/
-sys_logger_t *sys_logger_create(int facility);
+sys_logger_t *sys_logger_create(int facility, bool ike_name);
#endif /** SYS_LOGGER_H_ @}*/
diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c
index 70f38b285..1cdfd5949 100644
--- a/src/libcharon/config/child_cfg.c
+++ b/src/libcharon/config/child_cfg.c
@@ -27,15 +27,6 @@ ENUM(action_names, ACTION_NONE, ACTION_RESTART,
"restart",
);
-ENUM_BEGIN(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_NONE,
- "IPCOMP_NONE");
-ENUM_NEXT(ipcomp_transform_names, IPCOMP_OUI, IPCOMP_LZJH, IPCOMP_NONE,
- "IPCOMP_OUI",
- "IPCOMP_DEFLATE",
- "IPCOMP_LZS",
- "IPCOMP_LZJH");
-ENUM_END(ipcomp_transform_names, IPCOMP_LZJH);
-
typedef struct private_child_cfg_t private_child_cfg_t;
/**
diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h
index d34835ead..1e6fe3fe9 100644
--- a/src/libcharon/config/child_cfg.h
+++ b/src/libcharon/config/child_cfg.h
@@ -24,9 +24,6 @@
#define CHILD_CFG_H_
typedef enum action_t action_t;
-typedef enum ipcomp_transform_t ipcomp_transform_t;
-typedef struct lifetime_cfg_t lifetime_cfg_t;
-typedef struct mark_t mark_t;
typedef struct child_cfg_t child_cfg_t;
#include <library.h>
@@ -52,48 +49,6 @@ enum action_t {
extern enum_name_t *action_names;
/**
- * IPComp transform IDs, as in RFC 4306
- */
-enum ipcomp_transform_t {
- IPCOMP_NONE = 241,
- IPCOMP_OUI = 1,
- IPCOMP_DEFLATE = 2,
- IPCOMP_LZS = 3,
- IPCOMP_LZJH = 4,
-};
-
-/**
- * enum strings for ipcomp_transform_t.
- */
-extern enum_name_t *ipcomp_transform_names;
-
-/**
- * A lifetime_cfg_t defines the lifetime limits of a CHILD_SA.
- *
- * Set any of these values to 0 to ignore.
- */
-struct lifetime_cfg_t {
- struct {
- /** Limit before the CHILD_SA gets invalid. */
- u_int64_t life;
- /** Limit before the CHILD_SA gets rekeyed. */
- u_int64_t rekey;
- /** The range of a random value subtracted from rekey. */
- u_int64_t jitter;
- } time, bytes, packets;
-};
-
-/**
- * A mark_t defines an optional mark in a CHILD_SA.
- */
-struct mark_t {
- /** Mark value */
- u_int32_t value;
- /** Mark mask */
- u_int32_t mask;
-};
-
-/**
* A child_cfg_t defines the config template for a CHILD_SA.
*
* After creation, proposals and traffic selectors may be added to the config.
@@ -238,7 +193,7 @@ struct child_cfg_t {
* Check whether IPComp should be used, if the other peer supports it.
*
* @return TRUE, if IPComp should be used
- * FALSE, otherwise
+ * FALSE, otherwise
*/
bool (*use_ipcomp)(child_cfg_t *this);
@@ -259,7 +214,7 @@ struct child_cfg_t {
/**
* Optional mark for CHILD_SA
*
- * @param inbound TRUE for inbound, FALSE for outbound
+ * @param inbound TRUE for inbound, FALSE for outbound
* @return mark
*/
mark_t (*get_mark)(child_cfg_t *this, bool inbound);
@@ -277,7 +232,7 @@ struct child_cfg_t {
* Check whether IPsec transport SA should be set up in proxy mode
*
* @return TRUE, if proxy mode should be used
- * FALSE, otherwise
+ * FALSE, otherwise
*/
bool (*use_proxy_mode)(child_cfg_t *this);
@@ -285,7 +240,7 @@ struct child_cfg_t {
* Check whether IPsec policies should be installed in the kernel
*
* @return TRUE, if IPsec kernel policies should be installed
- * FALSE, otherwise
+ * FALSE, otherwise
*/
bool (*install_policy)(child_cfg_t *this);
diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c
index e86393028..5b8294599 100644
--- a/src/libcharon/config/proposal.c
+++ b/src/libcharon/config/proposal.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008-2009 Tobias Brunner
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2010 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -87,6 +87,11 @@ struct private_proposal_t {
* senders SPI
*/
u_int64_t spi;
+
+ /**
+ * Proposal number
+ */
+ u_int number;
};
/**
@@ -117,11 +122,9 @@ static void add_algo(linked_list_t *list, u_int16_t algo, u_int16_t key_size)
list->insert_last(list, (void*)algo_key);
}
-/**
- * Implements proposal_t.add_algorithm
- */
-static void add_algorithm(private_proposal_t *this, transform_type_t type,
- u_int16_t algo, u_int16_t key_size)
+METHOD(proposal_t, add_algorithm, void,
+ private_proposal_t *this, transform_type_t type,
+ u_int16_t algo, u_int16_t key_size)
{
switch (type)
{
@@ -160,11 +163,8 @@ static bool alg_filter(void *null, algorithm_t **in, u_int16_t *alg,
return TRUE;
}
-/**
- * Implements proposal_t.create_enumerator.
- */
-static enumerator_t *create_enumerator(private_proposal_t *this,
- transform_type_t type)
+METHOD(proposal_t, create_enumerator, enumerator_t*,
+ private_proposal_t *this, transform_type_t type)
{
linked_list_t *list;
@@ -192,11 +192,9 @@ static enumerator_t *create_enumerator(private_proposal_t *this,
(void*)alg_filter, NULL, NULL);
}
-/**
- * Implements proposal_t.get_algorithm.
- */
-static bool get_algorithm(private_proposal_t *this, transform_type_t type,
- u_int16_t *alg, u_int16_t *key_size)
+METHOD(proposal_t, get_algorithm, bool,
+ private_proposal_t *this, transform_type_t type,
+ u_int16_t *alg, u_int16_t *key_size)
{
enumerator_t *enumerator;
bool found = FALSE;
@@ -210,10 +208,8 @@ static bool get_algorithm(private_proposal_t *this, transform_type_t type,
return found;
}
-/**
- * Implements proposal_t.has_dh_group
- */
-static bool has_dh_group(private_proposal_t *this, diffie_hellman_group_t group)
+METHOD(proposal_t, has_dh_group, bool,
+ private_proposal_t *this, diffie_hellman_group_t group)
{
bool result = FALSE;
@@ -240,10 +236,8 @@ static bool has_dh_group(private_proposal_t *this, diffie_hellman_group_t group)
return result;
}
-/**
- * Implementation of proposal_t.strip_dh.
- */
-static void strip_dh(private_proposal_t *this)
+METHOD(proposal_t, strip_dh, void,
+ private_proposal_t *this)
{
algorithm_t *alg;
@@ -254,28 +248,6 @@ static void strip_dh(private_proposal_t *this)
}
/**
- * Returns true if the given alg is an authenticated encryption algorithm
- */
-static bool is_authenticated_encryption(u_int16_t alg)
-{
- switch(alg)
- {
- case ENCR_AES_CCM_ICV8:
- case ENCR_AES_CCM_ICV12:
- case ENCR_AES_CCM_ICV16:
- case ENCR_AES_GCM_ICV8:
- case ENCR_AES_GCM_ICV12:
- case ENCR_AES_GCM_ICV16:
- case ENCR_CAMELLIA_CCM_ICV8:
- case ENCR_CAMELLIA_CCM_ICV12:
- case ENCR_CAMELLIA_CCM_ICV16:
- case ENCR_NULL_AUTH_AES_GMAC:
- return TRUE;
- }
- return FALSE;
-}
-
-/**
* Find a matching alg/keysize in two linked lists
*/
static bool select_algo(linked_list_t *first, linked_list_t *second, bool priv,
@@ -326,12 +298,10 @@ static bool select_algo(linked_list_t *first, linked_list_t *second, bool priv,
return FALSE;
}
-/**
- * Implements proposal_t.select.
- */
-static proposal_t *select_proposal(private_proposal_t *this,
- private_proposal_t *other, bool private)
+METHOD(proposal_t, select_proposal, proposal_t*,
+ private_proposal_t *this, proposal_t *other_pub, bool private)
{
+ private_proposal_t *other = (private_proposal_t*)other_pub;
proposal_t *selected;
u_int16_t algo;
size_t key_size;
@@ -346,7 +316,7 @@ static proposal_t *select_proposal(private_proposal_t *this,
return NULL;
}
- selected = proposal_create(this->protocol);
+ selected = proposal_create(this->protocol, other->number);
/* select encryption algorithm */
if (select_algo(this->encryption_algos, other->encryption_algos, private,
@@ -366,7 +336,7 @@ static proposal_t *select_proposal(private_proposal_t *this,
return NULL;
}
/* select integrity algorithm */
- if (!is_authenticated_encryption(algo))
+ if (!encryption_algorithm_is_aead(algo))
{
if (select_algo(this->integrity_algos, other->integrity_algos, private,
&add, &algo, &key_size))
@@ -442,26 +412,20 @@ static proposal_t *select_proposal(private_proposal_t *this,
return selected;
}
-/**
- * Implements proposal_t.get_protocols.
- */
-static protocol_id_t get_protocol(private_proposal_t *this)
+METHOD(proposal_t, get_protocol, protocol_id_t,
+ private_proposal_t *this)
{
return this->protocol;
}
-/**
- * Implements proposal_t.set_spi.
- */
-static void set_spi(private_proposal_t *this, u_int64_t spi)
+METHOD(proposal_t, set_spi, void,
+ private_proposal_t *this, u_int64_t spi)
{
this->spi = spi;
}
-/**
- * Implements proposal_t.get_spi.
- */
-static u_int64_t get_spi(private_proposal_t *this)
+METHOD(proposal_t, get_spi, u_int64_t,
+ private_proposal_t *this)
{
return this->spi;
}
@@ -514,19 +478,21 @@ static bool algo_list_equals(linked_list_t *l1, linked_list_t *l2)
return equals;
}
-/**
- * Implementation of proposal_t.equals.
- */
-static bool equals(private_proposal_t *this, private_proposal_t *other)
+METHOD(proposal_t, get_number, u_int,
+ private_proposal_t *this)
+{
+ return this->number;
+}
+
+METHOD(proposal_t, equals, bool,
+ private_proposal_t *this, proposal_t *other_pub)
{
+ private_proposal_t *other = (private_proposal_t*)other_pub;
+
if (this == other)
{
return TRUE;
}
- if (this->public.equals != other->public.equals)
- {
- return FALSE;
- }
return (
algo_list_equals(this->encryption_algos, other->encryption_algos) &&
algo_list_equals(this->integrity_algos, other->integrity_algos) &&
@@ -535,13 +501,12 @@ static bool equals(private_proposal_t *this, private_proposal_t *other)
algo_list_equals(this->esns, other->esns));
}
-/**
- * Implements proposal_t.clone
- */
-static proposal_t *clone_(private_proposal_t *this)
+METHOD(proposal_t, clone_, proposal_t*,
+ private_proposal_t *this)
{
- private_proposal_t *clone = (private_proposal_t*)proposal_create(this->protocol);
+ private_proposal_t *clone;
+ clone = (private_proposal_t*)proposal_create(this->protocol, 0);
clone_algo_list(this->encryption_algos, clone->encryption_algos);
clone_algo_list(this->integrity_algos, clone->integrity_algos);
clone_algo_list(this->prf_algos, clone->prf_algos);
@@ -549,6 +514,7 @@ static proposal_t *clone_(private_proposal_t *this)
clone_algo_list(this->esns, clone->esns);
clone->spi = this->spi;
+ clone->number = this->number;
return &clone->public;
}
@@ -565,7 +531,7 @@ static void check_proposal(private_proposal_t *this)
e = this->encryption_algos->create_enumerator(this->encryption_algos);
while (e->enumerate(e, &alg))
{
- if (!is_authenticated_encryption(alg->algorithm))
+ if (!encryption_algorithm_is_aead(alg->algorithm))
{
all_aead = FALSE;
break;
@@ -623,6 +589,9 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
case AUTH_AES_XCBC_96:
prf = PRF_AES128_XCBC;
break;
+ case AUTH_CAMELLIA_XCBC_96:
+ prf = PRF_CAMELLIA128_XCBC;
+ break;
default:
prf = PRF_UNDEFINED;
}
@@ -715,10 +684,8 @@ int proposal_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
return written;
}
-/**
- * Implements proposal_t.destroy.
- */
-static void destroy(private_proposal_t *this)
+METHOD(proposal_t, destroy, void,
+ private_proposal_t *this)
{
this->encryption_algos->destroy_function(this->encryption_algos, free);
this->integrity_algos->destroy_function(this->integrity_algos, free);
@@ -731,31 +698,34 @@ static void destroy(private_proposal_t *this)
/*
* Describtion in header-file
*/
-proposal_t *proposal_create(protocol_id_t protocol)
+proposal_t *proposal_create(protocol_id_t protocol, u_int number)
{
- private_proposal_t *this = malloc_thing(private_proposal_t);
-
- this->public.add_algorithm = (void (*)(proposal_t*,transform_type_t,u_int16_t,u_int16_t))add_algorithm;
- this->public.create_enumerator = (enumerator_t* (*)(proposal_t*,transform_type_t))create_enumerator;
- this->public.get_algorithm = (bool (*)(proposal_t*,transform_type_t,u_int16_t*,u_int16_t*))get_algorithm;
- this->public.has_dh_group = (bool (*)(proposal_t*,diffie_hellman_group_t))has_dh_group;
- this->public.strip_dh = (void(*)(proposal_t*))strip_dh;
- this->public.select = (proposal_t* (*)(proposal_t*,proposal_t*,bool))select_proposal;
- this->public.get_protocol = (protocol_id_t(*)(proposal_t*))get_protocol;
- this->public.set_spi = (void(*)(proposal_t*,u_int64_t))set_spi;
- this->public.get_spi = (u_int64_t(*)(proposal_t*))get_spi;
- this->public.equals = (bool(*)(proposal_t*, proposal_t *other))equals;
- this->public.clone = (proposal_t*(*)(proposal_t*))clone_;
- this->public.destroy = (void(*)(proposal_t*))destroy;
-
- this->spi = 0;
- this->protocol = protocol;
-
- this->encryption_algos = linked_list_create();
- this->integrity_algos = linked_list_create();
- this->prf_algos = linked_list_create();
- this->dh_groups = linked_list_create();
- this->esns = linked_list_create();
+ private_proposal_t *this;
+
+ INIT(this,
+ .public = {
+ .add_algorithm = _add_algorithm,
+ .create_enumerator = _create_enumerator,
+ .get_algorithm = _get_algorithm,
+ .has_dh_group = _has_dh_group,
+ .strip_dh = _strip_dh,
+ .select = _select_proposal,
+ .get_protocol = _get_protocol,
+ .set_spi = _set_spi,
+ .get_spi = _get_spi,
+ .get_number = _get_number,
+ .equals = _equals,
+ .clone = _clone_,
+ .destroy = _destroy,
+ },
+ .protocol = protocol,
+ .number = number,
+ .encryption_algos = linked_list_create(),
+ .integrity_algos = linked_list_create(),
+ .prf_algos = linked_list_create(),
+ .dh_groups = linked_list_create(),
+ .esns = linked_list_create(),
+ );
return &this->public;
}
@@ -777,19 +747,24 @@ static void proposal_add_supported_ike(private_proposal_t *this)
switch (encryption)
{
case ENCR_AES_CBC:
- /* we assume that we support all AES sizes */
- add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128);
- add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192);
- add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256);
- break;
- case ENCR_3DES:
case ENCR_AES_CTR:
+ case ENCR_CAMELLIA_CBC:
+ case ENCR_CAMELLIA_CTR:
case ENCR_AES_CCM_ICV8:
case ENCR_AES_CCM_ICV12:
case ENCR_AES_CCM_ICV16:
case ENCR_AES_GCM_ICV8:
case ENCR_AES_GCM_ICV12:
case ENCR_AES_GCM_ICV16:
+ case ENCR_CAMELLIA_CCM_ICV8:
+ case ENCR_CAMELLIA_CCM_ICV12:
+ case ENCR_CAMELLIA_CCM_ICV16:
+ /* we assume that we support all AES/Camellia sizes */
+ add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 128);
+ add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 192);
+ add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 256);
+ break;
+ case ENCR_3DES:
add_algorithm(this, ENCRYPTION_ALGORITHM, encryption, 0);
break;
case ENCR_DES:
@@ -877,7 +852,7 @@ static void proposal_add_supported_ike(private_proposal_t *this)
*/
proposal_t *proposal_create_default(protocol_id_t protocol)
{
- private_proposal_t *this = (private_proposal_t*)proposal_create(protocol);
+ private_proposal_t *this = (private_proposal_t*)proposal_create(protocol, 0);
switch (protocol)
{
@@ -912,7 +887,7 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
*/
proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs)
{
- private_proposal_t *this = (private_proposal_t*)proposal_create(protocol);
+ private_proposal_t *this = (private_proposal_t*)proposal_create(protocol, 0);
chunk_t string = {(void*)algs, strlen(algs)};
chunk_t alg;
status_t status = SUCCESS;
diff --git a/src/libcharon/config/proposal.h b/src/libcharon/config/proposal.h
index 30f63b80d..97af5b60b 100644
--- a/src/libcharon/config/proposal.h
+++ b/src/libcharon/config/proposal.h
@@ -161,6 +161,13 @@ struct proposal_t {
void (*set_spi) (proposal_t *this, u_int64_t spi);
/**
+ * Get the proposal number, as encoded in SA payload
+ *
+ * @return proposal number
+ */
+ u_int (*get_number)(proposal_t *this);
+
+ /**
* Check for the eqality of two proposals.
*
* @param other other proposal to check for equality
@@ -185,9 +192,10 @@ struct proposal_t {
* Create a child proposal for AH, ESP or IKE.
*
* @param protocol protocol, such as PROTO_ESP
+ * @param number proposal number, as encoded in SA payload
* @return proposal_t object
*/
-proposal_t *proposal_create(protocol_id_t protocol);
+proposal_t *proposal_create(protocol_id_t protocol, u_int number);
/**
* Create a default proposal if nothing further specified.
diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c
index c0227027c..4b8e1fadd 100644
--- a/src/libcharon/daemon.c
+++ b/src/libcharon/daemon.c
@@ -33,6 +33,7 @@
#include <library.h>
#include <config/proposal.h>
+#include <kernel/kernel_handler.h>
#ifndef LOG_AUTHPRIV /* not defined on OpenSolaris */
#define LOG_AUTHPRIV LOG_AUTH
@@ -50,6 +51,11 @@ struct private_daemon_t {
daemon_t public;
/**
+ * Handler for kernel events
+ */
+ kernel_handler_t *kernel_handler;
+
+ /**
* capabilities to keep
*/
#ifdef CAPABILITIES_LIBCAP
@@ -94,10 +100,8 @@ static void dbg_bus(debug_t group, level_t level, char *fmt, ...)
static void destroy(private_daemon_t *this)
{
/* terminate all idle threads */
- if (this->public.processor)
- {
- this->public.processor->set_threads(this->public.processor, 0);
- }
+ lib->processor->set_threads(lib->processor, 0);
+
/* close all IKE_SAs */
if (this->public.ike_sa_manager)
{
@@ -110,21 +114,19 @@ static void destroy(private_daemon_t *this)
#ifdef CAPABILITIES_LIBCAP
cap_free(this->caps);
#endif /* CAPABILITIES_LIBCAP */
+ DESTROY_IF(this->kernel_handler);
DESTROY_IF(this->public.traps);
DESTROY_IF(this->public.ike_sa_manager);
- DESTROY_IF(this->public.kernel_interface);
- DESTROY_IF(this->public.scheduler);
DESTROY_IF(this->public.controller);
DESTROY_IF(this->public.eap);
DESTROY_IF(this->public.sim);
+ DESTROY_IF(this->public.tnccs);
#ifdef ME
DESTROY_IF(this->public.connect_manager);
DESTROY_IF(this->public.mediation_manager);
#endif /* ME */
DESTROY_IF(this->public.backends);
DESTROY_IF(this->public.socket);
- /* wait until all threads are gone */
- DESTROY_IF(this->public.processor);
/* rehook library logging, shutdown logging */
dbg = dbg_old;
@@ -176,7 +178,7 @@ METHOD(daemon_t, start, void,
private_daemon_t *this)
{
/* start the engine, go multithreaded */
- charon->processor->set_threads(charon->processor,
+ lib->processor->set_threads(lib->processor,
lib->settings->get_int(lib->settings, "charon.threads",
DEFAULT_THREADS));
}
@@ -213,7 +215,7 @@ static void initialize_loggers(private_daemon_t *this, bool use_stderr,
int loggers_defined = 0;
debug_t group;
level_t def;
- bool append;
+ bool append, ike_name;
FILE *file;
/* setup sysloggers */
@@ -222,13 +224,16 @@ static void initialize_loggers(private_daemon_t *this, bool use_stderr,
while (enumerator->enumerate(enumerator, &facility))
{
loggers_defined++;
+
+ ike_name = lib->settings->get_bool(lib->settings,
+ "charon.syslog.%s.ike_name", FALSE, facility);
if (streq(facility, "daemon"))
{
- sys_logger = sys_logger_create(LOG_DAEMON);
+ sys_logger = sys_logger_create(LOG_DAEMON, ike_name);
}
else if (streq(facility, "auth"))
{
- sys_logger = sys_logger_create(LOG_AUTHPRIV);
+ sys_logger = sys_logger_create(LOG_AUTHPRIV, ike_name);
}
else
{
@@ -282,7 +287,9 @@ static void initialize_loggers(private_daemon_t *this, bool use_stderr,
}
file_logger = file_logger_create(file,
lib->settings->get_str(lib->settings,
- "charon.filelog.%s.time_format", NULL, filename));
+ "charon.filelog.%s.time_format", NULL, filename),
+ lib->settings->get_bool(lib->settings,
+ "charon.filelog.%s.ike_name", FALSE, filename));
def = lib->settings->get_int(lib->settings,
"charon.filelog.%s.default", 1, filename);
for (group = 0; group < DBG_MAX; group++)
@@ -303,12 +310,12 @@ static void initialize_loggers(private_daemon_t *this, bool use_stderr,
if (!loggers_defined)
{
/* set up default stdout file_logger */
- file_logger = file_logger_create(stdout, NULL);
+ file_logger = file_logger_create(stdout, NULL, FALSE);
this->public.bus->add_listener(this->public.bus, &file_logger->listener);
this->public.file_loggers->insert_last(this->public.file_loggers,
file_logger);
/* set up default daemon sys_logger */
- sys_logger = sys_logger_create(LOG_DAEMON);
+ sys_logger = sys_logger_create(LOG_DAEMON, FALSE);
this->public.bus->add_listener(this->public.bus, &sys_logger->listener);
this->public.sys_loggers->insert_last(this->public.sys_loggers,
sys_logger);
@@ -322,7 +329,7 @@ static void initialize_loggers(private_daemon_t *this, bool use_stderr,
}
/* set up default auth sys_logger */
- sys_logger = sys_logger_create(LOG_AUTHPRIV);
+ sys_logger = sys_logger_create(LOG_AUTHPRIV, FALSE);
this->public.bus->add_listener(this->public.bus, &sys_logger->listener);
this->public.sys_loggers->insert_last(this->public.sys_loggers,
sys_logger);
@@ -356,15 +363,14 @@ METHOD(daemon_t, initialize, bool,
}
/* load secrets, ca certificates and crls */
- this->public.processor = processor_create();
- this->public.scheduler = scheduler_create();
this->public.controller = controller_create();
this->public.eap = eap_manager_create();
this->public.sim = sim_manager_create();
+ this->public.tnccs = tnccs_manager_create();
this->public.backends = backend_manager_create();
- this->public.kernel_interface = kernel_interface_create();
this->public.socket = socket_manager_create();
this->public.traps = trap_manager_create();
+ this->kernel_handler = kernel_handler_create();
/* load plugins, further infrastructure may need it */
if (!lib->plugins->load(lib->plugins, NULL,
diff --git a/src/libcharon/daemon.h b/src/libcharon/daemon.h
index 38f0256e7..c0c834b43 100644
--- a/src/libcharon/daemon.h
+++ b/src/libcharon/daemon.h
@@ -37,7 +37,7 @@
* @defgroup payloads payloads
* @ingroup encoding
*
- * @defgroup kernel kernel
+ * @defgroup ckernel kernel
* @ingroup libcharon
*
* @defgroup network network
@@ -46,11 +46,11 @@
* @defgroup cplugins plugins
* @ingroup libcharon
*
- * @defgroup processing processing
+ * @defgroup cprocessing processing
* @ingroup libcharon
*
- * @defgroup jobs jobs
- * @ingroup processing
+ * @defgroup cjobs jobs
+ * @ingroup cprocessing
*
* @defgroup sa sa
* @ingroup libcharon
@@ -140,9 +140,6 @@ typedef struct daemon_t daemon_t;
#include <network/sender.h>
#include <network/receiver.h>
#include <network/socket_manager.h>
-#include <processing/scheduler.h>
-#include <processing/processor.h>
-#include <kernel/kernel_interface.h>
#include <control/controller.h>
#include <bus/bus.h>
#include <bus/listeners/file_logger.h>
@@ -152,6 +149,7 @@ typedef struct daemon_t daemon_t;
#include <config/backend_manager.h>
#include <sa/authenticators/eap/eap_manager.h>
#include <sa/authenticators/eap/sim_manager.h>
+#include <tnccs/tnccs_manager.h>
#ifdef ME
#include <sa/connect_manager.h>
@@ -209,16 +207,6 @@ struct daemon_t {
receiver_t *receiver;
/**
- * The Scheduler-Thread.
- */
- scheduler_t *scheduler;
-
- /**
- * Job processing using a thread pool.
- */
- processor_t *processor;
-
- /**
* The signaling bus.
*/
bus_t *bus;
@@ -234,11 +222,6 @@ struct daemon_t {
linked_list_t *sys_loggers;
/**
- * Kernel Interface to communicate with kernel
- */
- kernel_interface_t *kernel_interface;
-
- /**
* Controller to control the daemon
*/
controller_t *controller;
@@ -253,6 +236,11 @@ struct daemon_t {
*/
sim_manager_t *sim;
+ /**
+ * TNCCS manager to maintain registered TNCCS protocols
+ */
+ tnccs_manager_t *tnccs;
+
#ifdef ME
/**
* Connect manager
diff --git a/src/libcharon/encoding/generator.c b/src/libcharon/encoding/generator.c
index 6485da492..224f76fce 100644
--- a/src/libcharon/encoding/generator.c
+++ b/src/libcharon/encoding/generator.c
@@ -42,6 +42,16 @@
#include <encoding/payloads/configuration_attribute.h>
#include <encoding/payloads/eap_payload.h>
+/**
+ * Generating is done in a data buffer.
+ * This is the start size of this buffer in bytes.
+ */
+#define GENERATOR_DATA_BUFFER_SIZE 500
+
+/**
+ * Number of bytes to increase the buffer, if it is too small.
+ */
+#define GENERATOR_DATA_BUFFER_INCREASE_VALUE 500
typedef struct private_generator_t private_generator_t;
@@ -453,36 +463,19 @@ static void generate_from_chunk(private_generator_t *this, u_int32_t offset)
write_bytes_to_buffer(this, value->ptr, value->len);
}
-/**
- * Implementation of private_generator_t.write_to_chunk.
- */
-static void write_to_chunk(private_generator_t *this,chunk_t *data)
+METHOD(generator_t, get_chunk, chunk_t,
+ private_generator_t *this, u_int32_t **lenpos)
{
- int data_length = get_length(this);
- u_int32_t header_length_field = data_length;
-
- /* write length into header length field */
- if (this->header_length_position_offset > 0)
- {
- u_int32_t val = htonl(header_length_field);
- write_bytes_to_buffer_at_offset(this, &val, sizeof(u_int32_t),
- this->header_length_position_offset);
- }
+ chunk_t data;
- if (this->current_bit > 0)
- {
- data_length++;
- }
- *data = chunk_alloc(data_length);
- memcpy(data->ptr, this->buffer, data_length);
-
- DBG3(DBG_ENC, "generated data of this generator %B", data);
+ *lenpos = (u_int32_t*)(this->buffer + this->header_length_position_offset);
+ data = chunk_create(this->buffer, get_length(this));
+ DBG3(DBG_ENC, "generated data of this generator %B", &data);
+ return data;
}
-/**
- * Implementation of private_generator_t.generate_payload.
- */
-static void generate_payload (private_generator_t *this,payload_t *payload)
+METHOD(generator_t, generate_payload, void,
+ private_generator_t *this,payload_t *payload)
{
int i, offset_start;
size_t rule_count;
@@ -846,14 +839,11 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
this->out_position - this->buffer - offset_start);
}
-/**
- * Implementation of generator_t.destroy.
- */
-static status_t destroy(private_generator_t *this)
+METHOD(generator_t, destroy, void,
+ private_generator_t *this)
{
free(this->buffer);
free(this);
- return SUCCESS;
}
/*
@@ -863,26 +853,18 @@ generator_t *generator_create()
{
private_generator_t *this;
- this = malloc_thing(private_generator_t);
-
- /* initiate public functions */
- this->public.generate_payload = (void(*)(generator_t*, payload_t *))generate_payload;
- this->public.destroy = (void(*)(generator_t*)) destroy;
- this->public.write_to_chunk = (void (*) (generator_t *,chunk_t *))write_to_chunk;
+ INIT(this,
+ .public = {
+ .get_chunk = _get_chunk,
+ .generate_payload = _generate_payload,
+ .destroy = _destroy,
+ },
+ .buffer = malloc(GENERATOR_DATA_BUFFER_SIZE),
+ );
- /* allocate memory for buffer */
- this->buffer = malloc(GENERATOR_DATA_BUFFER_SIZE);
-
- /* initiate private variables */
this->out_position = this->buffer;
this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE;
- this->data_struct = NULL;
- this->current_bit = 0;
- this->last_payload_length_position_offset = 0;
- this->header_length_position_offset = 0;
- this->attribute_format = FALSE;
- this->attribute_length = 0;
-
- return &(this->public);
+
+ return &this->public;
}
diff --git a/src/libcharon/encoding/generator.h b/src/libcharon/encoding/generator.h
index 2221c84af..fe561fdfd 100644
--- a/src/libcharon/encoding/generator.h
+++ b/src/libcharon/encoding/generator.h
@@ -29,24 +29,12 @@ typedef struct generator_t generator_t;
#include <encoding/payloads/payload.h>
/**
- * Generating is done in a data buffer.
- * This is the start size of this buffer in bytes.
- */
-#define GENERATOR_DATA_BUFFER_SIZE 500
-
-/**
- * Number of bytes to increase the buffer, if it is too small.
- */
-#define GENERATOR_DATA_BUFFER_INCREASE_VALUE 500
-
-
-/**
* A generator_t class used to generate IKEv2 payloads.
*
* After creation, multiple payloads can be generated with the generate_payload
* method. The generated bytes are appended. After all payloads are added,
* the write_to_chunk method writes out all generated data since
- * the creation of the generator. After that, the generator must be destroyed.
+ * the creation of the generator.
* The generater uses a set of encoding rules, which it can get from
* the supplied payload. With this rules, the generater can generate
* the payload and all substructures automatically.
@@ -56,18 +44,20 @@ struct generator_t {
/**
* Generates a specific payload from given payload object.
*
- * Remember: Header and substructures are also handled as payloads.
- *
* @param payload interface payload_t implementing object
*/
void (*generate_payload) (generator_t *this,payload_t *payload);
/**
- * Writes all generated data of the generator to a chunk.
+ * Return a chunk for the currently generated data.
+ *
+ * The returned length pointer must be filled in with the length of
+ * the generated chunk (in network order).
*
- * @param data chunk to write the data to
+ * @param lenpos receives a pointer to fill in length value
+ * @param return chunk to internal buffer.
*/
- void (*write_to_chunk) (generator_t *this,chunk_t *data);
+ chunk_t (*get_chunk) (generator_t *this, u_int32_t **lenpos);
/**
* Destroys a generator_t object.
diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c
index ee49a6686..d41ad4697 100644
--- a/src/libcharon/encoding/message.c
+++ b/src/libcharon/encoding/message.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006-2007 Tobias Brunner
- * Copyright (C) 2005-2009 Martin Willi
+ * Copyright (C) 2005-2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -43,111 +44,61 @@
*/
#define MAX_DELETE_PAYLOADS 20
-
-typedef struct payload_rule_t payload_rule_t;
-
/**
* A payload rule defines the rules for a payload
* in a specific message rule. It defines if and how
* many times a payload must/can occur in a message
* and if it must be encrypted.
*/
-struct payload_rule_t {
- /**
- * Payload type.
- */
- payload_type_t payload_type;
-
- /**
- * Minimal occurence of this payload.
- */
- size_t min_occurence;
-
- /**
- * Max occurence of this payload.
- */
- size_t max_occurence;
-
- /**
- * TRUE if payload must be encrypted
- */
- bool encrypted;
-
- /**
- * If this payload occurs, the message rule is
- * fullfilled in any case. This applies e.g. to
- * notify_payloads.
- */
- bool sufficient;
-};
-
-typedef struct payload_order_t payload_order_t;
+typedef struct {
+ /* Payload type */
+ payload_type_t type;
+ /* Minimal occurence of this payload. */
+ size_t min_occurence;
+ /* Max occurence of this payload. */
+ size_t max_occurence;
+ /* TRUE if payload must be encrypted */
+ bool encrypted;
+ /* If payload occurs, the message rule is fullfilled */
+ bool sufficient;
+} payload_rule_t;
/**
* payload ordering structure allows us to reorder payloads according to RFC.
*/
-struct payload_order_t {
-
- /**
- * payload type
- */
+typedef struct {
+ /** payload type */
payload_type_t type;
-
- /**
- * notify type, if payload == NOTIFY
- */
+ /** notify type, if payload == NOTIFY */
notify_type_t notify;
-};
-
-
-typedef struct message_rule_t message_rule_t;
+} payload_order_t;
/**
* A message rule defines the kind of a message,
* if it has encrypted contents and a list
* of payload ordering rules and payload parsing rules.
*/
-struct message_rule_t {
- /**
- * Type of message.
- */
+typedef struct {
+ /** Type of message. */
exchange_type_t exchange_type;
-
- /**
- * Is message a request or response.
- */
+ /** Is message a request or response. */
bool is_request;
-
- /**
- * Message contains encrypted content.
- */
- bool encrypted_content;
-
- /**
- * Number of payload rules which will follow
- */
- int payload_rule_count;
-
- /**
- * Pointer to first payload rule
- */
- payload_rule_t *payload_rules;
-
- /**
- * Number of payload order rules
- */
- int payload_order_count;
-
- /**
- * payload ordering rules
- */
- payload_order_t *payload_order;
-};
+ /** Message contains encrypted payloads. */
+ bool encrypted;
+ /** Number of payload rules which will follow */
+ int rule_count;
+ /** Pointer to first payload rule */
+ payload_rule_t *rules;
+ /** Number of payload order rules */
+ int order_count;
+ /** payload ordering rules */
+ payload_order_t *order;
+} message_rule_t;
/**
* Message rule for IKE_SA_INIT from initiator.
*/
-static payload_rule_t ike_sa_init_i_payload_rules[] = {
+static payload_rule_t ike_sa_init_i_rules[] = {
/* payload type min max encr suff */
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, FALSE, FALSE},
{SECURITY_ASSOCIATION, 1, 1, FALSE, FALSE},
@@ -159,7 +110,7 @@ static payload_rule_t ike_sa_init_i_payload_rules[] = {
/**
* payload order for IKE_SA_INIT initiator
*/
-static payload_order_t ike_sa_init_i_payload_order[] = {
+static payload_order_t ike_sa_init_i_order[] = {
/* payload type notify type */
{NOTIFY, COOKIE},
{SECURITY_ASSOCIATION, 0},
@@ -174,7 +125,7 @@ static payload_order_t ike_sa_init_i_payload_order[] = {
/**
* Message rule for IKE_SA_INIT from responder.
*/
-static payload_rule_t ike_sa_init_r_payload_rules[] = {
+static payload_rule_t ike_sa_init_r_rules[] = {
/* payload type min max encr suff */
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, FALSE, TRUE},
{SECURITY_ASSOCIATION, 1, 1, FALSE, FALSE},
@@ -186,7 +137,7 @@ static payload_rule_t ike_sa_init_r_payload_rules[] = {
/**
* payload order for IKE_SA_INIT responder
*/
-static payload_order_t ike_sa_init_r_payload_order[] = {
+static payload_order_t ike_sa_init_r_order[] = {
/* payload type notify type */
{SECURITY_ASSOCIATION, 0},
{KEY_EXCHANGE, 0},
@@ -202,7 +153,7 @@ static payload_order_t ike_sa_init_r_payload_order[] = {
/**
* Message rule for IKE_AUTH from initiator.
*/
-static payload_rule_t ike_auth_i_payload_rules[] = {
+static payload_rule_t ike_auth_i_rules[] = {
/* payload type min max encr suff */
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
{EXTENSIBLE_AUTHENTICATION, 0, 1, TRUE, TRUE},
@@ -227,7 +178,7 @@ static payload_rule_t ike_auth_i_payload_rules[] = {
/**
* payload order for IKE_AUTH initiator
*/
-static payload_order_t ike_auth_i_payload_order[] = {
+static payload_order_t ike_auth_i_order[] = {
/* payload type notify type */
{ID_INITIATOR, 0},
{CERTIFICATE, 0},
@@ -256,7 +207,7 @@ static payload_order_t ike_auth_i_payload_order[] = {
/**
* Message rule for IKE_AUTH from responder.
*/
-static payload_rule_t ike_auth_r_payload_rules[] = {
+static payload_rule_t ike_auth_r_rules[] = {
/* payload type min max encr suff */
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE},
{EXTENSIBLE_AUTHENTICATION, 0, 1, TRUE, TRUE},
@@ -273,7 +224,7 @@ static payload_rule_t ike_auth_r_payload_rules[] = {
/**
* payload order for IKE_AUTH responder
*/
-static payload_order_t ike_auth_r_payload_order[] = {
+static payload_order_t ike_auth_r_order[] = {
/* payload type notify type */
{ID_RESPONDER, 0},
{CERTIFICATE, 0},
@@ -299,7 +250,7 @@ static payload_order_t ike_auth_r_payload_order[] = {
/**
* Message rule for INFORMATIONAL from initiator.
*/
-static payload_rule_t informational_i_payload_rules[] = {
+static payload_rule_t informational_i_rules[] = {
/* payload type min max encr suff */
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
{CONFIGURATION, 0, 1, TRUE, FALSE},
@@ -310,7 +261,7 @@ static payload_rule_t informational_i_payload_rules[] = {
/**
* payload order for INFORMATIONAL initiator
*/
-static payload_order_t informational_i_payload_order[] = {
+static payload_order_t informational_i_order[] = {
/* payload type notify type */
{NOTIFY, UPDATE_SA_ADDRESSES},
{NOTIFY, NAT_DETECTION_SOURCE_IP},
@@ -324,7 +275,7 @@ static payload_order_t informational_i_payload_order[] = {
/**
* Message rule for INFORMATIONAL from responder.
*/
-static payload_rule_t informational_r_payload_rules[] = {
+static payload_rule_t informational_r_rules[] = {
/* payload type min max encr suff */
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
{CONFIGURATION, 0, 1, TRUE, FALSE},
@@ -335,7 +286,7 @@ static payload_rule_t informational_r_payload_rules[] = {
/**
* payload order for INFORMATIONAL responder
*/
-static payload_order_t informational_r_payload_order[] = {
+static payload_order_t informational_r_order[] = {
/* payload type notify type */
{NOTIFY, UPDATE_SA_ADDRESSES},
{NOTIFY, NAT_DETECTION_SOURCE_IP},
@@ -349,7 +300,7 @@ static payload_order_t informational_r_payload_order[] = {
/**
* Message rule for CREATE_CHILD_SA from initiator.
*/
-static payload_rule_t create_child_sa_i_payload_rules[] = {
+static payload_rule_t create_child_sa_i_rules[] = {
/* payload type min max encr suff */
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE},
{SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE},
@@ -364,7 +315,7 @@ static payload_rule_t create_child_sa_i_payload_rules[] = {
/**
* payload order for CREATE_CHILD_SA from initiator.
*/
-static payload_order_t create_child_sa_i_payload_order[] = {
+static payload_order_t create_child_sa_i_order[] = {
/* payload type notify type */
{NOTIFY, REKEY_SA},
{NOTIFY, IPCOMP_SUPPORTED},
@@ -382,7 +333,7 @@ static payload_order_t create_child_sa_i_payload_order[] = {
/**
* Message rule for CREATE_CHILD_SA from responder.
*/
-static payload_rule_t create_child_sa_r_payload_rules[] = {
+static payload_rule_t create_child_sa_r_rules[] = {
/* payload type min max encr suff */
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE},
{SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE},
@@ -397,7 +348,7 @@ static payload_rule_t create_child_sa_r_payload_rules[] = {
/**
* payload order for CREATE_CHILD_SA from responder.
*/
-static payload_order_t create_child_sa_r_payload_order[] = {
+static payload_order_t create_child_sa_r_order[] = {
/* payload type notify type */
{NOTIFY, IPCOMP_SUPPORTED},
{NOTIFY, USE_TRANSPORT_MODE},
@@ -416,7 +367,7 @@ static payload_order_t create_child_sa_r_payload_order[] = {
/**
* Message rule for ME_CONNECT from initiator.
*/
-static payload_rule_t me_connect_i_payload_rules[] = {
+static payload_rule_t me_connect_i_rules[] = {
/* payload type min max encr suff */
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE},
{ID_PEER, 1, 1, TRUE, FALSE},
@@ -426,7 +377,7 @@ static payload_rule_t me_connect_i_payload_rules[] = {
/**
* payload order for ME_CONNECT from initiator.
*/
-static payload_order_t me_connect_i_payload_order[] = {
+static payload_order_t me_connect_i_order[] = {
/* payload type notify type */
{NOTIFY, 0},
{ID_PEER, 0},
@@ -436,7 +387,7 @@ static payload_order_t me_connect_i_payload_order[] = {
/**
* Message rule for ME_CONNECT from responder.
*/
-static payload_rule_t me_connect_r_payload_rules[] = {
+static payload_rule_t me_connect_r_rules[] = {
/* payload type min max encr suff */
{NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE},
{VENDOR_ID, 0, 10, TRUE, FALSE}
@@ -445,7 +396,7 @@ static payload_rule_t me_connect_r_payload_rules[] = {
/**
* payload order for ME_CONNECT from responder.
*/
-static payload_order_t me_connect_r_payload_order[] = {
+static payload_order_t me_connect_r_order[] = {
/* payload type notify type */
{NOTIFY, 0},
{VENDOR_ID, 0},
@@ -457,65 +408,45 @@ static payload_order_t me_connect_r_payload_order[] = {
*/
static message_rule_t message_rules[] = {
{IKE_SA_INIT, TRUE, FALSE,
- (sizeof(ike_sa_init_i_payload_rules)/sizeof(payload_rule_t)),
- ike_sa_init_i_payload_rules,
- (sizeof(ike_sa_init_i_payload_order)/sizeof(payload_order_t)),
- ike_sa_init_i_payload_order,
+ countof(ike_sa_init_i_rules), ike_sa_init_i_rules,
+ countof(ike_sa_init_i_order), ike_sa_init_i_order,
},
{IKE_SA_INIT, FALSE, FALSE,
- (sizeof(ike_sa_init_r_payload_rules)/sizeof(payload_rule_t)),
- ike_sa_init_r_payload_rules,
- (sizeof(ike_sa_init_r_payload_order)/sizeof(payload_order_t)),
- ike_sa_init_r_payload_order,
+ countof(ike_sa_init_r_rules), ike_sa_init_r_rules,
+ countof(ike_sa_init_r_order), ike_sa_init_r_order,
},
{IKE_AUTH, TRUE, TRUE,
- (sizeof(ike_auth_i_payload_rules)/sizeof(payload_rule_t)),
- ike_auth_i_payload_rules,
- (sizeof(ike_auth_i_payload_order)/sizeof(payload_order_t)),
- ike_auth_i_payload_order,
+ countof(ike_auth_i_rules), ike_auth_i_rules,
+ countof(ike_auth_i_order), ike_auth_i_order,
},
{IKE_AUTH, FALSE, TRUE,
- (sizeof(ike_auth_r_payload_rules)/sizeof(payload_rule_t)),
- ike_auth_r_payload_rules,
- (sizeof(ike_auth_r_payload_order)/sizeof(payload_order_t)),
- ike_auth_r_payload_order,
+ countof(ike_auth_r_rules), ike_auth_r_rules,
+ countof(ike_auth_r_order), ike_auth_r_order,
},
{INFORMATIONAL, TRUE, TRUE,
- (sizeof(informational_i_payload_rules)/sizeof(payload_rule_t)),
- informational_i_payload_rules,
- (sizeof(informational_i_payload_order)/sizeof(payload_order_t)),
- informational_i_payload_order,
+ countof(informational_i_rules), informational_i_rules,
+ countof(informational_i_order), informational_i_order,
},
{INFORMATIONAL, FALSE, TRUE,
- (sizeof(informational_r_payload_rules)/sizeof(payload_rule_t)),
- informational_r_payload_rules,
- (sizeof(informational_r_payload_order)/sizeof(payload_order_t)),
- informational_r_payload_order,
+ countof(informational_r_rules), informational_r_rules,
+ countof(informational_r_order), informational_r_order,
},
{CREATE_CHILD_SA, TRUE, TRUE,
- (sizeof(create_child_sa_i_payload_rules)/sizeof(payload_rule_t)),
- create_child_sa_i_payload_rules,
- (sizeof(create_child_sa_i_payload_order)/sizeof(payload_order_t)),
- create_child_sa_i_payload_order,
+ countof(create_child_sa_i_rules), create_child_sa_i_rules,
+ countof(create_child_sa_i_order), create_child_sa_i_order,
},
{CREATE_CHILD_SA, FALSE, TRUE,
- (sizeof(create_child_sa_r_payload_rules)/sizeof(payload_rule_t)),
- create_child_sa_r_payload_rules,
- (sizeof(create_child_sa_r_payload_order)/sizeof(payload_order_t)),
- create_child_sa_r_payload_order,
+ countof(create_child_sa_r_rules), create_child_sa_r_rules,
+ countof(create_child_sa_r_order), create_child_sa_r_order,
},
#ifdef ME
{ME_CONNECT, TRUE, TRUE,
- (sizeof(me_connect_i_payload_rules)/sizeof(payload_rule_t)),
- me_connect_i_payload_rules,
- (sizeof(me_connect_i_payload_order)/sizeof(payload_order_t)),
- me_connect_i_payload_order,
+ countof(me_connect_i_rules), me_connect_i_rules,
+ countof(me_connect_i_order), me_connect_i_order,
},
{ME_CONNECT, FALSE, TRUE,
- (sizeof(me_connect_r_payload_rules)/sizeof(payload_rule_t)),
- me_connect_r_payload_rules,
- (sizeof(me_connect_r_payload_order)/sizeof(payload_order_t)),
- me_connect_r_payload_order,
+ countof(me_connect_r_rules), me_connect_r_rules,
+ countof(me_connect_r_order), me_connect_r_order,
},
#endif /* ME */
};
@@ -586,169 +517,132 @@ struct private_message_t {
/**
* The message rule for this message instance
*/
- message_rule_t *message_rule;
+ message_rule_t *rule;
};
/**
- * Implementation of private_message_t.set_message_rule.
+ * Get the message rule that applies to this message
*/
-static status_t set_message_rule(private_message_t *this)
+static message_rule_t* get_message_rule(private_message_t *this)
{
int i;
- for (i = 0; i < (sizeof(message_rules) / sizeof(message_rule_t)); i++)
+ for (i = 0; i < countof(message_rules); i++)
{
if ((this->exchange_type == message_rules[i].exchange_type) &&
(this->is_request == message_rules[i].is_request))
{
- /* found rule for given exchange_type*/
- this->message_rule = &(message_rules[i]);
- return SUCCESS;
+ return &message_rules[i];
}
}
- this->message_rule = NULL;
- return NOT_FOUND;
+ return NULL;
}
/**
- * Implementation of private_message_t.get_payload_rule.
+ * Look up a payload rule
*/
-static status_t get_payload_rule(private_message_t *this,
- payload_type_t payload_type, payload_rule_t **payload_rule)
+static payload_rule_t* get_payload_rule(private_message_t *this,
+ payload_type_t type)
{
int i;
- for (i = 0; i < this->message_rule->payload_rule_count;i++)
+ for (i = 0; i < this->rule->rule_count;i++)
{
- if (this->message_rule->payload_rules[i].payload_type == payload_type)
+ if (this->rule->rules[i].type == type)
{
- *payload_rule = &(this->message_rule->payload_rules[i]);
- return SUCCESS;
+ return &this->rule->rules[i];
}
}
-
- *payload_rule = NULL;
- return NOT_FOUND;
+ return NULL;
}
-/**
- * Implementation of message_t.set_ike_sa_id.
- */
-static void set_ike_sa_id(private_message_t *this,ike_sa_id_t *ike_sa_id)
+METHOD(message_t, set_ike_sa_id, void,
+ private_message_t *this,ike_sa_id_t *ike_sa_id)
{
DESTROY_IF(this->ike_sa_id);
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
}
-/**
- * Implementation of message_t.get_ike_sa_id.
- */
-static ike_sa_id_t* get_ike_sa_id(private_message_t *this)
+METHOD(message_t, get_ike_sa_id, ike_sa_id_t*,
+ private_message_t *this)
{
return this->ike_sa_id;
}
-/**
- * Implementation of message_t.set_message_id.
- */
-static void set_message_id(private_message_t *this,u_int32_t message_id)
+METHOD(message_t, set_message_id, void,
+ private_message_t *this,u_int32_t message_id)
{
this->message_id = message_id;
}
-/**
- * Implementation of message_t.get_message_id.
- */
-static u_int32_t get_message_id(private_message_t *this)
+METHOD(message_t, get_message_id, u_int32_t,
+ private_message_t *this)
{
return this->message_id;
}
-/**
- * Implementation of message_t.get_initiator_spi.
- */
-static u_int64_t get_initiator_spi(private_message_t *this)
+METHOD(message_t, get_initiator_spi, u_int64_t,
+ private_message_t *this)
{
return (this->ike_sa_id->get_initiator_spi(this->ike_sa_id));
}
-/**
- * Implementation of message_t.get_responder_spi.
- */
-static u_int64_t get_responder_spi(private_message_t *this)
+METHOD(message_t, get_responder_spi, u_int64_t,
+ private_message_t *this)
{
return (this->ike_sa_id->get_responder_spi(this->ike_sa_id));
}
-/**
- * Implementation of message_t.set_major_version.
- */
-static void set_major_version(private_message_t *this,u_int8_t major_version)
+METHOD(message_t, set_major_version, void,
+ private_message_t *this, u_int8_t major_version)
{
this->major_version = major_version;
}
-/**
- * Implementation of message_t.set_major_version.
- */
-static u_int8_t get_major_version(private_message_t *this)
+METHOD(message_t, get_major_version, u_int8_t,
+ private_message_t *this)
{
return this->major_version;
}
-/**
- * Implementation of message_t.set_minor_version.
- */
-static void set_minor_version(private_message_t *this,u_int8_t minor_version)
+METHOD(message_t, set_minor_version, void,
+ private_message_t *this,u_int8_t minor_version)
{
this->minor_version = minor_version;
}
-/**
- * Implementation of message_t.get_minor_version.
- */
-static u_int8_t get_minor_version(private_message_t *this)
+METHOD(message_t, get_minor_version, u_int8_t,
+ private_message_t *this)
{
return this->minor_version;
}
-/**
- * Implementation of message_t.set_exchange_type.
- */
-static void set_exchange_type(private_message_t *this,
- exchange_type_t exchange_type)
+METHOD(message_t, set_exchange_type, void,
+ private_message_t *this, exchange_type_t exchange_type)
{
this->exchange_type = exchange_type;
}
-/**
- * Implementation of message_t.get_exchange_type.
- */
-static exchange_type_t get_exchange_type(private_message_t *this)
+METHOD(message_t, get_exchange_type, exchange_type_t,
+ private_message_t *this)
{
return this->exchange_type;
}
-/**
- * Implementation of message_t.get_first_payload_type.
- */
-static payload_type_t get_first_payload_type(private_message_t *this)
+METHOD(message_t, get_first_payload_type, payload_type_t,
+ private_message_t *this)
{
return this->first_payload;
}
-/**
- * Implementation of message_t.set_request.
- */
-static void set_request(private_message_t *this, bool request)
+METHOD(message_t, set_request, void,
+ private_message_t *this, bool request)
{
this->is_request = request;
}
-/**
- * Implementation of message_t.get_request.
- */
-static exchange_type_t get_request(private_message_t *this)
+METHOD(message_t, get_request, bool,
+ private_message_t *this)
{
return this->is_request;
}
@@ -767,10 +661,8 @@ static bool is_encoded(private_message_t *this)
return TRUE;
}
-/**
- * Implementation of message_t.add_payload.
- */
-static void add_payload(private_message_t *this, payload_t *payload)
+METHOD(message_t, add_payload, void,
+ private_message_t *this, payload_t *payload)
{
payload_t *last_payload;
@@ -790,11 +682,8 @@ static void add_payload(private_message_t *this, payload_t *payload)
payload_type_names, payload->get_type(payload));
}
-/**
- * Implementation of message_t.add_notify.
- */
-static void add_notify(private_message_t *this, bool flush, notify_type_t type,
- chunk_t data)
+METHOD(message_t, add_notify, void,
+ private_message_t *this, bool flush, notify_type_t type, chunk_t data)
{
notify_payload_t *notify;
payload_t *payload;
@@ -813,50 +702,38 @@ static void add_notify(private_message_t *this, bool flush, notify_type_t type,
add_payload(this, (payload_t*)notify);
}
-/**
- * Implementation of message_t.set_source.
- */
-static void set_source(private_message_t *this, host_t *host)
+METHOD(message_t, set_source, void,
+ private_message_t *this, host_t *host)
{
this->packet->set_source(this->packet, host);
}
-/**
- * Implementation of message_t.set_destination.
- */
-static void set_destination(private_message_t *this, host_t *host)
+METHOD(message_t, set_destination, void,
+ private_message_t *this, host_t *host)
{
this->packet->set_destination(this->packet, host);
}
-/**
- * Implementation of message_t.get_source.
- */
-static host_t* get_source(private_message_t *this)
+METHOD(message_t, get_source, host_t*,
+ private_message_t *this)
{
return this->packet->get_source(this->packet);
}
-/**
- * Implementation of message_t.get_destination.
- */
-static host_t * get_destination(private_message_t *this)
+METHOD(message_t, get_destination, host_t*,
+ private_message_t *this)
{
return this->packet->get_destination(this->packet);
}
-/**
- * Implementation of message_t.create_payload_enumerator.
- */
-static enumerator_t *create_payload_enumerator(private_message_t *this)
+METHOD(message_t, create_payload_enumerator, enumerator_t*,
+ private_message_t *this)
{
return this->payloads->create_enumerator(this->payloads);
}
-/**
- * Implementation of message_t.get_payload.
- */
-static payload_t *get_payload(private_message_t *this, payload_type_t type)
+METHOD(message_t, get_payload, payload_t*,
+ private_message_t *this, payload_type_t type)
{
payload_t *current, *found = NULL;
enumerator_t *enumerator;
@@ -874,10 +751,8 @@ static payload_t *get_payload(private_message_t *this, payload_type_t type)
return found;
}
-/**
- * Implementation of message_t.get_notify
- */
-static notify_payload_t* get_notify(private_message_t *this, notify_type_t type)
+METHOD(message_t, get_notify, notify_payload_t*,
+ private_message_t *this, notify_type_t type)
{
enumerator_t *enumerator;
notify_payload_t *notify = NULL;
@@ -1034,11 +909,13 @@ static void order_payloads(private_message_t *this)
list->insert_first(list, payload);
}
/* for each rule, ... */
- for (i = 0; i < this->message_rule->payload_order_count; i++)
+ for (i = 0; i < this->rule->order_count; i++)
{
enumerator_t *enumerator;
notify_payload_t *notify;
- payload_order_t order = this->message_rule->payload_order[i];
+ payload_order_t order;
+
+ order = this->rule->order[i];
/* ... find all payload ... */
enumerator = list->create_enumerator(list);
@@ -1068,8 +945,8 @@ static void order_payloads(private_message_t *this)
{
DBG1(DBG_ENC, "payload %N has no ordering rule in %N %s",
payload_type_names, payload->get_type(payload),
- exchange_type_names, this->message_rule->exchange_type,
- this->message_rule->is_request ? "request" : "response");
+ exchange_type_names, this->rule->exchange_type,
+ this->rule->is_request ? "request" : "response");
}
add_payload(this, payload);
}
@@ -1077,98 +954,67 @@ static void order_payloads(private_message_t *this)
}
/**
- * Implementation of private_message_t.encrypt_payloads.
+ * Wrap payloads in a encryption payload
*/
-static status_t encrypt_payloads(private_message_t *this,
- crypter_t *crypter, signer_t* signer)
+static encryption_payload_t* wrap_payloads(private_message_t *this)
{
encryption_payload_t *encryption;
linked_list_t *payloads;
payload_t *current;
- status_t status;
- if (!this->message_rule->encrypted_content)
- {
- DBG2(DBG_ENC, "message doesn't have to be encrypted");
- /* message contains no content to encrypt */
- return SUCCESS;
- }
-
- if (!crypter || !signer)
- {
- DBG2(DBG_ENC, "no crypter or signer specified, do not encrypt message");
- /* message contains no content to encrypt */
- return SUCCESS;
- }
-
- DBG2(DBG_ENC, "copy all payloads to a temporary list");
+ /* copy all payloads in a temporary list */
payloads = linked_list_create();
-
- /* first copy all payloads in a temporary list */
- while (this->payloads->get_count(this->payloads) > 0)
+ while (this->payloads->remove_first(this->payloads,
+ (void**)&current) == SUCCESS)
{
- this->payloads->remove_first(this->payloads, (void**)&current);
payloads->insert_last(payloads, current);
}
encryption = encryption_payload_create();
-
- DBG2(DBG_ENC, "check each payloads if they have to get encrypted");
- while (payloads->get_count(payloads) > 0)
+ while (payloads->remove_first(payloads, (void**)&current) == SUCCESS)
{
payload_rule_t *rule;
payload_type_t type;
- bool to_encrypt = TRUE;
-
- payloads->remove_first(payloads, (void**)&current);
+ bool encrypt = TRUE;
type = current->get_type(current);
- if (get_payload_rule(this, type, &rule) == SUCCESS)
+ rule = get_payload_rule(this, type);
+ if (rule)
{
- to_encrypt = rule->encrypted;
+ encrypt = rule->encrypted;
}
- if (to_encrypt)
+ if (encrypt)
{
DBG2(DBG_ENC, "insert payload %N to encryption payload",
- payload_type_names, current->get_type(current));
+ payload_type_names, type);
encryption->add_payload(encryption, current);
}
else
{
DBG2(DBG_ENC, "insert payload %N unencrypted",
- payload_type_names, current->get_type(current));
- add_payload(this, (payload_t*)current);
+ payload_type_names, type);
+ add_payload(this, current);
}
}
-
- DBG2(DBG_ENC, "encrypting encryption payload");
- encryption->set_transforms(encryption, crypter, signer);
- status = encryption->encrypt(encryption);
- DBG2(DBG_ENC, "add encrypted payload to payload list");
- add_payload(this, (payload_t*)encryption);
-
payloads->destroy(payloads);
- return status;
+ return encryption;
}
-/**
- * Implementation of message_t.generate.
- */
-static status_t generate(private_message_t *this, crypter_t *crypter,
- signer_t* signer, packet_t **packet)
+METHOD(message_t, generate, status_t,
+ private_message_t *this, aead_t *aead, packet_t **packet)
{
generator_t *generator;
ike_header_t *ike_header;
- payload_t *payload, *next_payload;
+ payload_t *payload, *next;
+ encryption_payload_t *encryption = NULL;
enumerator_t *enumerator;
- status_t status;
- chunk_t packet_data;
+ chunk_t chunk;
char str[256];
+ u_int32_t *lenpos;
if (is_encoded(this))
- {
- /* already generated, return a new packet clone */
+ { /* already generated, return a new packet clone */
*packet = this->packet->clone(this->packet);
return SUCCESS;
}
@@ -1182,14 +1028,12 @@ static status_t generate(private_message_t *this, crypter_t *crypter,
if (this->packet->get_source(this->packet) == NULL ||
this->packet->get_destination(this->packet) == NULL)
{
- DBG1(DBG_ENC, "%s not defined",
- !this->packet->get_source(this->packet) ? "source" : "destination");
+ DBG1(DBG_ENC, "source/destination not defined");
return INVALID_STATE;
}
- /* set the rules for this messge */
- status = set_message_rule(this);
- if (status != SUCCESS)
+ this->rule = get_message_rule(this);
+ if (!this->rule)
{
DBG1(DBG_ENC, "no message rules specified for this message type");
return NOT_SUPPORTED;
@@ -1199,17 +1043,16 @@ static status_t generate(private_message_t *this, crypter_t *crypter,
DBG1(DBG_ENC, "generating %s", get_string(this, str, sizeof(str)));
- /* going to encrypt all content which have to be encrypted */
- status = encrypt_payloads(this, crypter, signer);
- if (status != SUCCESS)
+ if (aead && this->rule->encrypted)
{
- DBG1(DBG_ENC, "payload encryption failed");
- return status;
+ encryption = wrap_payloads(this);
+ }
+ else
+ {
+ DBG2(DBG_ENC, "not encrypting payloads");
}
- /* build ike header */
ike_header = ike_header_create();
-
ike_header->set_exchange_type(ike_header, this->exchange_type);
ike_header->set_message_id(ike_header, this->message_id);
ike_header->set_response_flag(ike_header, !this->is_request);
@@ -1222,54 +1065,49 @@ static status_t generate(private_message_t *this, crypter_t *crypter,
generator = generator_create();
+ /* generate all payloads with proper next type */
payload = (payload_t*)ike_header;
-
- /* generate every payload expect last one, this is done later*/
enumerator = create_payload_enumerator(this);
- while (enumerator->enumerate(enumerator, &next_payload))
+ while (enumerator->enumerate(enumerator, &next))
{
- payload->set_next_type(payload, next_payload->get_type(next_payload));
+ payload->set_next_type(payload, next->get_type(next));
generator->generate_payload(generator, payload);
- payload = next_payload;
+ payload = next;
}
enumerator->destroy(enumerator);
-
- /* last payload has no next payload*/
- payload->set_next_type(payload, NO_PAYLOAD);
-
+ payload->set_next_type(payload, encryption ? ENCRYPTED : NO_PAYLOAD);
generator->generate_payload(generator, payload);
-
ike_header->destroy(ike_header);
- /* build packet */
- generator->write_to_chunk(generator, &packet_data);
- generator->destroy(generator);
-
- /* if last payload is of type encrypted, integrity checksum if necessary */
- if (payload->get_type(payload) == ENCRYPTED)
+ if (encryption)
{
- DBG2(DBG_ENC, "build signature on whole message");
- encryption_payload_t *encryption_payload = (encryption_payload_t*)payload;
- status = encryption_payload->build_signature(encryption_payload, packet_data);
- if (status != SUCCESS)
+ u_int32_t *lenpos;
+
+ /* build associated data (without header of encryption payload) */
+ chunk = generator->get_chunk(generator, &lenpos);
+ encryption->set_transform(encryption, aead);
+ /* fill in length, including encryption payload */
+ htoun32(lenpos, chunk.len + encryption->get_length(encryption));
+
+ this->payloads->insert_last(this->payloads, encryption);
+ if (!encryption->encrypt(encryption, chunk))
{
- return status;
+ generator->destroy(generator);
+ return INVALID_STATE;
}
+ generator->generate_payload(generator, &encryption->payload_interface);
}
+ chunk = generator->get_chunk(generator, &lenpos);
+ htoun32(lenpos, chunk.len);
+ this->packet->set_data(this->packet, chunk_clone(chunk));
+ generator->destroy(generator);
- this->packet->set_data(this->packet, packet_data);
-
- /* clone packet for caller */
*packet = this->packet->clone(this->packet);
-
- DBG2(DBG_ENC, "message generated successfully");
return SUCCESS;
}
-/**
- * Implementation of message_t.get_packet.
- */
-static packet_t *get_packet(private_message_t *this)
+METHOD(message_t, get_packet, packet_t*,
+ private_message_t *this)
{
if (this->packet == NULL)
{
@@ -1278,10 +1116,8 @@ static packet_t *get_packet(private_message_t *this)
return this->packet->clone(this->packet);
}
-/**
- * Implementation of message_t.get_packet_data.
- */
-static chunk_t get_packet_data(private_message_t *this)
+METHOD(message_t, get_packet_data, chunk_t,
+ private_message_t *this)
{
if (this->packet == NULL)
{
@@ -1290,10 +1126,8 @@ static chunk_t get_packet_data(private_message_t *this)
return chunk_clone(this->packet->get_data(this->packet));
}
-/**
- * Implementation of message_t.parse_header.
- */
-static status_t parse_header(private_message_t *this)
+METHOD(message_t, parse_header, status_t,
+ private_message_t *this)
{
ike_header_t *ike_header;
status_t status;
@@ -1310,7 +1144,6 @@ static status_t parse_header(private_message_t *this)
}
- /* verify payload */
status = ike_header->payload_interface.verify(
&ike_header->payload_interface);
if (status != SUCCESS)
@@ -1320,18 +1153,14 @@ static status_t parse_header(private_message_t *this)
return status;
}
- if (this->ike_sa_id != NULL)
- {
- this->ike_sa_id->destroy(this->ike_sa_id);
- }
-
+ DESTROY_IF(this->ike_sa_id);
this->ike_sa_id = ike_sa_id_create(ike_header->get_initiator_spi(ike_header),
ike_header->get_responder_spi(ike_header),
ike_header->get_initiator_flag(ike_header));
this->exchange_type = ike_header->get_exchange_type(ike_header);
this->message_id = ike_header->get_message_id(ike_header);
- this->is_request = (!(ike_header->get_response_flag(ike_header)));
+ this->is_request = !ike_header->get_response_flag(ike_header);
this->major_version = ike_header->get_maj_version(ike_header);
this->minor_version = ike_header->get_min_version(ike_header);
this->first_payload = ike_header->payload_interface.get_next_type(
@@ -1342,232 +1171,151 @@ static status_t parse_header(private_message_t *this)
ike_header->destroy(ike_header);
- /* get the rules for this messge */
- status = set_message_rule(this);
- if (status != SUCCESS)
+ this->rule = get_message_rule(this);
+ if (!this->rule)
{
DBG1(DBG_ENC, "no message rules specified for a %N %s",
exchange_type_names, this->exchange_type,
this->is_request ? "request" : "response");
}
-
return status;
}
/**
- * Implementation of private_message_t.decrypt_and_verify_payloads.
+ * Decrypt payload from the encryption payload
*/
-static status_t decrypt_payloads(private_message_t *this, crypter_t *crypter,
- signer_t* signer)
+static status_t decrypt_payloads(private_message_t *this, aead_t *aead)
{
- bool current_payload_was_encrypted = FALSE;
- payload_t *previous_payload = NULL;
- int payload_number = 1;
- iterator_t *iterator;
- payload_t *current_payload;
- status_t status;
-
- iterator = this->payloads->create_iterator(this->payloads,TRUE);
+ bool was_encrypted = FALSE;
+ payload_t *payload, *previous = NULL;
+ enumerator_t *enumerator;
+ payload_rule_t *rule;
+ payload_type_t type;
+ status_t status = SUCCESS;
- /* process each payload and decrypt a encryption payload */
- while(iterator->iterate(iterator, (void**)&current_payload))
+ enumerator = this->payloads->create_enumerator(this->payloads);
+ while (enumerator->enumerate(enumerator, &payload))
{
- payload_rule_t *payload_rule;
- payload_type_t current_payload_type;
+ type = payload->get_type(payload);
- /* needed to check */
- current_payload_type = current_payload->get_type(current_payload);
+ DBG2(DBG_ENC, "process payload of type %N", payload_type_names, type);
- DBG2(DBG_ENC, "process payload of type %N",
- payload_type_names, current_payload_type);
-
- if (current_payload_type == ENCRYPTED)
+ if (type == ENCRYPTED)
{
- encryption_payload_t *encryption_payload;
- payload_t *current_encrypted_payload;
+ encryption_payload_t *encryption;
+ payload_t *encrypted;
+ chunk_t chunk;
- encryption_payload = (encryption_payload_t*)current_payload;
+ encryption = (encryption_payload_t*)payload;
DBG2(DBG_ENC, "found an encryption payload");
- if (payload_number != this->payloads->get_count(this->payloads))
+ if (enumerator->enumerate(enumerator, &payload))
{
- /* encrypted payload is not last one */
DBG1(DBG_ENC, "encrypted payload is not last payload");
- iterator->destroy(iterator);
- return VERIFY_ERROR;
+ status = VERIFY_ERROR;
+ break;
}
- /* decrypt */
- encryption_payload->set_transforms(encryption_payload,
- crypter, signer);
- DBG2(DBG_ENC, "verify signature of encryption payload");
- status = encryption_payload->verify_signature(encryption_payload,
- this->packet->get_data(this->packet));
- if (status != SUCCESS)
+ encryption->set_transform(encryption, aead);
+ chunk = this->packet->get_data(this->packet);
+ if (chunk.len < encryption->get_length(encryption))
{
- DBG1(DBG_ENC, "encryption payload signature invalid");
- iterator->destroy(iterator);
- return FAILED;
+ DBG1(DBG_ENC, "invalid payload length");
+ status = VERIFY_ERROR;
+ break;
}
- DBG2(DBG_ENC, "decrypting content of encryption payload");
- status = encryption_payload->decrypt(encryption_payload);
+ chunk.len -= encryption->get_length(encryption);
+ status = encryption->decrypt(encryption, chunk);
if (status != SUCCESS)
{
- DBG1(DBG_ENC, "encrypted payload could not be decrypted and parsed");
- iterator->destroy(iterator);
- return PARSE_ERROR;
- }
-
- /* needed later to find out if a payload was encrypted */
- current_payload_was_encrypted = TRUE;
-
- /* check if there are payloads contained in the encryption payload */
- if (encryption_payload->get_payload_count(encryption_payload) == 0)
- {
- DBG2(DBG_ENC, "encrypted payload is empty");
- /* remove the encryption payload, is not needed anymore */
- iterator->remove(iterator);
- /* encrypted payload contains no other payload */
- current_payload_type = NO_PAYLOAD;
- }
- else
- {
- /* encryption_payload is replaced with first payload contained
- * in encryption_payload */
- encryption_payload->remove_first_payload(encryption_payload,
- &current_encrypted_payload);
- iterator->replace(iterator, NULL,
- (void *)current_encrypted_payload);
- current_payload_type = current_encrypted_payload->get_type(
- current_encrypted_payload);
+ break;
}
- /* is the current paylad the first in the message? */
- if (previous_payload == NULL)
- {
- /* yes, set the first payload type of the message to the
- * current type */
- this->first_payload = current_payload_type;
- }
- else
- {
- /* no, set the next_type of the previous payload to the
- * current type */
- previous_payload->set_next_type(previous_payload,
- current_payload_type);
- }
+ was_encrypted = TRUE;
+ this->payloads->remove_at(this->payloads, enumerator);
- /* all encrypted payloads are added to the payload list */
- while (encryption_payload->get_payload_count(encryption_payload) > 0)
+ while ((encrypted = encryption->remove_payload(encryption)))
{
- encryption_payload->remove_first_payload(encryption_payload,
- &current_encrypted_payload);
- DBG2(DBG_ENC, "insert unencrypted payload of type "
- "%N at end of list", payload_type_names,
- current_encrypted_payload->get_type(
- current_encrypted_payload));
- this->payloads->insert_last(this->payloads,
- current_encrypted_payload);
+ type = encrypted->get_type(encrypted);
+ if (previous)
+ {
+ previous->set_next_type(previous, type);
+ }
+ else
+ {
+ this->first_payload = type;
+ }
+ DBG2(DBG_ENC, "insert decrypted payload of type "
+ "%N at end of list", payload_type_names, type);
+ this->payloads->insert_last(this->payloads, encrypted);
+ previous = encrypted;
}
-
- /* encryption payload is processed, payloads are moved. Destroy it. */
- encryption_payload->destroy(encryption_payload);
+ encryption->destroy(encryption);
}
-
- /* we allow unknown payloads of any type and don't bother if it was
- * encrypted. Not our problem. */
- if (current_payload_type != UNKNOWN_PAYLOAD &&
- current_payload_type != NO_PAYLOAD)
+ if (type != UNKNOWN_PAYLOAD && !was_encrypted)
{
- /* get the ruleset for found payload */
- status = get_payload_rule(this, current_payload_type, &payload_rule);
- if (status != SUCCESS)
- {
- /* payload is not allowed */
- DBG1(DBG_ENC, "payload type %N not allowed",
- payload_type_names, current_payload_type);
- iterator->destroy(iterator);
- return VERIFY_ERROR;
- }
-
- /* check if the payload was encrypted, and if it should been have
- * encrypted */
- if (payload_rule->encrypted != current_payload_was_encrypted)
+ rule = get_payload_rule(this, type);
+ if (!rule || rule->encrypted)
{
- /* payload was not encrypted, but should have been.
- * or vice-versa */
- DBG1(DBG_ENC, "payload type %N should be %s!",
- payload_type_names, current_payload_type,
- (payload_rule->encrypted) ? "encrypted" : "not encrypted");
- iterator->destroy(iterator);
- return VERIFY_ERROR;
+ DBG1(DBG_ENC, "payload type %N was not encrypted",
+ payload_type_names, type);
+ status = VERIFY_ERROR;
+ break;
}
}
- /* advance to the next payload */
- payload_number++;
- /* is stored to set next payload in case of found encryption payload */
- previous_payload = current_payload;
+ previous = payload;
}
- iterator->destroy(iterator);
- return SUCCESS;
+ enumerator->destroy(enumerator);
+ return status;
}
/**
- * Implementation of private_message_t.verify.
+ * Verify a message and all payload according to message/payload rules
*/
static status_t verify(private_message_t *this)
{
int i;
- enumerator_t *enumerator;
- payload_t *current_payload;
- size_t total_found_payloads = 0;
DBG2(DBG_ENC, "verifying message structure");
/* check for payloads with wrong count*/
- for (i = 0; i < this->message_rule->payload_rule_count; i++)
+ for (i = 0; i < this->rule->rule_count; i++)
{
- size_t found_payloads = 0;
+ enumerator_t *enumerator;
+ payload_t *payload;
payload_rule_t *rule;
+ int found = 0;
- rule = &this->message_rule->payload_rules[i];
+ rule = &this->rule->rules[i];
enumerator = create_payload_enumerator(this);
-
- /* check all payloads for specific rule */
- while (enumerator->enumerate(enumerator, &current_payload))
+ while (enumerator->enumerate(enumerator, &payload))
{
- payload_type_t current_payload_type;
- unknown_payload_t *unknown_payload;
+ payload_type_t type;
+ unknown_payload_t *unknown;
- current_payload_type = current_payload->get_type(current_payload);
- if (current_payload_type == UNKNOWN_PAYLOAD)
+ type = payload->get_type(payload);
+ if (type == UNKNOWN_PAYLOAD)
{
- /* unknown payloads are ignored, IF they are not critical */
- unknown_payload = (unknown_payload_t*)current_payload;
- if (unknown_payload->is_critical(unknown_payload))
+ /* unknown payloads are ignored if they are not critical */
+ unknown = (unknown_payload_t*)payload;
+ if (unknown->is_critical(unknown))
{
DBG1(DBG_ENC, "%N is not supported, but its critical!",
- payload_type_names, current_payload_type);
+ payload_type_names, type);
enumerator->destroy(enumerator);
return NOT_SUPPORTED;
}
}
- else if (current_payload_type == rule->payload_type)
+ else if (type == rule->type)
{
- found_payloads++;
- total_found_payloads++;
- DBG2(DBG_ENC, "found payload of type %N", payload_type_names,
- rule->payload_type);
-
- /* as soon as ohe payload occures more then specified,
- * the verification fails */
- if (found_payloads >
- rule->max_occurence)
+ found++;
+ DBG2(DBG_ENC, "found payload of type %N",
+ payload_type_names, type);
+ if (found > rule->max_occurence)
{
DBG1(DBG_ENC, "payload of type %N more than %d times (%d) "
"occured in current message", payload_type_names,
- current_payload_type, rule->max_occurence,
- found_payloads);
+ type, rule->max_occurence, found);
enumerator->destroy(enumerator);
return VERIFY_ERROR;
}
@@ -1575,11 +1323,10 @@ static status_t verify(private_message_t *this)
}
enumerator->destroy(enumerator);
- if (found_payloads < rule->min_occurence)
+ if (found < rule->min_occurence)
{
DBG1(DBG_ENC, "payload of type %N not occured %d times (%d)",
- payload_type_names, rule->payload_type, rule->min_occurence,
- found_payloads);
+ payload_type_names, rule->type, rule->min_occurence, found);
return VERIFY_ERROR;
}
if (rule->sufficient)
@@ -1590,72 +1337,60 @@ static status_t verify(private_message_t *this)
return SUCCESS;
}
-/**
- * Implementation of message_t.parse_body.
- */
-static status_t parse_body(private_message_t *this, crypter_t *crypter,
- signer_t *signer)
+METHOD(message_t, parse_body, status_t,
+ private_message_t *this, aead_t *aead)
{
status_t status = SUCCESS;
- payload_type_t current_payload_type;
+ payload_t *payload;
+ payload_type_t type;
char str[256];
- current_payload_type = this->first_payload;
+ type = this->first_payload;
DBG2(DBG_ENC, "parsing body of message, first payload is %N",
- payload_type_names, current_payload_type);
+ payload_type_names, type);
- /* parse payload for payload, while there are more available */
- while ((current_payload_type != NO_PAYLOAD))
+ while (type != NO_PAYLOAD)
{
- payload_t *current_payload;
-
DBG2(DBG_ENC, "starting parsing a %N payload",
- payload_type_names, current_payload_type);
+ payload_type_names, type);
- /* parse current payload */
- status = this->parser->parse_payload(this->parser, current_payload_type,
- (payload_t**)&current_payload);
+ status = this->parser->parse_payload(this->parser, type, &payload);
if (status != SUCCESS)
{
DBG1(DBG_ENC, "payload type %N could not be parsed",
- payload_type_names, current_payload_type);
+ payload_type_names, type);
return PARSE_ERROR;
}
- DBG2(DBG_ENC, "verifying payload of type %N",
- payload_type_names, current_payload_type);
-
- /* verify it, stop parsig if its invalid */
- status = current_payload->verify(current_payload);
+ DBG2(DBG_ENC, "verifying payload of type %N", payload_type_names, type);
+ status = payload->verify(payload);
if (status != SUCCESS)
{
DBG1(DBG_ENC, "%N payload verification failed",
- payload_type_names, current_payload_type);
- current_payload->destroy(current_payload);
+ payload_type_names, type);
+ payload->destroy(payload);
return VERIFY_ERROR;
}
DBG2(DBG_ENC, "%N payload verified. Adding to payload list",
- payload_type_names, current_payload_type);
- this->payloads->insert_last(this->payloads,current_payload);
+ payload_type_names, type);
+ this->payloads->insert_last(this->payloads, payload);
/* an encryption payload is the last one, so STOP here. decryption is
* done later */
- if (current_payload_type == ENCRYPTED)
+ if (type == ENCRYPTED)
{
DBG2(DBG_ENC, "%N payload found. Stop parsing",
- payload_type_names, current_payload_type);
+ payload_type_names, type);
break;
}
-
- /* get next payload type */
- current_payload_type = current_payload->get_next_type(current_payload);
+ type = payload->get_next_type(payload);
}
- if (current_payload_type == ENCRYPTED)
+ if (type == ENCRYPTED)
{
- status = decrypt_payloads(this,crypter,signer);
+ status = decrypt_payloads(this, aead);
if (status != SUCCESS)
{
DBG1(DBG_ENC, "could not decrypt payloads");
@@ -1674,10 +1409,8 @@ static status_t parse_body(private_message_t *this, crypter_t *crypter,
return SUCCESS;
}
-/**
- * Implementation of message_t.destroy.
- */
-static void destroy (private_message_t *this)
+METHOD(message_t, destroy, void,
+ private_message_t *this)
{
DESTROY_IF(this->ike_sa_id);
this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy));
@@ -1691,58 +1424,48 @@ static void destroy (private_message_t *this)
*/
message_t *message_create_from_packet(packet_t *packet)
{
- private_message_t *this = malloc_thing(private_message_t);
-
- /* public functions */
- this->public.set_major_version = (void(*)(message_t*, u_int8_t))set_major_version;
- this->public.get_major_version = (u_int8_t(*)(message_t*))get_major_version;
- this->public.set_minor_version = (void(*)(message_t*, u_int8_t))set_minor_version;
- this->public.get_minor_version = (u_int8_t(*)(message_t*))get_minor_version;
- this->public.set_message_id = (void(*)(message_t*, u_int32_t))set_message_id;
- this->public.get_message_id = (u_int32_t(*)(message_t*))get_message_id;
- this->public.get_initiator_spi = (u_int64_t(*)(message_t*))get_initiator_spi;
- this->public.get_responder_spi = (u_int64_t(*)(message_t*))get_responder_spi;
- this->public.set_ike_sa_id = (void(*)(message_t*, ike_sa_id_t *))set_ike_sa_id;
- this->public.get_ike_sa_id = (ike_sa_id_t*(*)(message_t*))get_ike_sa_id;
- this->public.set_exchange_type = (void(*)(message_t*, exchange_type_t))set_exchange_type;
- this->public.get_exchange_type = (exchange_type_t(*)(message_t*))get_exchange_type;
- this->public.get_first_payload_type = (payload_type_t(*)(message_t*))get_first_payload_type;
- this->public.set_request = (void(*)(message_t*, bool))set_request;
- this->public.get_request = (bool(*)(message_t*))get_request;
- this->public.add_payload = (void(*)(message_t*,payload_t*))add_payload;
- this->public.add_notify = (void(*)(message_t*,bool,notify_type_t,chunk_t))add_notify;
- this->public.generate = (status_t (*) (message_t *,crypter_t*,signer_t*,packet_t**)) generate;
- this->public.set_source = (void (*) (message_t*,host_t*)) set_source;
- this->public.get_source = (host_t * (*) (message_t*)) get_source;
- this->public.set_destination = (void (*) (message_t*,host_t*)) set_destination;
- this->public.get_destination = (host_t * (*) (message_t*)) get_destination;
- this->public.create_payload_enumerator = (enumerator_t * (*) (message_t *)) create_payload_enumerator;
- this->public.get_payload = (payload_t * (*) (message_t *, payload_type_t)) get_payload;
- this->public.get_notify = (notify_payload_t*(*)(message_t*, notify_type_t type))get_notify;
- this->public.parse_header = (status_t (*) (message_t *)) parse_header;
- this->public.parse_body = (status_t (*) (message_t *,crypter_t*,signer_t*)) parse_body;
- this->public.get_packet = (packet_t * (*) (message_t*)) get_packet;
- this->public.get_packet_data = (chunk_t (*) (message_t *this)) get_packet_data;
- this->public.destroy = (void(*)(message_t*))destroy;
-
- /* private values */
- this->exchange_type = EXCHANGE_TYPE_UNDEFINED;
- this->is_request = TRUE;
- this->ike_sa_id = NULL;
- this->first_payload = NO_PAYLOAD;
- this->message_id = 0;
-
- /* private values */
- if (packet == NULL)
- {
- packet = packet_create();
- }
- this->message_rule = NULL;
- this->packet = packet;
- this->payloads = linked_list_create();
-
- /* parser is created from data of packet */
- this->parser = parser_create(this->packet->get_data(this->packet));
+ private_message_t *this;
+
+ INIT(this,
+ .public = {
+ .set_major_version = _set_major_version,
+ .get_major_version = _get_major_version,
+ .set_minor_version = _set_minor_version,
+ .get_minor_version = _get_minor_version,
+ .set_message_id = _set_message_id,
+ .get_message_id = _get_message_id,
+ .get_initiator_spi = _get_initiator_spi,
+ .get_responder_spi = _get_responder_spi,
+ .set_ike_sa_id = _set_ike_sa_id,
+ .get_ike_sa_id = _get_ike_sa_id,
+ .set_exchange_type = _set_exchange_type,
+ .get_exchange_type = _get_exchange_type,
+ .get_first_payload_type = _get_first_payload_type,
+ .set_request = _set_request,
+ .get_request = _get_request,
+ .add_payload = _add_payload,
+ .add_notify = _add_notify,
+ .generate = _generate,
+ .set_source = _set_source,
+ .get_source = _get_source,
+ .set_destination = _set_destination,
+ .get_destination = _get_destination,
+ .create_payload_enumerator = _create_payload_enumerator,
+ .get_payload = _get_payload,
+ .get_notify = _get_notify,
+ .parse_header = _parse_header,
+ .parse_body = _parse_body,
+ .get_packet = _get_packet,
+ .get_packet_data = _get_packet_data,
+ .destroy = _destroy,
+ },
+ .exchange_type = EXCHANGE_TYPE_UNDEFINED,
+ .is_request = TRUE,
+ .first_payload = NO_PAYLOAD,
+ .packet = packet,
+ .payloads = linked_list_create(),
+ .parser = parser_create(packet->get_data(packet)),
+ );
return (&this->public);
}
@@ -1752,6 +1475,6 @@ message_t *message_create_from_packet(packet_t *packet)
*/
message_t *message_create()
{
- return message_create_from_packet(NULL);
+ return message_create_from_packet(packet_create());
}
diff --git a/src/libcharon/encoding/message.h b/src/libcharon/encoding/message.h
index 2c7718f49..8c1cbcd09 100644
--- a/src/libcharon/encoding/message.h
+++ b/src/libcharon/encoding/message.h
@@ -32,8 +32,7 @@ typedef struct message_t message_t;
#include <encoding/payloads/ike_header.h>
#include <encoding/payloads/notify_payload.h>
#include <utils/linked_list.h>
-#include <crypto/crypters/crypter.h>
-#include <crypto/signers/signer.h>
+#include <crypto/aead.h>
/**
* This class is used to represent an IKEv2-Message.
@@ -201,14 +200,10 @@ struct message_t {
* The body gets not only parsed, but rather it gets verified.
* All payloads are verified if they are allowed to exist in the message
* of this type and if their own structure is ok.
- * If there are encrypted payloads, they get decrypted via the supplied
- * crypter. Also the message integrity gets verified with the supplied
- * signer.
- * Crypter/signer can be omitted (by passing NULL) when no encryption
- * payload is expected.
- *
- * @param crypter crypter to decrypt encryption payloads
- * @param signer signer to verifiy a message with an encryption payload
+ * If there are encrypted payloads, they get decrypted and verified using
+ * the given aead transform (if given).
+ *
+ * @param aead aead transform to verify/decrypt message
* @return
* - SUCCESS if parsing successful
* - NOT_SUPPORTED if ciritcal unknown payloads found
@@ -216,32 +211,28 @@ struct message_t {
* - PARSE_ERROR if message parsing failed
* - VERIFY_ERROR if message verification failed (bad syntax)
* - FAILED if integrity check failed
- * - INVALID_STATE if crypter/signer not supplied, but needed
+ * - INVALID_STATE if aead not supplied, but needed
*/
- status_t (*parse_body) (message_t *this, crypter_t *crypter, signer_t *signer);
+ status_t (*parse_body) (message_t *this, aead_t *aead);
/**
* Generates the UDP packet of specific message.
*
* Payloads which must be encrypted are generated first and added to
- * an encryption payload. This encryption payload will get encrypted via
- * the supplied crypter. Then all other payloads and the header get generated.
- * After that, the checksum is added to the encryption payload over the full
- * message.
- * Crypter/signer can be omitted (by passing NULL) when no encryption
- * payload is expected.
- * Generation is only done once, multiple calls will just return a packet copy.
- *
- * @param crypter crypter to use when a payload must be encrypted
- * @param signer signer to build a mac
+ * an encryption payload. This encryption payload will get encrypted and
+ * signed via the supplied aead transform (if given).
+ * Generation is only done once, multiple calls will just return a copy
+ * of the packet.
+ *
+ * @param aead aead transform to encrypt/sign message
* @param packet copy of generated packet
* @return
* - SUCCESS if packet could be generated
* - INVALID_STATE if exchange type is currently not set
* - NOT_FOUND if no rules found for message generation
- * - INVALID_STATE if crypter/signer not supplied but needed.
+ * - INVALID_STATE if aead not supplied but needed.
*/
- status_t (*generate) (message_t *this, crypter_t *crypter, signer_t *signer, packet_t **packet);
+ status_t (*generate) (message_t *this, aead_t *aead, packet_t **packet);
/**
* Gets the source host informations.
@@ -331,13 +322,8 @@ struct message_t {
/**
* Creates an message_t object from a incoming UDP Packet.
*
- * @warning the given packet_t object is not copied and gets
- * destroyed in message_t's destroy call.
- *
- * - exchange_type is set to NOT_SET
- * - original_initiator is set to TRUE
- * - is_request is set to TRUE
- * Call message_t.parse_header afterwards.
+ * The given packet gets owned by the message. The message is uninitialized,
+ * call parse_header() to populate header fields.
*
* @param packet packet_t object which is assigned to message
* @return message_t object
diff --git a/src/libcharon/encoding/payloads/delete_payload.c b/src/libcharon/encoding/payloads/delete_payload.c
index 97b4743b2..5fc3b7c88 100644
--- a/src/libcharon/encoding/payloads/delete_payload.c
+++ b/src/libcharon/encoding/payloads/delete_payload.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -65,11 +66,6 @@ struct private_delete_payload_t {
* The contained SPI's.
*/
chunk_t spis;
-
- /**
- * List containing u_int32_t spis
- */
- linked_list_t *spi_list;
};
/**
@@ -77,7 +73,6 @@ struct private_delete_payload_t {
*
* The defined offsets are the positions in a object of type
* private_delete_payload_t.
- *
*/
encoding_rule_t delete_payload_encodings[] = {
/* 1 Byte next payload type, stored in the field next_payload */
@@ -85,20 +80,20 @@ encoding_rule_t delete_payload_encodings[] = {
/* the critical bit */
{ FLAG, offsetof(private_delete_payload_t, critical) },
/* 7 Bit reserved bits, nowhere stored */
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
/* Length of the whole payload*/
- { PAYLOAD_LENGTH, offsetof(private_delete_payload_t, payload_length)},
+ { PAYLOAD_LENGTH, offsetof(private_delete_payload_t, payload_length) },
{ U_INT_8, offsetof(private_delete_payload_t, protocol_id) },
{ U_INT_8, offsetof(private_delete_payload_t, spi_size) },
{ U_INT_16, offsetof(private_delete_payload_t, spi_count) },
/* some delete data bytes, length is defined in PAYLOAD_LENGTH */
- { SPIS, offsetof(private_delete_payload_t, spis) }
+ { SPIS, offsetof(private_delete_payload_t, spis) }
};
/*
@@ -115,10 +110,8 @@ encoding_rule_t delete_payload_encodings[] = {
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-/**
- * Implementation of payload_t.verify.
- */
-static status_t verify(private_delete_payload_t *this)
+METHOD(payload_t, verify, status_t,
+ private_delete_payload_t *this)
{
switch (this->protocol_id)
{
@@ -147,112 +140,104 @@ static status_t verify(private_delete_payload_t *this)
return SUCCESS;
}
-/**
- * Implementation of delete_payload_t.get_encoding_rules.
- */
-static void get_encoding_rules(private_delete_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
+METHOD(payload_t, get_encoding_rules, void,
+ private_delete_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
{
*rules = delete_payload_encodings;
- *rule_count = sizeof(delete_payload_encodings) / sizeof(encoding_rule_t);
+ *rule_count = countof(delete_payload_encodings);
}
-/**
- * Implementation of payload_t.get_type.
- */
-static payload_type_t get_payload_type(private_delete_payload_t *this)
+METHOD(payload_t, get_payload_type, payload_type_t,
+ private_delete_payload_t *this)
{
return DELETE;
}
-/**
- * Implementation of payload_t.get_next_type.
- */
-static payload_type_t get_next_type(private_delete_payload_t *this)
+METHOD(payload_t, get_next_type, payload_type_t,
+ private_delete_payload_t *this)
{
- return (this->next_payload);
+ return this->next_payload;
}
-/**
- * Implementation of payload_t.set_next_type.
- */
-static void set_next_type(private_delete_payload_t *this,payload_type_t type)
+METHOD(payload_t, set_next_type, void,
+ private_delete_payload_t *this,payload_type_t type)
{
this->next_payload = type;
}
-/**
- * Implementation of payload_t.get_length.
- */
-static size_t get_length(private_delete_payload_t *this)
+METHOD(payload_t, get_length, size_t,
+ private_delete_payload_t *this)
{
return this->payload_length;
}
-/**
- * Implementation of delete_payload_t.get_protocol_id.
- */
-static protocol_id_t get_protocol_id (private_delete_payload_t *this)
+METHOD(delete_payload_t, get_protocol_id, protocol_id_t,
+ private_delete_payload_t *this)
{
- return (this->protocol_id);
+ return this->protocol_id;
}
-/**
- * Implementation of delete_payload_t.add_spi.
- */
-static void add_spi(private_delete_payload_t *this, u_int32_t spi)
+METHOD(delete_payload_t, add_spi, void,
+ private_delete_payload_t *this, u_int32_t spi)
{
- /* only add SPIs if AH|ESP, ignore others */
- if (this->protocol_id == PROTO_AH || this->protocol_id == PROTO_ESP)
+ switch (this->protocol_id)
{
- this->spi_count += 1;
- this->spis.len += this->spi_size;
- this->spis.ptr = realloc(this->spis.ptr, this->spis.len);
- *(u_int32_t*)(this->spis.ptr + (this->spis.len / this->spi_size - 1)) = spi;
- if (this->spi_list)
- {
- /* reset SPI iterator list */
- this->spi_list->destroy(this->spi_list);
- this->spi_list = NULL;
- }
+ case PROTO_AH:
+ case PROTO_ESP:
+ this->spi_count++;
+ this->payload_length += sizeof(spi);
+ this->spis = chunk_cat("mc", this->spis, chunk_from_thing(spi));
+ break;
+ default:
+ break;
}
}
/**
- * Implementation of delete_payload_t.create_spi_iterator.
+ * SPI enumerator implementation
*/
-static iterator_t* create_spi_iterator(private_delete_payload_t *this)
-{
- int i;
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** remaining SPIs */
+ chunk_t spis;
+} spi_enumerator_t;
- if (this->spi_list == NULL)
+METHOD(enumerator_t, spis_enumerate, bool,
+ spi_enumerator_t *this, u_int32_t *spi)
+{
+ if (this->spis.len >= sizeof(*spi))
{
- this->spi_list = linked_list_create();
- /* only parse SPIs if AH|ESP */
- if (this->protocol_id == PROTO_AH || this->protocol_id == PROTO_ESP)
- {
- for (i = 0; i < this->spi_count; i++)
- {
- this->spi_list->insert_last(this->spi_list, this->spis.ptr + i *
- this->spi_size);
- }
- }
+ memcpy(spi, this->spis.ptr, sizeof(*spi));
+ this->spis = chunk_skip(this->spis, sizeof(*spi));
+ return TRUE;
}
- return this->spi_list->create_iterator(this->spi_list, TRUE);
+ return FALSE;
}
-/**
- * Implementation of payload_t.destroy and delete_payload_t.destroy.
- */
-static void destroy(private_delete_payload_t *this)
+METHOD(delete_payload_t, create_spi_enumerator, enumerator_t*,
+ private_delete_payload_t *this)
{
- if (this->spis.ptr != NULL)
- {
- chunk_free(&this->spis);
- }
- if (this->spi_list)
+ spi_enumerator_t *e;
+
+ if (this->spi_size != sizeof(u_int32_t))
{
- this->spi_list->destroy(this->spi_list);
+ return enumerator_create_empty();
}
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_spis_enumerate,
+ .destroy = (void*)free,
+ },
+ .spis = this->spis,
+ );
+ return &e->public;
+}
+
+METHOD2(payload_t, delete_payload_t, destroy, void,
+ private_delete_payload_t *this)
+{
+ free(this->spis.ptr);
free(this);
}
@@ -261,32 +246,28 @@ static void destroy(private_delete_payload_t *this)
*/
delete_payload_t *delete_payload_create(protocol_id_t protocol_id)
{
- private_delete_payload_t *this = malloc_thing(private_delete_payload_t);
-
- /* interface functions */
- this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
- this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
- this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
- this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
- this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
- this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
- this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
-
- /* public functions */
- this->public.destroy = (void (*) (delete_payload_t *)) destroy;
- this->public.get_protocol_id = (protocol_id_t (*) (delete_payload_t *)) get_protocol_id;
- this->public.add_spi = (void (*) (delete_payload_t *,u_int32_t))add_spi;
- this->public.create_spi_iterator = (iterator_t* (*) (delete_payload_t *)) create_spi_iterator;
-
- /* private variables */
- this->critical = FALSE;
- this->next_payload = NO_PAYLOAD;
- this->payload_length = DELETE_PAYLOAD_HEADER_LENGTH;
- this->protocol_id = protocol_id;
- this->spi_size = protocol_id == PROTO_AH || protocol_id == PROTO_ESP ? 4 : 0;
- this->spi_count = 0;
- this->spis = chunk_empty;
- this->spi_list = NULL;
+ private_delete_payload_t *this;
- return (&this->public);
+ INIT(this,
+ .public = {
+ .payload_interface = {
+ .verify = _verify,
+ .get_encoding_rules = _get_encoding_rules,
+ .get_length = _get_length,
+ .get_next_type = _get_next_type,
+ .set_next_type = _set_next_type,
+ .get_type = _get_payload_type,
+ .destroy = _destroy,
+ },
+ .get_protocol_id = _get_protocol_id,
+ .add_spi = _add_spi,
+ .create_spi_enumerator = _create_spi_enumerator,
+ .destroy = _destroy,
+ },
+ .next_payload = NO_PAYLOAD,
+ .payload_length = DELETE_PAYLOAD_HEADER_LENGTH,
+ .protocol_id = protocol_id,
+ .spi_size = protocol_id == PROTO_AH || protocol_id == PROTO_ESP ? 4 : 0,
+ );
+ return &this->public;
}
diff --git a/src/libcharon/encoding/payloads/delete_payload.h b/src/libcharon/encoding/payloads/delete_payload.h
index 3b62c1af1..026829f97 100644
--- a/src/libcharon/encoding/payloads/delete_payload.h
+++ b/src/libcharon/encoding/payloads/delete_payload.h
@@ -39,6 +39,7 @@ typedef struct delete_payload_t delete_payload_t;
* The DELETE payload format is described in RFC section 3.11.
*/
struct delete_payload_t {
+
/**
* The payload_t interface.
*/
@@ -59,13 +60,11 @@ struct delete_payload_t {
void (*add_spi) (delete_payload_t *this, u_int32_t spi);
/**
- * Get an iterator over the SPIs.
- *
- * The iterate() function returns a pointer to a u_int32_t SPI.
+ * Get an enumerator over the SPIs in network order.
*
- * @return iterator over SPIs
+ * @return enumerator over SPIs, u_int32_t
*/
- iterator_t *(*create_spi_iterator) (delete_payload_t *this);
+ enumerator_t *(*create_spi_enumerator) (delete_payload_t *this);
/**
* Destroys an delete_payload_t object.
diff --git a/src/libcharon/encoding/payloads/encryption_payload.c b/src/libcharon/encoding/payloads/encryption_payload.c
index 2adbb88b9..3b23ea9fb 100644
--- a/src/libcharon/encoding/payloads/encryption_payload.c
+++ b/src/libcharon/encoding/payloads/encryption_payload.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -24,9 +25,6 @@
#include <utils/linked_list.h>
#include <encoding/generator.h>
#include <encoding/parser.h>
-#include <utils/iterator.h>
-#include <crypto/signers/signer.h>
-
typedef struct private_encryption_payload_t private_encryption_payload_t;
@@ -50,9 +48,9 @@ struct private_encryption_payload_t {
u_int8_t next_payload;
/**
- * Critical flag.
+ * Flags, including reserved bits
*/
- bool critical;
+ u_int8_t flags;
/**
* Length of this payload
@@ -60,28 +58,17 @@ struct private_encryption_payload_t {
u_int16_t payload_length;
/**
- * Chunk containing the iv, data, padding,
- * and (an eventually not calculated) signature.
+ * Chunk containing the IV, plain, padding and ICV.
*/
chunk_t encrypted;
/**
- * Chunk containing the data in decrypted (unpadded) form.
- */
- chunk_t decrypted;
-
- /**
- * Signer set by set_signer.
+ * AEAD transform to use
*/
- signer_t *signer;
+ aead_t *aead;
/**
- * Crypter, supplied by encrypt/decrypt
- */
- crypter_t *crypter;
-
- /**
- * Contained payloads of this encrpytion_payload.
+ * Contained payloads
*/
linked_list_t *payloads;
};
@@ -91,25 +78,16 @@ struct private_encryption_payload_t {
*
* The defined offsets are the positions in a object of type
* private_encryption_payload_t.
- *
*/
encoding_rule_t encryption_payload_encodings[] = {
/* 1 Byte next payload type, stored in the field next_payload */
{ U_INT_8, offsetof(private_encryption_payload_t, next_payload) },
- /* the critical bit */
- { FLAG, offsetof(private_encryption_payload_t, critical) },
- /* 7 Bit reserved bits, nowhere stored */
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
+ /* Critical and 7 reserved bits, all stored for reconstruction */
+ { U_INT_8, offsetof(private_encryption_payload_t, flags) },
/* Length of the whole encryption payload*/
{ PAYLOAD_LENGTH, offsetof(private_encryption_payload_t, payload_length) },
/* encrypted data, stored in a chunk. contains iv, data, padding */
- { ENCRYPTED_DATA, offsetof(private_encryption_payload_t, encrypted) },
+ { ENCRYPTED_DATA, offsetof(private_encryption_payload_t, encrypted) },
};
/*
@@ -131,108 +109,90 @@ encoding_rule_t encryption_payload_encodings[] = {
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-/**
- * Implementation of payload_t.verify.
- */
-static status_t verify(private_encryption_payload_t *this)
+METHOD(payload_t, verify, status_t,
+ private_encryption_payload_t *this)
{
return SUCCESS;
}
-/**
- * Implementation of payload_t.get_encoding_rules.
- */
-static void get_encoding_rules(private_encryption_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
+METHOD(payload_t, get_encoding_rules, void,
+ private_encryption_payload_t *this, encoding_rule_t **rules,
+ size_t *count)
{
*rules = encryption_payload_encodings;
- *rule_count = sizeof(encryption_payload_encodings) / sizeof(encoding_rule_t);
+ *count = countof(encryption_payload_encodings);
}
-/**
- * Implementation of payload_t.get_type.
- */
-static payload_type_t get_type(private_encryption_payload_t *this)
+METHOD(payload_t, get_type, payload_type_t,
+ private_encryption_payload_t *this)
{
return ENCRYPTED;
}
-/**
- * Implementation of payload_t.get_next_type.
- */
-static payload_type_t get_next_type(private_encryption_payload_t *this)
+METHOD(payload_t, get_next_type, payload_type_t,
+ private_encryption_payload_t *this)
{
- /* returns first contained payload here */
- return (this->next_payload);
+ return this->next_payload;
}
-/**
- * Implementation of payload_t.set_next_type.
- */
-static void set_next_type(private_encryption_payload_t *this, payload_type_t type)
+METHOD(payload_t, set_next_type, void,
+ private_encryption_payload_t *this, payload_type_t type)
{
- /* set next type is not allowed, since this payload MUST be the last one
- * and so nothing is done in here*/
+ /* the next payload is set during add */
}
/**
- * (re-)compute the lenght of the whole payload
+ * Compute the lenght of the whole payload
*/
static void compute_length(private_encryption_payload_t *this)
{
- iterator_t *iterator;
- payload_t *current_payload;
- size_t block_size, length = 0;
- iterator = this->payloads->create_iterator(this->payloads, TRUE);
+ enumerator_t *enumerator;
+ payload_t *payload;
+ size_t bs, length = 0;
- /* count payload length */
- while (iterator->iterate(iterator, (void **) &current_payload))
+ if (this->encrypted.len)
{
- length += current_payload->get_length(current_payload);
+ length = this->encrypted.len;
}
- iterator->destroy(iterator);
-
- if (this->crypter && this->signer)
+ else
{
- /* append one byte for padding length */
- length++;
- /* append padding */
- block_size = this->crypter->get_block_size(this->crypter);
- length += block_size - length % block_size;
- /* add iv */
- length += block_size;
- /* add signature */
- length += this->signer->get_block_size(this->signer);
+ enumerator = this->payloads->create_enumerator(this->payloads);
+ while (enumerator->enumerate(enumerator, &payload))
+ {
+ length += payload->get_length(payload);
+ }
+ enumerator->destroy(enumerator);
+
+ if (this->aead)
+ {
+ /* append padding */
+ bs = this->aead->get_block_size(this->aead);
+ length += bs - (length % bs);
+ /* add iv */
+ length += this->aead->get_iv_size(this->aead);
+ /* add icv */
+ length += this->aead->get_icv_size(this->aead);
+ }
}
length += ENCRYPTION_PAYLOAD_HEADER_LENGTH;
this->payload_length = length;
}
-/**
- * Implementation of payload_t.get_length.
- */
-static size_t get_length(private_encryption_payload_t *this)
+METHOD2(payload_t, encryption_payload_t, get_length, size_t,
+ private_encryption_payload_t *this)
{
compute_length(this);
return this->payload_length;
}
-/**
- * Implementation of payload_t.create_payload_iterator.
- */
-static iterator_t *create_payload_iterator (private_encryption_payload_t *this, bool forward)
-{
- return (this->payloads->create_iterator(this->payloads, forward));
-}
-
-/**
- * Implementation of payload_t.add_payload.
- */
-static void add_payload(private_encryption_payload_t *this, payload_t *payload)
+METHOD(encryption_payload_t, add_payload, void,
+ private_encryption_payload_t *this, payload_t *payload)
{
payload_t *last_payload;
+
if (this->payloads->get_count(this->payloads) > 0)
{
- this->payloads->get_last(this->payloads,(void **) &last_payload);
+ this->payloads->get_last(this->payloads, (void **)&last_payload);
last_payload->set_next_type(last_payload, payload->get_type(payload));
}
else
@@ -240,339 +200,255 @@ static void add_payload(private_encryption_payload_t *this, payload_t *payload)
this->next_payload = payload->get_type(payload);
}
payload->set_next_type(payload, NO_PAYLOAD);
- this->payloads->insert_last(this->payloads, (void*)payload);
+ this->payloads->insert_last(this->payloads, payload);
compute_length(this);
}
-/**
- * Implementation of encryption_payload_t.remove_first_payload.
- */
-static status_t remove_first_payload(private_encryption_payload_t *this, payload_t **payload)
+METHOD(encryption_payload_t, remove_payload, payload_t *,
+ private_encryption_payload_t *this)
{
- return this->payloads->remove_first(this->payloads, (void**)payload);
-}
+ payload_t *payload;
-/**
- * Implementation of encryption_payload_t.get_payload_count.
- */
-static size_t get_payload_count(private_encryption_payload_t *this)
-{
- return this->payloads->get_count(this->payloads);
+ if (this->payloads->remove_first(this->payloads,
+ (void**)&payload) == SUCCESS)
+ {
+ return payload;
+ }
+ return NULL;
}
/**
- * Generate payload before encryption.
+ * Generate payload before encryption
*/
-static void generate(private_encryption_payload_t *this)
+static chunk_t generate(private_encryption_payload_t *this,
+ generator_t *generator)
{
- payload_t *current_payload, *next_payload;
- generator_t *generator;
- iterator_t *iterator;
-
- /* recalculate length before generating */
- compute_length(this);
+ payload_t *current, *next;
+ enumerator_t *enumerator;
+ u_int32_t *lenpos;
+ chunk_t chunk = chunk_empty;
- /* create iterator */
- iterator = this->payloads->create_iterator(this->payloads, TRUE);
-
- /* get first payload */
- if (iterator->iterate(iterator, (void**)&current_payload))
- {
- this->next_payload = current_payload->get_type(current_payload);
- }
- else
+ enumerator = this->payloads->create_enumerator(this->payloads);
+ if (enumerator->enumerate(enumerator, &current))
{
- /* no paylads? */
- DBG2(DBG_ENC, "generating contained payloads, but none available");
- free(this->decrypted.ptr);
- this->decrypted = chunk_empty;
- iterator->destroy(iterator);
- return;
- }
+ this->next_payload = current->get_type(current);
- generator = generator_create();
+ while (enumerator->enumerate(enumerator, &next))
+ {
+ current->set_next_type(current, next->get_type(next));
+ generator->generate_payload(generator, current);
+ current = next;
+ }
+ current->set_next_type(current, NO_PAYLOAD);
+ generator->generate_payload(generator, current);
- /* build all payload, except last */
- while(iterator->iterate(iterator, (void**)&next_payload))
- {
- current_payload->set_next_type(current_payload, next_payload->get_type(next_payload));
- generator->generate_payload(generator, current_payload);
- current_payload = next_payload;
+ chunk = generator->get_chunk(generator, &lenpos);
+ DBG2(DBG_ENC, "generated content in encryption payload");
}
- iterator->destroy(iterator);
-
- /* build last payload */
- current_payload->set_next_type(current_payload, NO_PAYLOAD);
- generator->generate_payload(generator, current_payload);
-
- /* free already generated data */
- free(this->decrypted.ptr);
-
- generator->write_to_chunk(generator, &(this->decrypted));
- generator->destroy(generator);
- DBG2(DBG_ENC, "successfully generated content in encryption payload");
+ enumerator->destroy(enumerator);
+ return chunk;
}
/**
- * Implementation of encryption_payload_t.encrypt.
+ * Append the encryption payload header to the associated data
*/
-static status_t encrypt(private_encryption_payload_t *this)
+static chunk_t append_header(private_encryption_payload_t *this, chunk_t assoc)
{
- chunk_t iv, padding, to_crypt, result;
+ struct {
+ u_int8_t next_payload;
+ u_int8_t flags;
+ u_int16_t length;
+ } __attribute__((packed)) header = {
+ .next_payload = this->next_payload,
+ .flags = this->flags,
+ .length = htons(get_length(this)),
+ };
+ return chunk_cat("cc", assoc, chunk_from_thing(header));
+}
+
+METHOD(encryption_payload_t, encrypt, bool,
+ private_encryption_payload_t *this, chunk_t assoc)
+{
+ chunk_t iv, plain, padding, icv, crypt;
+ generator_t *generator;
rng_t *rng;
- size_t block_size;
+ size_t bs;
- if (this->signer == NULL || this->crypter == NULL)
+ if (this->aead == NULL)
{
- DBG1(DBG_ENC, "could not encrypt, signer/crypter not set");
- return INVALID_STATE;
+ DBG1(DBG_ENC, "encrypting encryption payload failed, transform missing");
+ return FALSE;
}
- /* for random data in iv and padding */
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
if (!rng)
{
- DBG1(DBG_ENC, "could not encrypt, no RNG found");
- return FAILED;
+ DBG1(DBG_ENC, "encrypting encryption payload failed, no RNG found");
+ return FALSE;
}
- /* build payload chunk */
- generate(this);
- DBG2(DBG_ENC, "encrypting payloads");
- DBG3(DBG_ENC, "data to encrypt %B", &this->decrypted);
+ assoc = append_header(this, assoc);
- /* build padding */
- block_size = this->crypter->get_block_size(this->crypter);
- padding.len = block_size - ((this->decrypted.len + 1) % block_size);
- rng->allocate_bytes(rng, padding.len, &padding);
-
- /* concatenate payload data, padding, padding len */
- to_crypt.len = this->decrypted.len + padding.len + 1;
- to_crypt.ptr = malloc(to_crypt.len);
-
- memcpy(to_crypt.ptr, this->decrypted.ptr, this->decrypted.len);
- memcpy(to_crypt.ptr + this->decrypted.len, padding.ptr, padding.len);
- *(to_crypt.ptr + to_crypt.len - 1) = padding.len;
+ generator = generator_create();
+ plain = generate(this, generator);
+ bs = this->aead->get_block_size(this->aead);
+ /* we need at least one byte padding to store the padding length */
+ padding.len = bs - (plain.len % bs);
+ iv.len = this->aead->get_iv_size(this->aead);
+ icv.len = this->aead->get_icv_size(this->aead);
+
+ /* prepare data to authenticate-encrypt:
+ * | IV | plain | padding | ICV |
+ * \____crypt______/ ^
+ * | /
+ * v /
+ * assoc -> + ------->/
+ */
+ free(this->encrypted.ptr);
+ this->encrypted = chunk_alloc(iv.len + plain.len + padding.len + icv.len);
+ iv.ptr = this->encrypted.ptr;
+ memcpy(iv.ptr + iv.len, plain.ptr, plain.len);
+ plain.ptr = iv.ptr + iv.len;
+ padding.ptr = plain.ptr + plain.len;
+ icv.ptr = padding.ptr + padding.len;
+ crypt = chunk_create(plain.ptr, plain.len + padding.len);
+ generator->destroy(generator);
- /* build iv */
- iv.len = block_size;
- rng->allocate_bytes(rng, iv.len, &iv);
+ rng->get_bytes(rng, iv.len, iv.ptr);
+ rng->get_bytes(rng, padding.len - 1, padding.ptr);
+ padding.ptr[padding.len - 1] = padding.len - 1;
rng->destroy(rng);
- DBG3(DBG_ENC, "data before encryption with padding %B", &to_crypt);
+ DBG3(DBG_ENC, "encryption payload encryption:");
+ DBG3(DBG_ENC, "IV %B", &iv);
+ DBG3(DBG_ENC, "plain %B", &plain);
+ DBG3(DBG_ENC, "padding %B", &padding);
+ DBG3(DBG_ENC, "assoc %B", &assoc);
- /* encrypt to_crypt chunk */
- free(this->encrypted.ptr);
- this->crypter->encrypt(this->crypter, to_crypt, iv, &result);
- free(padding.ptr);
- free(to_crypt.ptr);
-
- DBG3(DBG_ENC, "data after encryption %B", &result);
-
- /* build encrypted result with iv and signature */
- this->encrypted.len = iv.len + result.len + this->signer->get_block_size(this->signer);
- free(this->encrypted.ptr);
- this->encrypted.ptr = malloc(this->encrypted.len);
+ this->aead->encrypt(this->aead, crypt, assoc, iv, NULL);
- /* fill in result, signature is left out */
- memcpy(this->encrypted.ptr, iv.ptr, iv.len);
- memcpy(this->encrypted.ptr + iv.len, result.ptr, result.len);
+ DBG3(DBG_ENC, "encrypted %B", &crypt);
+ DBG3(DBG_ENC, "ICV %B", &icv);
- free(result.ptr);
- free(iv.ptr);
- DBG3(DBG_ENC, "data after encryption with IV and (invalid) signature %B",
- &this->encrypted);
+ free(assoc.ptr);
- return SUCCESS;
+ return TRUE;
}
/**
* Parse the payloads after decryption.
*/
-static status_t parse(private_encryption_payload_t *this)
+static status_t parse(private_encryption_payload_t *this, chunk_t plain)
{
parser_t *parser;
- status_t status;
- payload_type_t current_payload_type;
-
- /* build a parser on the decrypted data */
- parser = parser_create(this->decrypted);
+ payload_type_t type;
- current_payload_type = this->next_payload;
- /* parse all payloads */
- while (current_payload_type != NO_PAYLOAD)
+ parser = parser_create(plain);
+ type = this->next_payload;
+ while (type != NO_PAYLOAD)
{
- payload_t *current_payload;
+ payload_t *payload;
- status = parser->parse_payload(parser, current_payload_type, (payload_t**)&current_payload);
- if (status != SUCCESS)
+ if (parser->parse_payload(parser, type, &payload) != SUCCESS)
{
parser->destroy(parser);
return PARSE_ERROR;
}
-
- status = current_payload->verify(current_payload);
- if (status != SUCCESS)
+ if (payload->verify(payload) != SUCCESS)
{
DBG1(DBG_ENC, "%N verification failed",
- payload_type_names, current_payload->get_type(current_payload));
- current_payload->destroy(current_payload);
+ payload_type_names, payload->get_type(payload));
+ payload->destroy(payload);
parser->destroy(parser);
return VERIFY_ERROR;
}
-
- /* get next payload type */
- current_payload_type = current_payload->get_next_type(current_payload);
-
- this->payloads->insert_last(this->payloads,current_payload);
+ type = payload->get_next_type(payload);
+ this->payloads->insert_last(this->payloads, payload);
}
parser->destroy(parser);
- DBG2(DBG_ENC, "succesfully parsed content of encryption payload");
+ DBG2(DBG_ENC, "parsed content of encryption payload");
return SUCCESS;
}
-/**
- * Implementation of encryption_payload_t.encrypt.
- */
-static status_t decrypt(private_encryption_payload_t *this)
+METHOD(encryption_payload_t, decrypt, status_t,
+ private_encryption_payload_t *this, chunk_t assoc)
{
- chunk_t iv, concatenated;
- u_int8_t padding_length;
-
- DBG2(DBG_ENC, "decrypting encryption payload");
- DBG3(DBG_ENC, "data before decryption with IV and (invalid) signature %B",
- &this->encrypted);
+ chunk_t iv, plain, padding, icv, crypt;
+ size_t bs;
- if (this->signer == NULL || this->crypter == NULL)
+ if (this->aead == NULL)
{
- DBG1(DBG_ENC, "could not decrypt, no crypter/signer set");
+ DBG1(DBG_ENC, "decrypting encryption payload failed, transform missing");
return INVALID_STATE;
}
- /* get IV */
- iv.len = this->crypter->get_block_size(this->crypter);
+ /* prepare data to authenticate-decrypt:
+ * | IV | plain | padding | ICV |
+ * \____crypt______/ ^
+ * | /
+ * v /
+ * assoc -> + ------->/
+ */
+ bs = this->aead->get_block_size(this->aead);
+ iv.len = this->aead->get_iv_size(this->aead);
iv.ptr = this->encrypted.ptr;
+ icv.len = this->aead->get_icv_size(this->aead);
+ icv.ptr = this->encrypted.ptr + this->encrypted.len - icv.len;
+ crypt.ptr = iv.ptr + iv.len;
+ crypt.len = this->encrypted.len - iv.len;
- /* point concatenated to data + padding + padding_length*/
- concatenated.ptr = this->encrypted.ptr + iv.len;
- concatenated.len = this->encrypted.len - iv.len -
- this->signer->get_block_size(this->signer);
-
- /* concatenated must be a multiple of block_size of crypter */
- if (concatenated.len < iv.len || concatenated.len % iv.len)
+ if (iv.len + icv.len > this->encrypted.len ||
+ (crypt.len - icv.len) % bs)
{
- DBG1(DBG_ENC, "could not decrypt, invalid input");
+ DBG1(DBG_ENC, "decrypting encryption payload failed, invalid length");
return FAILED;
}
- /* free previus data, if any */
- free(this->decrypted.ptr);
-
- DBG3(DBG_ENC, "data before decryption %B", &concatenated);
-
- this->crypter->decrypt(this->crypter, concatenated, iv, &this->decrypted);
+ assoc = append_header(this, assoc);
- DBG3(DBG_ENC, "data after decryption with padding %B", &this->decrypted);
+ DBG3(DBG_ENC, "encryption payload decryption:");
+ DBG3(DBG_ENC, "IV %B", &iv);
+ DBG3(DBG_ENC, "encrypted %B", &crypt);
+ DBG3(DBG_ENC, "ICV %B", &icv);
+ DBG3(DBG_ENC, "assoc %B", &assoc);
- /* get padding length, sits just bevore signature */
- padding_length = *(this->decrypted.ptr + this->decrypted.len - 1);
- /* add one byte to the padding length, since the padding_length field is
- * not included */
- padding_length++;
-
- /* check size again */
- if (padding_length > concatenated.len || padding_length > this->decrypted.len)
+ if (!this->aead->decrypt(this->aead, crypt, assoc, iv, NULL))
{
- DBG1(DBG_ENC, "decryption failed, invalid padding length found. Invalid key?");
- /* decryption failed :-/ */
+ DBG1(DBG_ENC, "verifying encryption payload integrity failed");
+ free(assoc.ptr);
return FAILED;
}
- this->decrypted.len -= padding_length;
-
- /* free padding */
- this->decrypted.ptr = realloc(this->decrypted.ptr, this->decrypted.len);
- DBG3(DBG_ENC, "data after decryption without padding %B", &this->decrypted);
- DBG2(DBG_ENC, "decryption successful, trying to parse content");
- return parse(this);
-}
+ free(assoc.ptr);
-/**
- * Implementation of encryption_payload_t.set_transforms.
- */
-static void set_transforms(private_encryption_payload_t *this, crypter_t* crypter, signer_t* signer)
-{
- this->signer = signer;
- this->crypter = crypter;
-}
-
-/**
- * Implementation of encryption_payload_t.build_signature.
- */
-static status_t build_signature(private_encryption_payload_t *this, chunk_t data)
-{
- chunk_t data_without_sig = data;
- chunk_t sig;
-
- if (this->signer == NULL)
+ plain = chunk_create(crypt.ptr, crypt.len - icv.len);
+ padding.len = plain.ptr[plain.len - 1] + 1;
+ if (padding.len > plain.len)
{
- DBG1(DBG_ENC, "unable to build signature, no signer set");
- return INVALID_STATE;
+ DBG1(DBG_ENC, "decrypting encryption payload failed, "
+ "padding invalid %B", &crypt);
+ return PARSE_ERROR;
}
+ plain.len -= padding.len;
+ padding.ptr = plain.ptr + plain.len;
- sig.len = this->signer->get_block_size(this->signer);
- data_without_sig.len -= sig.len;
- sig.ptr = data.ptr + data_without_sig.len;
- DBG2(DBG_ENC, "building signature");
- this->signer->get_signature(this->signer, data_without_sig, sig.ptr);
- return SUCCESS;
+ DBG3(DBG_ENC, "plain %B", &plain);
+ DBG3(DBG_ENC, "padding %B", &padding);
+
+ return parse(this, plain);
}
-/**
- * Implementation of encryption_payload_t.verify_signature.
- */
-static status_t verify_signature(private_encryption_payload_t *this, chunk_t data)
+METHOD(encryption_payload_t, set_transform, void,
+ private_encryption_payload_t *this, aead_t* aead)
{
- chunk_t sig, data_without_sig;
- bool valid;
-
- if (this->signer == NULL)
- {
- DBG1(DBG_ENC, "unable to verify signature, no signer set");
- return INVALID_STATE;
- }
- /* find signature in data chunk */
- sig.len = this->signer->get_block_size(this->signer);
- if (data.len <= sig.len)
- {
- DBG1(DBG_ENC, "unable to verify signature, invalid input");
- return FAILED;
- }
- sig.ptr = data.ptr + data.len - sig.len;
-
- /* verify it */
- data_without_sig.len = data.len - sig.len;
- data_without_sig.ptr = data.ptr;
- valid = this->signer->verify_signature(this->signer, data_without_sig, sig);
-
- if (!valid)
- {
- DBG1(DBG_ENC, "signature verification failed");
- return FAILED;
- }
-
- DBG2(DBG_ENC, "signature verification successful");
- return SUCCESS;
+ this->aead = aead;
}
-/**
- * Implementation of payload_t.destroy.
- */
-static void destroy(private_encryption_payload_t *this)
+METHOD2(payload_t, encryption_payload_t, destroy, void,
+ private_encryption_payload_t *this)
{
this->payloads->destroy_offset(this->payloads, offsetof(payload_t, destroy));
free(this->encrypted.ptr);
- free(this->decrypted.ptr);
free(this);
}
@@ -581,39 +457,31 @@ static void destroy(private_encryption_payload_t *this)
*/
encryption_payload_t *encryption_payload_create()
{
- private_encryption_payload_t *this = malloc_thing(private_encryption_payload_t);
-
- /* payload_t interface functions */
- this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
- this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
- this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
- this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
- this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
- this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
- this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
-
- /* public functions */
- this->public.create_payload_iterator = (iterator_t * (*) (encryption_payload_t *,bool)) create_payload_iterator;
- this->public.add_payload = (void (*) (encryption_payload_t *,payload_t *)) add_payload;
- this->public.remove_first_payload = (status_t (*)(encryption_payload_t*, payload_t **)) remove_first_payload;
- this->public.get_payload_count = (size_t (*)(encryption_payload_t*)) get_payload_count;
-
- this->public.encrypt = (status_t (*) (encryption_payload_t *)) encrypt;
- this->public.decrypt = (status_t (*) (encryption_payload_t *)) decrypt;
- this->public.set_transforms = (void (*) (encryption_payload_t*,crypter_t*,signer_t*)) set_transforms;
- this->public.build_signature = (status_t (*) (encryption_payload_t*, chunk_t)) build_signature;
- this->public.verify_signature = (status_t (*) (encryption_payload_t*, chunk_t)) verify_signature;
- this->public.destroy = (void (*) (encryption_payload_t *)) destroy;
-
- /* set default values of the fields */
- this->critical = FALSE;
- this->next_payload = NO_PAYLOAD;
- this->payload_length = ENCRYPTION_PAYLOAD_HEADER_LENGTH;
- this->encrypted = chunk_empty;
- this->decrypted = chunk_empty;
- this->signer = NULL;
- this->crypter = NULL;
- this->payloads = linked_list_create();
-
- return (&(this->public));
+ private_encryption_payload_t *this;
+
+ INIT(this,
+ .public = {
+ .payload_interface = {
+ .verify = _verify,
+ .get_encoding_rules = _get_encoding_rules,
+ .get_length = _get_length,
+ .get_next_type = _get_next_type,
+ .set_next_type = _set_next_type,
+ .get_type = _get_type,
+ .destroy = _destroy,
+ },
+ .get_length = _get_length,
+ .add_payload = _add_payload,
+ .remove_payload = _remove_payload,
+ .set_transform = _set_transform,
+ .encrypt = _encrypt,
+ .decrypt = _decrypt,
+ .destroy = _destroy,
+ },
+ .next_payload = NO_PAYLOAD,
+ .payload_length = ENCRYPTION_PAYLOAD_HEADER_LENGTH,
+ .payloads = linked_list_create(),
+ );
+
+ return &this->public;
}
diff --git a/src/libcharon/encoding/payloads/encryption_payload.h b/src/libcharon/encoding/payloads/encryption_payload.h
index ac5326b87..e99c42fb7 100644
--- a/src/libcharon/encoding/payloads/encryption_payload.h
+++ b/src/libcharon/encoding/payloads/encryption_payload.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -25,45 +26,30 @@
typedef struct encryption_payload_t encryption_payload_t;
#include <library.h>
-#include <crypto/crypters/crypter.h>
-#include <crypto/signers/signer.h>
+#include <crypto/aead.h>
#include <encoding/payloads/payload.h>
-#include <utils/linked_list.h>
/**
* Encrpytion payload length in bytes without IV and following data.
*/
#define ENCRYPTION_PAYLOAD_HEADER_LENGTH 4
-
/**
* The encryption payload as described in RFC section 3.14.
- *
- * Before any crypt/decrypt/sign/verify operation can occur,
- * the transforms must be set. After that, a parsed encryption payload
- * can be decrypted, which also will parse the contained payloads.
- * Encryption is done the same way, added payloads will get generated
- * and then encrypted.
- * For signature building, there is the FULL packet needed. Meaning it
- * must be builded after generation of all payloads and the encryption
- * of the encryption payload.
- * Signature verificatin is done before decryption.
*/
struct encryption_payload_t {
+
/**
* Implements payload_t interface.
*/
payload_t payload_interface;
/**
- * Creates an iterator for all contained payloads.
+ * Get the payload length.
*
- * iterator_t object has to get destroyed by the caller.
- *
- * @param forward iterator direction (TRUE: front to end)
- * return created iterator_t object
+ * @return (expected) payload length
*/
- iterator_t *(*create_payload_iterator) (encryption_payload_t *this, bool forward);
+ size_t (*get_length)(encryption_payload_t *this);
/**
* Adds a payload to this encryption payload.
@@ -73,89 +59,39 @@ struct encryption_payload_t {
void (*add_payload) (encryption_payload_t *this, payload_t *payload);
/**
- * Reove the last payload in the contained payload list.
+ * Remove the first payload in the list
*
* @param payload removed payload
- * @return
- * - SUCCESS, or
- * - NOT_FOUND if list empty
- */
- status_t (*remove_first_payload) (encryption_payload_t *this, payload_t **payload);
-
- /**
- * Get the number of payloads.
- *
- * @return number of contained payloads
+ * @return payload, NULL if none left
*/
- size_t (*get_payload_count) (encryption_payload_t *this);
+ payload_t* (*remove_payload)(encryption_payload_t *this);
/**
- * Set transforms to use.
- *
- * To decryption, encryption, signature building and verifying,
- * the payload needs a crypter and a signer object.
+ * Set the AEAD transform to use.
*
- * @warning Do NOT call this function again after encryption, since
- * the signer must be the same while encrypting and signature building!
- *
- * @param crypter crypter_t to use for data de-/encryption
- * @param signer signer_t to use for data signing/verifying
+ * @param aead aead transform to use
*/
- void (*set_transforms) (encryption_payload_t *this, crypter_t *crypter, signer_t *signer);
+ void (*set_transform) (encryption_payload_t *this, aead_t *aead);
/**
- * Generate and encrypt contained payloads.
- *
- * This function generates the content for added payloads
- * and encrypts them. Signature is not built, since we need
- * additional data (the full message).
+ * Generate, encrypt and sign contained payloads.
*
- * @return SUCCESS, or INVALID_STATE if transforms not set
+ * @param assoc associated data
+ * @return TRUE if encrypted
*/
- status_t (*encrypt) (encryption_payload_t *this);
+ bool (*encrypt) (encryption_payload_t *this, chunk_t assoc);
/**
- * Decrypt and parse contained payloads.
- *
- * This function decrypts the contained data. After,
- * the payloads are parsed internally and are accessible
- * via the iterator.
- *
- * @return
- * - SUCCESS, or
- * - INVALID_STATE if transforms not set, or
- * - FAILED if data is invalid
- */
- status_t (*decrypt) (encryption_payload_t *this);
-
- /**
- * Build the signature.
- *
- * The signature is built over the FULL message, so the header
- * and every payload (inclusive this one) must already be generated.
- * The generated message is supplied via the data paramater.
- *
- * @param data chunk contains the already generated message
- * @return
- * - SUCCESS, or
- * - INVALID_STATE if transforms not set
- */
- status_t (*build_signature) (encryption_payload_t *this, chunk_t data);
-
- /**
- * Verify the signature.
- *
- * Since the signature is built over the full message, we need
- * this data to do the verification. The message data
- * is supplied via the data argument.
- *
- * @param data chunk contains the message
- * @return
- * - SUCCESS, or
- * - FAILED if signature invalid, or
- * - INVALID_STATE if transforms not set
+ * Decrypt, verify and parse contained payloads.
+ *
+ * @param assoc associated data
+ * - SUCCESS if parsing successful
+ * - PARSE_ERROR if sub-payload parsing failed
+ * - VERIFY_ERROR if sub-payload verification failed
+ * - FAILED if integrity check failed
+ * - INVALID_STATE if aead not supplied, but needed
*/
- status_t (*verify_signature) (encryption_payload_t *this, chunk_t data);
+ status_t (*decrypt) (encryption_payload_t *this, chunk_t assoc);
/**
* Destroys an encryption_payload_t object.
@@ -166,7 +102,7 @@ struct encryption_payload_t {
/**
* Creates an empty encryption_payload_t object.
*
- * @return encryption_payload_t object
+ * @return encryption_payload_t object
*/
encryption_payload_t *encryption_payload_create(void);
diff --git a/src/libcharon/encoding/payloads/notify_payload.c b/src/libcharon/encoding/payloads/notify_payload.c
index 469698ef5..a56fd1869 100644
--- a/src/libcharon/encoding/payloads/notify_payload.c
+++ b/src/libcharon/encoding/payloads/notify_payload.c
@@ -41,7 +41,7 @@ ENUM_NEXT(notify_type_names, INVALID_KE_PAYLOAD, INVALID_KE_PAYLOAD, NO_PROPOSAL
"INVALID_KE_PAYLOAD");
ENUM_NEXT(notify_type_names, AUTHENTICATION_FAILED, AUTHENTICATION_FAILED, INVALID_KE_PAYLOAD,
"AUTHENTICATION_FAILED");
-ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, USE_ASSIGNED_HoA, AUTHENTICATION_FAILED,
+ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED,
"SINGLE_PAIR_REQUIRED",
"NO_ADDITIONAL_SAS",
"INTERNAL_ADDRESS_FAILURE",
@@ -50,10 +50,12 @@ ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, USE_ASSIGNED_HoA, AUTHENTICAT
"INVALID_SELECTORS",
"UNACCEPTABLE_ADDRESSES",
"UNEXPECTED_NAT_DETECTED",
- "USE_ASSIGNED_HoA");
-ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, USE_ASSIGNED_HoA,
+ "USE_ASSIGNED_HoA",
+ "TEMPORARY_FAILURE",
+ "CHILD_SA_NOT_FOUND");
+ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_FOUND,
"ME_CONNECT_FAILED");
-ENUM_NEXT(notify_type_names, INITIAL_CONTACT, LINK_ID, ME_CONNECT_FAILED,
+ENUM_NEXT(notify_type_names, INITIAL_CONTACT, EAP_ONLY_AUTHENTICATION, ME_CONNECT_FAILED,
"INITIAL_CONTACT",
"SET_WINDOW_SIZE",
"ADDITIONAL_TS_POSSIBLE",
@@ -84,8 +86,9 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, LINK_ID, ME_CONNECT_FAILED,
"TICKET_ACK",
"TICKET_NACK",
"TICKET_OPAQUE",
- "LINK_ID");
-ENUM_NEXT(notify_type_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, LINK_ID,
+ "LINK_ID",
+ "USE_WESP_MODE",
+ "ROHC_SUPPORTED",
"EAP_ONLY_AUTHENTICATION");
ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
"USE_BEET_MODE");
@@ -117,7 +120,7 @@ ENUM_NEXT(notify_type_short_names, INVALID_KE_PAYLOAD, INVALID_KE_PAYLOAD, NO_PR
"INVAL_KE");
ENUM_NEXT(notify_type_short_names, AUTHENTICATION_FAILED, AUTHENTICATION_FAILED, INVALID_KE_PAYLOAD,
"AUTH_FAILED");
-ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, USE_ASSIGNED_HoA, AUTHENTICATION_FAILED,
+ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED,
"SINGLE_PAIR",
"NO_ADD_SAS",
"INT_ADDR_FAIL",
@@ -126,10 +129,12 @@ ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, USE_ASSIGNED_HoA, AUTHE
"INVAL_SEL",
"UNACCEPT_ADDR",
"UNEXPECT_NAT",
- "ASSIGNED_HoA");
-ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, USE_ASSIGNED_HoA,
+ "ASSIGNED_HoA",
+ "TEMP_FAIL",
+ "NO_CHILD_SA");
+ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_FOUND,
"ME_CONN_FAIL");
-ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, LINK_ID, ME_CONNECT_FAILED,
+ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, EAP_ONLY_AUTHENTICATION, ME_CONNECT_FAILED,
"INIT_CONTACT",
"SET_WINSIZE",
"ADD_TS_POSS",
@@ -160,8 +165,9 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, LINK_ID, ME_CONNECT_FAILED,
"TKT_ACK",
"TKT_NACK",
"TKT_OPAK",
- "LINK_ID");
-ENUM_NEXT(notify_type_short_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, LINK_ID,
+ "LINK_ID",
+ "WESP_MODE",
+ "ROHC_SUP",
"EAP_ONLY");
ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
"BEET_MODE");
@@ -238,29 +244,29 @@ struct private_notify_payload_t {
*/
encoding_rule_t notify_payload_encodings[] = {
/* 1 Byte next payload type, stored in the field next_payload */
- { U_INT_8, offsetof(private_notify_payload_t, next_payload) },
+ { U_INT_8, offsetof(private_notify_payload_t, next_payload) },
/* the critical bit */
- { FLAG, offsetof(private_notify_payload_t, critical) },
+ { FLAG, offsetof(private_notify_payload_t, critical) },
/* 7 Bit reserved bits, nowhere stored */
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
/* Length of the whole payload*/
- { PAYLOAD_LENGTH, offsetof(private_notify_payload_t, payload_length) },
+ { PAYLOAD_LENGTH, offsetof(private_notify_payload_t, payload_length) },
/* Protocol ID as 8 bit field*/
- { U_INT_8, offsetof(private_notify_payload_t, protocol_id) },
+ { U_INT_8, offsetof(private_notify_payload_t, protocol_id) },
/* SPI Size as 8 bit field*/
- { SPI_SIZE, offsetof(private_notify_payload_t, spi_size) },
+ { SPI_SIZE, offsetof(private_notify_payload_t, spi_size) },
/* Notify message type as 16 bit field*/
{ U_INT_16, offsetof(private_notify_payload_t, notify_type) },
/* SPI as variable length field*/
{ SPI, offsetof(private_notify_payload_t, spi) },
/* Key Exchange Data is from variable size */
- { NOTIFICATION_DATA, offsetof(private_notify_payload_t, notification_data) }
+ { NOTIFICATION_DATA, offsetof(private_notify_payload_t, notification_data) }
};
/*
diff --git a/src/libcharon/encoding/payloads/notify_payload.h b/src/libcharon/encoding/payloads/notify_payload.h
index 0e1bc23b8..8abc236e1 100644
--- a/src/libcharon/encoding/payloads/notify_payload.h
+++ b/src/libcharon/encoding/payloads/notify_payload.h
@@ -64,6 +64,9 @@ enum notify_type_t {
UNEXPECTED_NAT_DETECTED = 41,
/* mobile IPv6 bootstrapping, RFC 5026 */
USE_ASSIGNED_HoA = 42,
+ /* IKEv2 RFC 5996 */
+ TEMPORARY_FAILURE = 43,
+ CHILD_SA_NOT_FOUND = 44,
/* IKE-ME, private use */
ME_CONNECT_FAILED = 8192,
@@ -98,16 +101,21 @@ enum notify_type_t {
REDIRECT_SUPPORTED = 16406,
REDIRECT = 16407,
REDIRECTED_FROM = 16408,
- /* draft-ietf-ipsecme-ikev2-resumption, assigned by IANA */
+ /* session resumption, RFC 5723 */
TICKET_LT_OPAQUE = 16409,
TICKET_REQUEST = 16410,
TICKET_ACK = 16411,
TICKET_NACK = 16412,
TICKET_OPAQUE = 16413,
+ /* IPv6 configuration, RFC 5739 */
LINK_ID = 16414,
+ /* wrapped esp, RFC 5840 */
+ USE_WESP_MODE = 16415,
+ /* robust header compression, RFC 5857 */
+ ROHC_SUPPORTED = 16416,
+ /* EAP-only authentication, RFC 5998 */
+ EAP_ONLY_AUTHENTICATION = 16417,
- /* draft-eronen-ipsec-ikev2-eap-auth, not assigned by IANA yet */
- EAP_ONLY_AUTHENTICATION = 40960,
/* BEET mode, not even a draft yet. private use */
USE_BEET_MODE = 40961,
/* IKE-ME, private use */
@@ -144,7 +152,7 @@ struct notify_payload_t {
/**
* Gets the protocol id of this payload.
*
- * @return protocol id of this payload
+ * @return protocol id of this payload
*/
u_int8_t (*get_protocol_id) (notify_payload_t *this);
@@ -158,7 +166,7 @@ struct notify_payload_t {
/**
* Gets the notify message type of this payload.
*
- * @return notify message type of this payload
+ * @return notify message type of this payload
*/
notify_type_t (*get_notify_type) (notify_payload_t *this);
@@ -174,7 +182,7 @@ struct notify_payload_t {
*
* This is only valid for notifys with protocol AH|ESP
*
- * @return SPI value
+ * @return SPI value
*/
u_int32_t (*get_spi) (notify_payload_t *this);
@@ -192,7 +200,7 @@ struct notify_payload_t {
*
* Returned data are not copied.
*
- * @return chunk_t pointing to the value
+ * @return chunk_t pointing to the value
*/
chunk_t (*get_notification_data) (notify_payload_t *this);
@@ -201,7 +209,7 @@ struct notify_payload_t {
*
* @warning Value is getting copied.
*
- * @param notification_data chunk_t pointing to the value to set
+ * @param notification_data chunk_t pointing to the value to set
*/
void (*set_notification_data) (notify_payload_t *this,
chunk_t notification_data);
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c
index c93f73a68..985b03255 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.c
+++ b/src/libcharon/encoding/payloads/proposal_substructure.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -24,20 +24,18 @@
#include <utils/linked_list.h>
#include <daemon.h>
-
/**
* IKEv1 Value for a proposal payload.
*/
#define PROPOSAL_TYPE_VALUE 2
-
typedef struct private_proposal_substructure_t private_proposal_substructure_t;
/**
* Private data of an proposal_substructure_t object.
- *
*/
struct private_proposal_substructure_t {
+
/**
* Public proposal_substructure_t interface.
*/
@@ -92,24 +90,24 @@ struct private_proposal_substructure_t {
*/
encoding_rule_t proposal_substructure_encodings[] = {
/* 1 Byte next payload type, stored in the field next_payload */
- { U_INT_8, offsetof(private_proposal_substructure_t, next_payload) },
+ { U_INT_8, offsetof(private_proposal_substructure_t, next_payload) },
/* Reserved Byte is skipped */
- { RESERVED_BYTE, 0 },
+ { RESERVED_BYTE, 0 },
/* Length of the whole proposal substructure payload*/
- { PAYLOAD_LENGTH, offsetof(private_proposal_substructure_t, proposal_length) },
+ { PAYLOAD_LENGTH, offsetof(private_proposal_substructure_t, proposal_length) },
/* proposal number is a number of 8 bit */
- { U_INT_8, offsetof(private_proposal_substructure_t, proposal_number) },
+ { U_INT_8, offsetof(private_proposal_substructure_t, proposal_number) },
/* protocol ID is a number of 8 bit */
- { U_INT_8, offsetof(private_proposal_substructure_t, protocol_id) },
+ { U_INT_8, offsetof(private_proposal_substructure_t, protocol_id) },
/* SPI Size has its own type */
- { SPI_SIZE, offsetof(private_proposal_substructure_t, spi_size) },
+ { SPI_SIZE, offsetof(private_proposal_substructure_t, spi_size) },
/* Number of transforms is a number of 8 bit */
- { U_INT_8, offsetof(private_proposal_substructure_t, transforms_count) },
+ { U_INT_8, offsetof(private_proposal_substructure_t, transforms_count) },
/* SPI is a chunk of variable size*/
- { SPI, offsetof(private_proposal_substructure_t, spi) },
+ { SPI, offsetof(private_proposal_substructure_t, spi) },
/* Transforms are stored in a transform substructure,
offset points to a linked_list_t pointer */
- { TRANSFORMS, offsetof(private_proposal_substructure_t, transforms) }
+ { TRANSFORMS, offsetof(private_proposal_substructure_t, transforms) }
};
/*
@@ -128,16 +126,14 @@ encoding_rule_t proposal_substructure_encodings[] = {
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-/**
- * Implementation of payload_t.verify.
- */
-static status_t verify(private_proposal_substructure_t *this)
+METHOD(payload_t, verify, status_t,
+ private_proposal_substructure_t *this)
{
status_t status = SUCCESS;
- iterator_t *iterator;
- payload_t *current_transform;
+ enumerator_t *enumerator;
+ payload_t *current;
- if ((this->next_payload != NO_PAYLOAD) && (this->next_payload != 2))
+ if (this->next_payload != NO_PAYLOAD && this->next_payload != 2)
{
/* must be 0 or 2 */
DBG1(DBG_ENC, "inconsistent next payload");
@@ -169,61 +165,46 @@ static status_t verify(private_proposal_substructure_t *this)
}
break;
default:
- DBG1(DBG_ENC, "invalid proposal protocol (%d)", this->protocol_id);
- return FAILED;
- }
- if ((this->protocol_id == 0) || (this->protocol_id >= 4))
- {
- /* reserved are not supported */
- DBG1(DBG_ENC, "invalid protocol");
- return FAILED;
+ break;
}
-
- iterator = this->transforms->create_iterator(this->transforms,TRUE);
- while(iterator->iterate(iterator, (void**)&current_transform))
+ enumerator = this->transforms->create_enumerator(this->transforms);
+ while (enumerator->enumerate(enumerator, &current))
{
- status = current_transform->verify(current_transform);
+ status = current->verify(current);
if (status != SUCCESS)
{
DBG1(DBG_ENC, "TRANSFORM_SUBSTRUCTURE verification failed");
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* proposal number is checked in SA payload */
return status;
}
-/**
- * Implementation of payload_t.get_encoding_rules.
- */
-static void get_encoding_rules(private_proposal_substructure_t *this, encoding_rule_t **rules, size_t *rule_count)
+METHOD(payload_t, get_encoding_rules, void,
+ private_proposal_substructure_t *this, encoding_rule_t **rules,
+ size_t *rule_count)
{
*rules = proposal_substructure_encodings;
- *rule_count = sizeof(proposal_substructure_encodings) / sizeof(encoding_rule_t);
+ *rule_count = countof(proposal_substructure_encodings);
}
-/**
- * Implementation of payload_t.get_type.
- */
-static payload_type_t get_type(private_proposal_substructure_t *this)
+METHOD(payload_t, get_type, payload_type_t,
+ private_proposal_substructure_t *this)
{
return PROPOSAL_SUBSTRUCTURE;
}
-/**
- * Implementation of payload_t.get_next_type.
- */
-static payload_type_t get_next_type(private_proposal_substructure_t *this)
+METHOD(payload_t, get_next_type, payload_type_t,
+ private_proposal_substructure_t *this)
{
- return (this->next_payload);
+ return this->next_payload;
}
-/**
- * Implementation of payload_t.set_next_type.
- */
-static void set_next_type(private_proposal_substructure_t *this,payload_type_t type)
+METHOD(payload_t, set_next_type, void,
+ private_proposal_substructure_t *this, payload_type_t type)
{
}
@@ -250,145 +231,88 @@ static void compute_length(private_proposal_substructure_t *this)
this->proposal_length = length;
}
-/**
- * Implementation of payload_t.get_length.
- */
-static size_t get_length(private_proposal_substructure_t *this)
+METHOD(payload_t, get_length, size_t,
+ private_proposal_substructure_t *this)
{
compute_length(this);
return this->proposal_length;
}
/**
- * Implementation of proposal_substructure_t.create_transform_substructure_iterator.
- */
-static iterator_t *create_transform_substructure_iterator (private_proposal_substructure_t *this,bool forward)
-{
- return (this->transforms->create_iterator(this->transforms,forward));
-}
-
-/**
- * Implementation of proposal_substructure_t.add_transform_substructure.
+ * Add a transform substructure to the proposal
*/
-static void add_transform_substructure (private_proposal_substructure_t *this,transform_substructure_t *transform)
+static void add_transform_substructure(private_proposal_substructure_t *this,
+ transform_substructure_t *transform)
{
- status_t status;
if (this->transforms->get_count(this->transforms) > 0)
{
- transform_substructure_t *last_transform;
- status = this->transforms->get_last(this->transforms,(void **) &last_transform);
- /* last transform is now not anymore last one */
- last_transform->set_is_last_transform(last_transform,FALSE);
+ transform_substructure_t *last;
+ this->transforms->get_last(this->transforms, (void **)&last);
+ last->set_is_last_transform(last, FALSE);
}
transform->set_is_last_transform(transform,TRUE);
-
- this->transforms->insert_last(this->transforms,(void *) transform);
+ this->transforms->insert_last(this->transforms, transform);
compute_length(this);
}
-/**
- * Implementation of proposal_substructure_t.proposal_substructure_t.
- */
-static void set_is_last_proposal (private_proposal_substructure_t *this, bool is_last)
+METHOD(proposal_substructure_t, set_is_last_proposal, void,
+ private_proposal_substructure_t *this, bool is_last)
{
- this->next_payload = (is_last) ? 0: PROPOSAL_TYPE_VALUE;
+ this->next_payload = is_last ? 0 : PROPOSAL_TYPE_VALUE;
}
-/**
- * Implementation of proposal_substructure_t.set_proposal_number.
- */
-static void set_proposal_number(private_proposal_substructure_t *this,u_int8_t proposal_number)
+METHOD(proposal_substructure_t, set_proposal_number, void,
+ private_proposal_substructure_t *this,u_int8_t proposal_number)
{
this->proposal_number = proposal_number;
}
-/**
- * Implementation of proposal_substructure_t.get_proposal_number.
- */
-static u_int8_t get_proposal_number (private_proposal_substructure_t *this)
+METHOD(proposal_substructure_t, get_proposal_number, u_int8_t,
+ private_proposal_substructure_t *this)
{
- return (this->proposal_number);
+ return this->proposal_number;
}
-/**
- * Implementation of proposal_substructure_t.set_protocol_id.
- */
-static void set_protocol_id(private_proposal_substructure_t *this,u_int8_t protocol_id)
+METHOD(proposal_substructure_t, set_protocol_id, void,
+ private_proposal_substructure_t *this,u_int8_t protocol_id)
{
this->protocol_id = protocol_id;
}
-/**
- * Implementation of proposal_substructure_t.get_protocol_id.
- */
-static u_int8_t get_protocol_id(private_proposal_substructure_t *this)
+METHOD(proposal_substructure_t, get_protocol_id, u_int8_t,
+ private_proposal_substructure_t *this)
{
- return (this->protocol_id);
+ return this->protocol_id;
}
-/**
- * Implementation of proposal_substructure_t.set_spi.
- */
-static void set_spi(private_proposal_substructure_t *this, chunk_t spi)
+METHOD(proposal_substructure_t, set_spi, void,
+ private_proposal_substructure_t *this, chunk_t spi)
{
- /* first delete already set spi value */
- if (this->spi.ptr != NULL)
- {
- free(this->spi.ptr);
- this->spi.ptr = NULL;
- this->spi.len = 0;
- compute_length(this);
- }
-
- this->spi.ptr = clalloc(spi.ptr,spi.len);
- this->spi.len = spi.len;
+ free(this->spi.ptr);
+ this->spi = chunk_clone(spi);
this->spi_size = spi.len;
compute_length(this);
}
-/**
- * Implementation of proposal_substructure_t.get_spi.
- */
-static chunk_t get_spi(private_proposal_substructure_t *this)
-{
- chunk_t spi;
- spi.ptr = this->spi.ptr;
- spi.len = this->spi.len;
-
- return spi;
-}
-
-/**
- * Implementation of proposal_substructure_t.get_transform_count.
- */
-static size_t get_transform_count (private_proposal_substructure_t *this)
-{
- return this->transforms->get_count(this->transforms);
-}
-
-/**
- * Implementation of proposal_substructure_t.get_spi_size.
- */
-static size_t get_spi_size (private_proposal_substructure_t *this)
+METHOD(proposal_substructure_t, get_spi, chunk_t,
+ private_proposal_substructure_t *this)
{
- return this->spi.len;
+ return this->spi;
}
-/**
- * Implementation of proposal_substructure_t.get_proposal.
- */
-proposal_t* get_proposal(private_proposal_substructure_t *this)
+METHOD(proposal_substructure_t, get_proposal, proposal_t*,
+ private_proposal_substructure_t *this)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
transform_substructure_t *transform;
proposal_t *proposal;
u_int64_t spi;
- proposal = proposal_create(this->protocol_id);
+ proposal = proposal_create(this->protocol_id, this->proposal_number);
- iterator = this->transforms->create_iterator(this->transforms, TRUE);
- while (iterator->iterate(iterator, (void**)&transform))
+ enumerator = this->transforms->create_enumerator(this->transforms);
+ while (enumerator->enumerate(enumerator, &transform))
{
transform_type_t transform_type;
u_int16_t transform_id;
@@ -400,7 +324,7 @@ proposal_t* get_proposal(private_proposal_substructure_t *this)
proposal->add_algorithm(proposal, transform_type, transform_id, key_length);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
switch (this->spi.len)
{
@@ -418,42 +342,36 @@ proposal_t* get_proposal(private_proposal_substructure_t *this)
return proposal;
}
-/**
- * Implementation of proposal_substructure_t.clone.
- */
-static private_proposal_substructure_t* clone_(private_proposal_substructure_t *this)
+METHOD(proposal_substructure_t, clone_, proposal_substructure_t*,
+ private_proposal_substructure_t *this)
{
private_proposal_substructure_t *clone;
- iterator_t *transforms;
- transform_substructure_t *current_transform;
+ enumerator_t *enumerator;
+ transform_substructure_t *current;
- clone = (private_proposal_substructure_t *) proposal_substructure_create();
+ clone = (private_proposal_substructure_t*)proposal_substructure_create();
clone->next_payload = this->next_payload;
clone->proposal_number = this->proposal_number;
clone->protocol_id = this->protocol_id;
clone->spi_size = this->spi_size;
if (this->spi.ptr != NULL)
{
- clone->spi.ptr = clalloc(this->spi.ptr,this->spi.len);
+ clone->spi.ptr = clalloc(this->spi.ptr, this->spi.len);
clone->spi.len = this->spi.len;
}
-
- transforms = this->transforms->create_iterator(this->transforms,FALSE);
- while (transforms->iterate(transforms, (void**)&current_transform))
+ enumerator = this->transforms->create_enumerator(this->transforms);
+ while (enumerator->enumerate(enumerator, &current))
{
- current_transform = current_transform->clone(current_transform);
- clone->public.add_transform_substructure(&clone->public, current_transform);
+ current = current->clone(current);
+ add_transform_substructure(clone, current);
}
- transforms->destroy(transforms);
+ enumerator->destroy(enumerator);
- return clone;
+ return &clone->public;
}
-/**
- * Implements payload_t's and proposal_substructure_t's destroy function.
- * See #payload_s.destroy or proposal_substructure_s.destroy for description.
- */
-static void destroy(private_proposal_substructure_t *this)
+METHOD2(payload_t, proposal_substructure_t, destroy, void,
+ private_proposal_substructure_t *this)
{
this->transforms->destroy_offset(this->transforms,
offsetof(transform_substructure_t, destroy));
@@ -466,53 +384,42 @@ static void destroy(private_proposal_substructure_t *this)
*/
proposal_substructure_t *proposal_substructure_create()
{
- private_proposal_substructure_t *this = malloc_thing(private_proposal_substructure_t);
-
- /* interface functions */
- this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
- this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
- this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
- this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
- this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
- this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
- this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
-
-
- /* public functions */
- this->public.create_transform_substructure_iterator = (iterator_t* (*) (proposal_substructure_t *,bool)) create_transform_substructure_iterator;
- this->public.add_transform_substructure = (void (*) (proposal_substructure_t *,transform_substructure_t *)) add_transform_substructure;
- this->public.set_proposal_number = (void (*) (proposal_substructure_t *,u_int8_t))set_proposal_number;
- this->public.get_proposal_number = (u_int8_t (*) (proposal_substructure_t *)) get_proposal_number;
- this->public.set_protocol_id = (void (*) (proposal_substructure_t *,u_int8_t))set_protocol_id;
- this->public.get_protocol_id = (u_int8_t (*) (proposal_substructure_t *)) get_protocol_id;
- this->public.set_is_last_proposal = (void (*) (proposal_substructure_t *,bool)) set_is_last_proposal;
- this->public.get_proposal = (proposal_t* (*) (proposal_substructure_t*))get_proposal;
- this->public.set_spi = (void (*) (proposal_substructure_t *,chunk_t))set_spi;
- this->public.get_spi = (chunk_t (*) (proposal_substructure_t *)) get_spi;
- this->public.get_transform_count = (size_t (*) (proposal_substructure_t *)) get_transform_count;
- this->public.get_spi_size = (size_t (*) (proposal_substructure_t *)) get_spi_size;
- this->public.clone = (proposal_substructure_t * (*) (proposal_substructure_t *)) clone_;
- this->public.destroy = (void (*) (proposal_substructure_t *)) destroy;
-
- /* set default values of the fields */
- this->next_payload = NO_PAYLOAD;
- this->proposal_length = 0;
- this->proposal_number = 0;
- this->protocol_id = 0;
- this->transforms_count = 0;
- this->spi_size = 0;
- this->spi.ptr = NULL;
- this->spi.len = 0;
-
- this->transforms = linked_list_create();
-
- return (&(this->public));
+ private_proposal_substructure_t *this;
+
+ INIT(this,
+ .public = {
+ .payload_interface = {
+ .verify = _verify,
+ .get_encoding_rules = _get_encoding_rules,
+ .get_length = _get_length,
+ .get_next_type = _get_next_type,
+ .set_next_type = _set_next_type,
+ .get_type = _get_type,
+ .destroy = _destroy,
+ },
+ .set_proposal_number = _set_proposal_number,
+ .get_proposal_number = _get_proposal_number,
+ .set_protocol_id = _set_protocol_id,
+ .get_protocol_id = _get_protocol_id,
+ .set_is_last_proposal = _set_is_last_proposal,
+ .get_proposal = _get_proposal,
+ .set_spi = _set_spi,
+ .get_spi = _get_spi,
+ .clone = _clone_,
+ .destroy = _destroy,
+ },
+ .next_payload = NO_PAYLOAD,
+ .transforms = linked_list_create(),
+ );
+
+ return &this->public;
}
/*
* Described in header.
*/
-proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal)
+proposal_substructure_t *proposal_substructure_create_from_proposal(
+ proposal_t *proposal)
{
transform_substructure_t *transform;
private_proposal_substructure_t *this;
@@ -591,7 +498,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
default:
break;
}
- this->proposal_number = 0;
+ this->proposal_number = proposal->get_number(proposal);
this->protocol_id = proposal->get_protocol(proposal);
return &this->public;
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.h b/src/libcharon/encoding/payloads/proposal_substructure.h
index 4934802af..56e7184b6 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.h
+++ b/src/libcharon/encoding/payloads/proposal_substructure.h
@@ -42,36 +42,19 @@ typedef struct proposal_substructure_t proposal_substructure_t;
* The PROPOSAL SUBSTRUCTURE format is described in RFC section 3.3.1.
*/
struct proposal_substructure_t {
+
/**
* The payload_t interface.
*/
payload_t payload_interface;
/**
- * Creates an iterator of stored transform_substructure_t objects.
- *
- * @param forward iterator direction (TRUE: front to end)
- * @return created iterator_t object
- */
- iterator_t *(*create_transform_substructure_iterator) (
- proposal_substructure_t *this, bool forward);
-
- /**
- * Adds a transform_substructure_t object to this object.
- *
- * @param transform transform_substructure_t object to add
- */
- void (*add_transform_substructure) (proposal_substructure_t *this,
- transform_substructure_t *transform);
-
- /**
* Sets the proposal number of current proposal.
*
* @param id proposal number to set
*/
void (*set_proposal_number) (proposal_substructure_t *this,
u_int8_t proposal_number);
-
/**
* get proposal number of current proposal.
*
@@ -80,20 +63,6 @@ struct proposal_substructure_t {
u_int8_t (*get_proposal_number) (proposal_substructure_t *this);
/**
- * get the number of transforms in current proposal.
- *
- * @return transform count in current proposal
- */
- size_t (*get_transform_count) (proposal_substructure_t *this);
-
- /**
- * get size of the set spi in bytes.
- *
- * @return size of the spi in bytes
- */
- size_t (*get_spi_size) (proposal_substructure_t *this);
-
- /**
* Sets the protocol id of current proposal.
*
* @param id protocol id to set
diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c
index 187a8fee0..4fbd4cac0 100644
--- a/src/libcharon/encoding/payloads/sa_payload.c
+++ b/src/libcharon/encoding/payloads/sa_payload.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -27,9 +27,9 @@ typedef struct private_sa_payload_t private_sa_payload_t;
/**
* Private data of an sa_payload_t object.
- *
*/
struct private_sa_payload_t {
+
/**
* Public sa_payload_t interface.
*/
@@ -61,26 +61,25 @@ struct private_sa_payload_t {
*
* The defined offsets are the positions in a object of type
* private_sa_payload_t.
- *
*/
encoding_rule_t sa_payload_encodings[] = {
/* 1 Byte next payload type, stored in the field next_payload */
- { U_INT_8, offsetof(private_sa_payload_t, next_payload) },
+ { U_INT_8, offsetof(private_sa_payload_t, next_payload) },
/* the critical bit */
- { FLAG, offsetof(private_sa_payload_t, critical) },
+ { FLAG, offsetof(private_sa_payload_t, critical) },
/* 7 Bit reserved bits, nowhere stored */
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
- { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
+ { RESERVED_BIT, 0 },
/* Length of the whole SA payload*/
- { PAYLOAD_LENGTH, offsetof(private_sa_payload_t, payload_length) },
+ { PAYLOAD_LENGTH, offsetof(private_sa_payload_t, payload_length) },
/* Proposals are stored in a proposal substructure,
offset points to a linked_list_t pointer */
- { PROPOSALS, offsetof(private_sa_payload_t, proposals) }
+ { PROPOSALS, offsetof(private_sa_payload_t, proposals) },
};
/*
@@ -95,26 +94,23 @@ encoding_rule_t sa_payload_encodings[] = {
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
-/**
- * Implementation of payload_t.verify.
- */
-static status_t verify(private_sa_payload_t *this)
+METHOD(payload_t, verify, status_t,
+ private_sa_payload_t *this)
{
int expected_number = 1, current_number;
status_t status = SUCCESS;
- iterator_t *iterator;
- proposal_substructure_t *current_proposal;
+ enumerator_t *enumerator;
+ proposal_substructure_t *substruct;
bool first = TRUE;
/* check proposal numbering */
- iterator = this->proposals->create_iterator(this->proposals,TRUE);
-
- while(iterator->iterate(iterator, (void**)&current_proposal))
+ enumerator = this->proposals->create_enumerator(this->proposals);
+ while (enumerator->enumerate(enumerator, (void**)&substruct))
{
- current_number = current_proposal->get_proposal_number(current_proposal);
+ current_number = substruct->get_proposal_number(substruct);
if (current_number < expected_number)
{
- if (current_number != (expected_number + 1))
+ if (current_number != expected_number + 1)
{
DBG1(DBG_ENC, "proposal number is %d, expected %d or %d",
current_number, expected_number, expected_number + 1);
@@ -124,13 +120,12 @@ static status_t verify(private_sa_payload_t *this)
}
else if (current_number < expected_number)
{
- /* must not be smaller then proceeding one */
- DBG1(DBG_ENC, "proposal number smaller than that of previous proposal");
+ DBG1(DBG_ENC, "proposal number smaller than previous");
status = FAILED;
break;
}
- status = current_proposal->payload_interface.verify(&(current_proposal->payload_interface));
+ status = substruct->payload_interface.verify(&substruct->payload_interface);
if (status != SUCCESS)
{
DBG1(DBG_ENC, "PROPOSAL_SUBSTRUCTURE verification failed");
@@ -139,52 +134,31 @@ static status_t verify(private_sa_payload_t *this)
first = FALSE;
expected_number = current_number;
}
-
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return status;
}
-
-/**
- * Implementation of payload_t.destroy and sa_payload_t.destroy.
- */
-static status_t destroy(private_sa_payload_t *this)
-{
- this->proposals->destroy_offset(this->proposals,
- offsetof(proposal_substructure_t, destroy));
- free(this);
- return SUCCESS;
-}
-
-/**
- * Implementation of payload_t.get_encoding_rules.
- */
-static void get_encoding_rules(private_sa_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
+METHOD(payload_t, get_encoding_rules, void,
+ private_sa_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
{
*rules = sa_payload_encodings;
- *rule_count = sizeof(sa_payload_encodings) / sizeof(encoding_rule_t);
+ *rule_count = countof(sa_payload_encodings);
}
-/**
- * Implementation of payload_t.get_type.
- */
-static payload_type_t get_type(private_sa_payload_t *this)
+METHOD(payload_t, get_type, payload_type_t,
+ private_sa_payload_t *this)
{
return SECURITY_ASSOCIATION;
}
-/**
- * Implementation of payload_t.get_next_type.
- */
-static payload_type_t get_next_type(private_sa_payload_t *this)
+METHOD(payload_t, get_next_type, payload_type_t,
+ private_sa_payload_t *this)
{
- return (this->next_payload);
+ return this->next_payload;
}
-/**
- * Implementation of payload_t.set_next_type.
- */
-static void set_next_type(private_sa_payload_t *this,payload_type_t type)
+METHOD(payload_t, set_next_type, void,
+ private_sa_payload_t *this,payload_type_t type)
{
this->next_payload = type;
}
@@ -192,116 +166,104 @@ static void set_next_type(private_sa_payload_t *this,payload_type_t type)
/**
* recompute length of the payload.
*/
-static void compute_length (private_sa_payload_t *this)
+static void compute_length(private_sa_payload_t *this)
{
- iterator_t *iterator;
- payload_t *current_proposal;
+ enumerator_t *enumerator;
+ payload_t *current;
size_t length = SA_PAYLOAD_HEADER_LENGTH;
- iterator = this->proposals->create_iterator(this->proposals,TRUE);
- while (iterator->iterate(iterator, (void **)&current_proposal))
+ enumerator = this->proposals->create_enumerator(this->proposals);
+ while (enumerator->enumerate(enumerator, (void **)&current))
{
- length += current_proposal->get_length(current_proposal);
+ length += current->get_length(current);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
this->payload_length = length;
}
-/**
- * Implementation of payload_t.get_length.
- */
-static size_t get_length(private_sa_payload_t *this)
+METHOD(payload_t, get_length, size_t,
+ private_sa_payload_t *this)
{
compute_length(this);
return this->payload_length;
}
-/**
- * Implementation of sa_payload_t.create_proposal_substructure_iterator.
- */
-static iterator_t *create_proposal_substructure_iterator (private_sa_payload_t *this,bool forward)
+METHOD(sa_payload_t, add_proposal, void,
+ private_sa_payload_t *this, proposal_t *proposal)
{
- return this->proposals->create_iterator(this->proposals,forward);
-}
+ proposal_substructure_t *substruct, *last;
+ u_int count;
-/**
- * Implementation of sa_payload_t.add_proposal_substructure.
- */
-static void add_proposal_substructure(private_sa_payload_t *this,proposal_substructure_t *proposal)
-{
- status_t status;
- u_int proposal_count = this->proposals->get_count(this->proposals);
-
- if (proposal_count > 0)
+ count = this->proposals->get_count(this->proposals);
+ substruct = proposal_substructure_create_from_proposal(proposal);
+ if (count > 0)
{
- proposal_substructure_t *last_proposal;
- status = this->proposals->get_last(this->proposals,(void **) &last_proposal);
+ this->proposals->get_last(this->proposals, (void**)&last);
/* last transform is now not anymore last one */
- last_proposal->set_is_last_proposal(last_proposal, FALSE);
+ last->set_is_last_proposal(last, FALSE);
+ }
+ substruct->set_is_last_proposal(substruct, TRUE);
+ if (proposal->get_number(proposal))
+ { /* use the selected proposals number, if any */
+ substruct->set_proposal_number(substruct, proposal->get_number(proposal));
+ }
+ else
+ {
+ substruct->set_proposal_number(substruct, count + 1);
}
- proposal->set_is_last_proposal(proposal, TRUE);
- proposal->set_proposal_number(proposal, proposal_count + 1);
- this->proposals->insert_last(this->proposals,(void *) proposal);
+ this->proposals->insert_last(this->proposals, substruct);
compute_length(this);
}
-/**
- * Implementation of sa_payload_t.add_proposal.
- */
-static void add_proposal(private_sa_payload_t *this, proposal_t *proposal)
-{
- proposal_substructure_t *substructure;
-
- substructure = proposal_substructure_create_from_proposal(proposal);
- add_proposal_substructure(this, substructure);
-}
-
-/**
- * Implementation of sa_payload_t.get_proposals.
- */
-static linked_list_t *get_proposals(private_sa_payload_t *this)
+METHOD(sa_payload_t, get_proposals, linked_list_t*,
+ private_sa_payload_t *this)
{
int struct_number = 0;
int ignore_struct_number = 0;
- iterator_t *iterator;
- proposal_substructure_t *proposal_struct;
- linked_list_t *proposal_list;
-
- /* this list will hold our proposals */
- proposal_list = linked_list_create();
+ enumerator_t *enumerator;
+ proposal_substructure_t *substruct;
+ linked_list_t *list;
+ proposal_t *proposal;
+ list = linked_list_create();
/* we do not support proposals split up to two proposal substructures, as
* AH+ESP bundles are not supported in RFC4301 anymore.
* To handle such structures safely, we just skip proposals with multiple
* protocols.
*/
- iterator = this->proposals->create_iterator(this->proposals, TRUE);
- while (iterator->iterate(iterator, (void **)&proposal_struct))
+ enumerator = this->proposals->create_enumerator(this->proposals);
+ while (enumerator->enumerate(enumerator, &substruct))
{
- proposal_t *proposal;
-
/* check if a proposal has a single protocol */
- if (proposal_struct->get_proposal_number(proposal_struct) == struct_number)
+ if (substruct->get_proposal_number(substruct) == struct_number)
{
if (ignore_struct_number < struct_number)
{
- /* remova an already added, if first of series */
- proposal_list->remove_last(proposal_list, (void**)&proposal);
+ /* remove an already added, if first of series */
+ list->remove_last(list, (void**)&proposal);
proposal->destroy(proposal);
ignore_struct_number = struct_number;
}
continue;
}
struct_number++;
- proposal = proposal_struct->get_proposal(proposal_struct);
+ proposal = substruct->get_proposal(substruct);
if (proposal)
{
- proposal_list->insert_last(proposal_list, proposal);
+ list->insert_last(list, proposal);
}
}
- iterator->destroy(iterator);
- return proposal_list;
+ enumerator->destroy(enumerator);
+ return list;
+}
+
+METHOD2(payload_t, sa_payload_t, destroy, void,
+ private_sa_payload_t *this)
+{
+ this->proposals->destroy_offset(this->proposals,
+ offsetof(proposal_substructure_t, destroy));
+ free(this);
}
/*
@@ -309,29 +271,27 @@ static linked_list_t *get_proposals(private_sa_payload_t *this)
*/
sa_payload_t *sa_payload_create()
{
- private_sa_payload_t *this = malloc_thing(private_sa_payload_t);
-
- /* public interface */
- this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
- this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
- this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
- this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
- this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
- this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
- this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
-
- /* public functions */
- this->public.create_proposal_substructure_iterator = (iterator_t* (*) (sa_payload_t *,bool)) create_proposal_substructure_iterator;
- this->public.add_proposal_substructure = (void (*) (sa_payload_t *,proposal_substructure_t *)) add_proposal_substructure;
- this->public.add_proposal = (void (*) (sa_payload_t*,proposal_t*))add_proposal;
- this->public.get_proposals = (linked_list_t* (*) (sa_payload_t *)) get_proposals;
- this->public.destroy = (void (*) (sa_payload_t *)) destroy;
-
- /* set default values of the fields */
- this->critical = FALSE;
- this->next_payload = NO_PAYLOAD;
- this->payload_length = SA_PAYLOAD_HEADER_LENGTH;
- this->proposals = linked_list_create();
+ private_sa_payload_t *this;
+
+ INIT(this,
+ .public = {
+ .payload_interface = {
+ .verify = _verify,
+ .get_encoding_rules = _get_encoding_rules,
+ .get_length = _get_length,
+ .get_next_type = _get_next_type,
+ .set_next_type = _set_next_type,
+ .get_type = _get_type,
+ .destroy = _destroy,
+ },
+ .add_proposal = _add_proposal,
+ .get_proposals = _get_proposals,
+ .destroy = _destroy,
+ },
+ .next_payload = NO_PAYLOAD,
+ .payload_length = SA_PAYLOAD_HEADER_LENGTH,
+ .proposals = linked_list_create(),
+ );
return &this->public;
}
@@ -340,19 +300,19 @@ sa_payload_t *sa_payload_create()
*/
sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals)
{
- iterator_t *iterator;
+ private_sa_payload_t *this;
+ enumerator_t *enumerator;
proposal_t *proposal;
- sa_payload_t *sa_payload = sa_payload_create();
- /* add every payload from the list */
- iterator = proposals->create_iterator(proposals, TRUE);
- while (iterator->iterate(iterator, (void**)&proposal))
+ this = (private_sa_payload_t*)sa_payload_create();
+ enumerator = proposals->create_enumerator(proposals);
+ while (enumerator->enumerate(enumerator, &proposal))
{
- add_proposal((private_sa_payload_t*)sa_payload, proposal);
+ add_proposal(this, proposal);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
- return sa_payload;
+ return &this->public;
}
/*
@@ -360,9 +320,10 @@ sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals)
*/
sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal)
{
- sa_payload_t *sa_payload = sa_payload_create();
+ private_sa_payload_t *this;
- add_proposal((private_sa_payload_t*)sa_payload, proposal);
+ this = (private_sa_payload_t*)sa_payload_create();
+ add_proposal(this, proposal);
- return sa_payload;
+ return &this->public;
}
diff --git a/src/libcharon/encoding/payloads/sa_payload.h b/src/libcharon/encoding/payloads/sa_payload.h
index 25f5a2407..801a70738 100644
--- a/src/libcharon/encoding/payloads/sa_payload.h
+++ b/src/libcharon/encoding/payloads/sa_payload.h
@@ -40,33 +40,13 @@ typedef struct sa_payload_t sa_payload_t;
* The SA Payload format is described in RFC section 3.3.
*/
struct sa_payload_t {
+
/**
* The payload_t interface.
*/
payload_t payload_interface;
/**
- * Creates an iterator of stored proposal_substructure_t objects.
- *
- * When deleting an proposal using this iterator,
- * the length of this transform substructure has to be refreshed
- * by calling get_length()!
- *
- * @param forward iterator direction (TRUE: front to end)
- * @return created iterator_t object
- */
- iterator_t *(*create_proposal_substructure_iterator) (sa_payload_t *this,
- bool forward);
-
- /**
- * Adds a proposal_substructure_t object to this object.
- *
- * @param proposal proposal_substructure_t object to add
- */
- void (*add_proposal_substructure) (sa_payload_t *this,
- proposal_substructure_t *proposal);
-
- /**
* Gets the proposals in this payload as a list.
*
* @return a list containing proposal_t s
diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c
new file mode 100644
index 000000000..d9e39fe43
--- /dev/null
+++ b/src/libcharon/kernel/kernel_handler.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "kernel_handler.h"
+
+#include <hydra.h>
+#include <daemon.h>
+#include <processing/jobs/acquire_job.h>
+#include <processing/jobs/delete_child_sa_job.h>
+#include <processing/jobs/migrate_job.h>
+#include <processing/jobs/rekey_child_sa_job.h>
+#include <processing/jobs/roam_job.h>
+#include <processing/jobs/update_sa_job.h>
+
+typedef struct private_kernel_handler_t private_kernel_handler_t;
+
+/**
+ * Private data of a kernel_handler_t object.
+ */
+struct private_kernel_handler_t {
+
+ /**
+ * Public part of kernel_handler_t object.
+ */
+ kernel_handler_t public;
+
+};
+
+/**
+ * convert an IP protocol identifier to the IKEv2 specific protocol identifier.
+ */
+static inline protocol_id_t proto_ip2ike(u_int8_t protocol)
+{
+ switch (protocol)
+ {
+ case IPPROTO_ESP:
+ return PROTO_ESP;
+ case IPPROTO_AH:
+ return PROTO_AH;
+ default:
+ return protocol;
+ }
+}
+
+METHOD(kernel_listener_t, acquire, bool,
+ private_kernel_handler_t *this, u_int32_t reqid,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+{
+ job_t *job;
+ if (src_ts && dst_ts)
+ {
+ DBG1(DBG_KNL, "creating acquire job for policy %R === %R "
+ "with reqid {%u}", src_ts, dst_ts, reqid);
+ }
+ else
+ {
+ DBG1(DBG_KNL, "creating acquire job for policy with reqid {%u}", reqid);
+ }
+ job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts);
+ lib->processor->queue_job(lib->processor, job);
+ return TRUE;
+}
+
+METHOD(kernel_listener_t, expire, bool,
+ private_kernel_handler_t *this, u_int32_t reqid, u_int8_t protocol,
+ u_int32_t spi, bool hard)
+{
+ job_t *job;
+ protocol_id_t proto = proto_ip2ike(protocol);
+ DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x "
+ "and reqid {%u}", hard ? "delete" : "rekey",
+ protocol_id_names, proto, ntohl(spi), reqid);
+ if (hard)
+ {
+ job = (job_t*)delete_child_sa_job_create(reqid, proto, spi);
+ }
+ else
+ {
+ job = (job_t*)rekey_child_sa_job_create(reqid, proto, spi);
+ }
+ lib->processor->queue_job(lib->processor, job);
+ return TRUE;
+}
+
+METHOD(kernel_listener_t, mapping, bool,
+ private_kernel_handler_t *this, u_int32_t reqid, u_int32_t spi,
+ host_t *remote)
+{
+ job_t *job;
+ DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and "
+ "reqid {%u} changed, queuing update job", ntohl(spi), reqid);
+ job = (job_t*)update_sa_job_create(reqid, remote);
+ lib->processor->queue_job(lib->processor, job);
+ return TRUE;
+}
+
+METHOD(kernel_listener_t, migrate, bool,
+ private_kernel_handler_t *this, u_int32_t reqid,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+ policy_dir_t direction, host_t *local, host_t *remote)
+{
+ job_t *job;
+ DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with "
+ "reqid {%u}", src_ts, dst_ts, policy_dir_names, direction,
+ reqid, local);
+ job = (job_t*)migrate_job_create(reqid, src_ts, dst_ts, direction, local,
+ remote);
+ lib->processor->queue_job(lib->processor, job);
+ return TRUE;
+}
+
+METHOD(kernel_listener_t, roam, bool,
+ private_kernel_handler_t *this, bool address)
+{
+ job_t *job;
+ job = (job_t*)roam_job_create(address);
+ lib->processor->queue_job(lib->processor, job);
+ return TRUE;
+}
+
+METHOD(kernel_handler_t, destroy, void,
+ private_kernel_handler_t *this)
+{
+ hydra->kernel_interface->remove_listener(hydra->kernel_interface,
+ &this->public.listener);
+ free(this);
+}
+
+kernel_handler_t *kernel_handler_create()
+{
+ private_kernel_handler_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .acquire = _acquire,
+ .expire = _expire,
+ .mapping = _mapping,
+ .migrate = _migrate,
+ .roam = _roam,
+ },
+ .destroy = _destroy,
+ },
+ );
+
+ hydra->kernel_interface->add_listener(hydra->kernel_interface,
+ &this->public.listener);
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/kernel/kernel_handler.h b/src/libcharon/kernel/kernel_handler.h
new file mode 100644
index 000000000..48ad6889c
--- /dev/null
+++ b/src/libcharon/kernel/kernel_handler.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup kernel_handler kernel_handler
+ * @{ @ingroup ckernel
+ */
+
+#ifndef KERNEL_HANDLER_H_
+#define KERNEL_HANDLER_H_
+
+typedef struct kernel_handler_t kernel_handler_t;
+
+#include <kernel/kernel_listener.h>
+
+/**
+ * Listens to and handles kernel events.
+ */
+struct kernel_handler_t {
+
+ /**
+ * Implements the kernel listener interface.
+ */
+ kernel_listener_t listener;
+
+ /**
+ * Destroy this instance.
+ */
+ void (*destroy)(kernel_handler_t *this);
+
+};
+
+/**
+ * Create an object of type kernel_handler_t.
+ */
+kernel_handler_t *kernel_handler_create();
+
+#endif /** KERNEL_HANDLER_H_ @}*/
diff --git a/src/libcharon/kernel/kernel_interface.c b/src/libcharon/kernel/kernel_interface.c
deleted file mode 100644
index 837e628bc..000000000
--- a/src/libcharon/kernel/kernel_interface.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2008-2009 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "kernel_interface.h"
-
-#include <daemon.h>
-
-typedef struct private_kernel_interface_t private_kernel_interface_t;
-
-/**
- * Private data of a kernel_interface_t object.
- */
-struct private_kernel_interface_t {
-
- /**
- * Public part of kernel_interface_t object.
- */
- kernel_interface_t public;
-
- /**
- * ipsec interface
- */
- kernel_ipsec_t *ipsec;
-
- /**
- * network interface
- */
- kernel_net_t *net;
-};
-
-METHOD(kernel_interface_t, get_spi, status_t,
- private_kernel_interface_t *this, host_t *src, host_t *dst,
- protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi)
-{
- if (!this->ipsec)
- {
- return NOT_SUPPORTED;
- }
- return this->ipsec->get_spi(this->ipsec, src, dst, protocol, reqid, spi);
-}
-
-METHOD(kernel_interface_t, get_cpi, status_t,
- private_kernel_interface_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
-{
- if (!this->ipsec)
- {
- return NOT_SUPPORTED;
- }
- return this->ipsec->get_cpi(this->ipsec, src, dst, reqid, cpi);
-}
-
-METHOD(kernel_interface_t, add_sa, status_t,
- private_kernel_interface_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int32_t reqid,
- mark_t mark, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
- u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool encap, bool inbound, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts)
-{
- if (!this->ipsec)
- {
- return NOT_SUPPORTED;
- }
- return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,
- mark, lifetime, enc_alg, enc_key, int_alg, int_key, mode, ipcomp,
- cpi, encap, inbound, src_ts, dst_ts);
-}
-
-METHOD(kernel_interface_t, update_sa, status_t,
- private_kernel_interface_t *this, u_int32_t spi, protocol_id_t protocol,
- u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
- bool encap, bool new_encap, mark_t mark)
-{
- if (!this->ipsec)
- {
- return NOT_SUPPORTED;
- }
- return this->ipsec->update_sa(this->ipsec, spi, protocol, cpi, src, dst,
- new_src, new_dst, encap, new_encap, mark);
-}
-
-METHOD(kernel_interface_t, query_sa, status_t,
- private_kernel_interface_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
-{
- if (!this->ipsec)
- {
- return NOT_SUPPORTED;
- }
- return this->ipsec->query_sa(this->ipsec, src, dst, spi, protocol, mark, bytes);
-}
-
-METHOD(kernel_interface_t, del_sa, status_t,
- private_kernel_interface_t *this, host_t *src, host_t *dst, u_int32_t spi,
- protocol_id_t protocol, u_int16_t cpi, mark_t mark)
-{
- if (!this->ipsec)
- {
- return NOT_SUPPORTED;
- }
- return this->ipsec->del_sa(this->ipsec, src, dst, spi, protocol, cpi, mark);
-}
-
-METHOD(kernel_interface_t, add_policy, status_t,
- private_kernel_interface_t *this, host_t *src, host_t *dst,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
- policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
- u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool routed)
-{
- if (!this->ipsec)
- {
- return NOT_SUPPORTED;
- }
- return this->ipsec->add_policy(this->ipsec, src, dst, src_ts, dst_ts,
- direction, spi, protocol, reqid, mark, mode, ipcomp, cpi, routed);
-}
-
-METHOD(kernel_interface_t, query_policy, status_t,
- private_kernel_interface_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
- u_int32_t *use_time)
-{
- if (!this->ipsec)
- {
- return NOT_SUPPORTED;
- }
- return this->ipsec->query_policy(this->ipsec, src_ts, dst_ts,
- direction, mark, use_time);
-}
-
-METHOD(kernel_interface_t, del_policy, status_t,
- private_kernel_interface_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
- bool unrouted)
-{
- if (!this->ipsec)
- {
- return NOT_SUPPORTED;
- }
- return this->ipsec->del_policy(this->ipsec, src_ts, dst_ts,
- direction, mark, unrouted);
-}
-
-METHOD(kernel_interface_t, get_source_addr, host_t*,
- private_kernel_interface_t *this, host_t *dest, host_t *src)
-{
- if (!this->net)
- {
- return NULL;
- }
- return this->net->get_source_addr(this->net, dest, src);
-}
-
-METHOD(kernel_interface_t, get_nexthop, host_t*,
- private_kernel_interface_t *this, host_t *dest)
-{
- if (!this->net)
- {
- return NULL;
- }
- return this->net->get_nexthop(this->net, dest);
-}
-
-METHOD(kernel_interface_t, get_interface, char*,
- private_kernel_interface_t *this, host_t *host)
-{
- if (!this->net)
- {
- return NULL;
- }
- return this->net->get_interface(this->net, host);
-}
-
-METHOD(kernel_interface_t, create_address_enumerator, enumerator_t*,
- private_kernel_interface_t *this, bool include_down_ifaces,
- bool include_virtual_ips)
-{
- if (!this->net)
- {
- return enumerator_create_empty();
- }
- return this->net->create_address_enumerator(this->net, include_down_ifaces,
- include_virtual_ips);
-}
-
-METHOD(kernel_interface_t, add_ip, status_t,
- private_kernel_interface_t *this, host_t *virtual_ip, host_t *iface_ip)
-{
- if (!this->net)
- {
- return NOT_SUPPORTED;
- }
- return this->net->add_ip(this->net, virtual_ip, iface_ip);
-}
-
-METHOD(kernel_interface_t, del_ip, status_t,
- private_kernel_interface_t *this, host_t *virtual_ip)
-{
- if (!this->net)
- {
- return NOT_SUPPORTED;
- }
- return this->net->del_ip(this->net, virtual_ip);
-}
-
-METHOD(kernel_interface_t, add_route, status_t,
- private_kernel_interface_t *this, chunk_t dst_net,
- u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
-{
- if (!this->net)
- {
- return NOT_SUPPORTED;
- }
- return this->net->add_route(this->net, dst_net, prefixlen, gateway,
- src_ip, if_name);
-}
-
-METHOD(kernel_interface_t, del_route, status_t,
- private_kernel_interface_t *this, chunk_t dst_net,
- u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
-{
- if (!this->net)
- {
- return NOT_SUPPORTED;
- }
- return this->net->del_route(this->net, dst_net, prefixlen, gateway,
- src_ip, if_name);
-}
-
-METHOD(kernel_interface_t, bypass_socket, bool,
- private_kernel_interface_t *this, int fd, int family)
-{
- if (!this->ipsec)
- {
- return FALSE;
- }
- return this->ipsec->bypass_socket(this->ipsec, fd, family);
-}
-
-METHOD(kernel_interface_t, get_address_by_ts, status_t,
- private_kernel_interface_t *this, traffic_selector_t *ts, host_t **ip)
-{
- enumerator_t *addrs;
- host_t *host;
- int family;
- bool found = FALSE;
-
- DBG2(DBG_KNL, "getting a local address in traffic selector %R", ts);
-
- /* if we have a family which includes localhost, we do not
- * search for an IP, we use the default */
- family = ts->get_type(ts) == TS_IPV4_ADDR_RANGE ? AF_INET : AF_INET6;
-
- if (family == AF_INET)
- {
- host = host_create_from_string("127.0.0.1", 0);
- }
- else
- {
- host = host_create_from_string("::1", 0);
- }
-
- if (ts->includes(ts, host))
- {
- *ip = host_create_any(family);
- host->destroy(host);
- DBG2(DBG_KNL, "using host %H", *ip);
- return SUCCESS;
- }
- host->destroy(host);
-
- addrs = create_address_enumerator(this, TRUE, TRUE);
- while (addrs->enumerate(addrs, (void**)&host))
- {
- if (ts->includes(ts, host))
- {
- found = TRUE;
- *ip = host->clone(host);
- break;
- }
- }
- addrs->destroy(addrs);
-
- if (!found)
- {
- DBG1(DBG_KNL, "no local address found in traffic selector %R", ts);
- return FAILED;
- }
-
- DBG2(DBG_KNL, "using host %H", *ip);
- return SUCCESS;
-}
-
-
-METHOD(kernel_interface_t, add_ipsec_interface, void,
- private_kernel_interface_t *this, kernel_ipsec_constructor_t constructor)
-{
- if (!this->ipsec)
- {
- this->ipsec = constructor();
- }
-}
-
-METHOD(kernel_interface_t, remove_ipsec_interface, void,
- private_kernel_interface_t *this, kernel_ipsec_constructor_t constructor)
-{
- /* TODO: replace if interface currently in use */
-}
-
-METHOD(kernel_interface_t, add_net_interface, void,
- private_kernel_interface_t *this, kernel_net_constructor_t constructor)
-{
- if (!this->net)
- {
- this->net = constructor();
- }
-}
-
-METHOD(kernel_interface_t, remove_net_interface, void,
- private_kernel_interface_t *this, kernel_net_constructor_t constructor)
-{
- /* TODO: replace if interface currently in use */
-}
-
-METHOD(kernel_interface_t, destroy, void,
- private_kernel_interface_t *this)
-{
- DESTROY_IF(this->ipsec);
- DESTROY_IF(this->net);
- free(this);
-}
-
-/*
- * Described in header-file
- */
-kernel_interface_t *kernel_interface_create()
-{
- private_kernel_interface_t *this;
-
- INIT(this,
- .public = {
- .get_spi = _get_spi,
- .get_cpi = _get_cpi,
- .add_sa = _add_sa,
- .update_sa = _update_sa,
- .query_sa = _query_sa,
- .del_sa = _del_sa,
- .add_policy = _add_policy,
- .query_policy = _query_policy,
- .del_policy = _del_policy,
- .get_source_addr = _get_source_addr,
- .get_nexthop = _get_nexthop,
- .get_interface = _get_interface,
- .create_address_enumerator = _create_address_enumerator,
- .add_ip = _add_ip,
- .del_ip = _del_ip,
- .add_route = _add_route,
- .del_route = _del_route,
- .bypass_socket = _bypass_socket,
-
- .get_address_by_ts = _get_address_by_ts,
- .add_ipsec_interface = _add_ipsec_interface,
- .remove_ipsec_interface = _remove_ipsec_interface,
- .add_net_interface = _add_net_interface,
- .remove_net_interface = _remove_net_interface,
- .destroy = _destroy,
- },
- );
-
- return &this->public;
-}
-
diff --git a/src/libcharon/kernel/kernel_interface.h b/src/libcharon/kernel/kernel_interface.h
deleted file mode 100644
index 92d85f9c9..000000000
--- a/src/libcharon/kernel/kernel_interface.h
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Tobias Brunner
- * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup kernel_interface kernel_interface
- * @{ @ingroup kernel
- */
-
-#ifndef KERNEL_INTERFACE_H_
-#define KERNEL_INTERFACE_H_
-
-typedef struct kernel_interface_t kernel_interface_t;
-
-#include <utils/host.h>
-#include <crypto/prf_plus.h>
-#include <encoding/payloads/proposal_substructure.h>
-
-#include <kernel/kernel_ipsec.h>
-#include <kernel/kernel_net.h>
-
-/**
- * Constructor function for ipsec kernel interface
- */
-typedef kernel_ipsec_t* (*kernel_ipsec_constructor_t)(void);
-
-/**
- * Constructor function for network kernel interface
- */
-typedef kernel_net_t* (*kernel_net_constructor_t)(void);
-
-/**
- * Manager and wrapper for different kernel interfaces.
- *
- * The kernel interface handles the communication with the kernel
- * for SA and policy management and interface and IP address management.
- */
-struct kernel_interface_t {
-
- /**
- * Get a SPI from the kernel.
- *
- * @param src source address of SA
- * @param dst destination address of SA
- * @param protocol protocol for SA (ESP/AH)
- * @param reqid unique ID for this SA
- * @param spi allocated spi
- * @return SUCCESS if operation completed
- */
- status_t (*get_spi)(kernel_interface_t *this, host_t *src, host_t *dst,
- protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi);
-
- /**
- * Get a Compression Parameter Index (CPI) from the kernel.
- *
- * @param src source address of SA
- * @param dst destination address of SA
- * @param reqid unique ID for the corresponding SA
- * @param cpi allocated cpi
- * @return SUCCESS if operation completed
- */
- status_t (*get_cpi)(kernel_interface_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi);
-
- /**
- * Add an SA to the SAD.
- *
- * add_sa() may update an already allocated
- * SPI (via get_spi). In this case, the replace
- * flag must be set.
- * This function does install a single SA for a
- * single protocol in one direction.
- *
- * @param src source address for this SA
- * @param dst destination address for this SA
- * @param spi SPI allocated by us or remote peer
- * @param protocol protocol for this SA (ESP/AH)
- * @param reqid unique ID for this SA
- * @param mark optional mark for this SA
- * @param lifetime lifetime_cfg_t for this SA
- * @param enc_alg Algorithm to use for encryption (ESP only)
- * @param enc_key key to use for encryption
- * @param int_alg Algorithm to use for integrity protection
- * @param int_key key to use for integrity protection
- * @param mode mode of the SA (tunnel, transport)
- * @param ipcomp IPComp transform to use
- * @param cpi CPI for IPComp
- * @param encap enable UDP encapsulation for NAT traversal
- * @param inbound TRUE if this is an inbound SA
- * @param src_ts traffic selector with BEET source address
- * @param dst_ts traffic selector with BEET destination address
- * @return SUCCESS if operation completed
- */
- status_t (*add_sa) (kernel_interface_t *this,
- host_t *src, host_t *dst, u_int32_t spi,
- protocol_id_t protocol, u_int32_t reqid, mark_t mark,
- lifetime_cfg_t *lifetime,
- u_int16_t enc_alg, chunk_t enc_key,
- u_int16_t int_alg, chunk_t int_key,
- ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
- bool encap, bool inbound,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts);
-
- /**
- * Update the hosts on an installed SA.
- *
- * We cannot directly update the destination address as the kernel
- * requires the spi, the protocol AND the destination address (and family)
- * to identify SAs. Therefore if the destination address changed we
- * create a new SA and delete the old one.
- *
- * @param spi SPI of the SA
- * @param protocol protocol for this SA (ESP/AH)
- * @param cpi CPI for IPComp, 0 if no IPComp is used
- * @param src current source address
- * @param dst current destination address
- * @param new_src new source address
- * @param new_dst new destination address
- * @param encap current use of UDP encapsulation
- * @param new_encap new use of UDP encapsulation
- * @param mark optional mark for this SA
- * @return SUCCESS if operation completed, NOT_SUPPORTED if
- * the kernel interface can't update the SA
- */
- status_t (*update_sa)(kernel_interface_t *this,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi,
- host_t *src, host_t *dst,
- host_t *new_src, host_t *new_dst,
- bool encap, bool new_encap, mark_t mark);
-
- /**
- * Query the number of bytes processed by an SA from the SAD.
- *
- * @param src source address for this SA
- * @param dst destination address for this SA
- * @param spi SPI allocated by us or remote peer
- * @param protocol protocol for this SA (ESP/AH)
- * @param mark optional mark for this SA
- * @param[out] bytes the number of bytes processed by SA
- * @return SUCCESS if operation completed
- */
- status_t (*query_sa) (kernel_interface_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, mark_t mark,
- u_int64_t *bytes);
-
- /**
- * Delete a previously installed SA from the SAD.
- *
- * @param src source address for this SA
- * @param dst destination address for this SA
- * @param spi SPI allocated by us or remote peer
- * @param protocol protocol for this SA (ESP/AH)
- * @param cpi CPI for IPComp or 0
- * @param mark optional mark for this SA
- * @return SUCCESS if operation completed
- */
- status_t (*del_sa) (kernel_interface_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi,
- mark_t mark);
-
- /**
- * Add a policy to the SPD.
- *
- * A policy is always associated to an SA. Traffic which matches a
- * policy is handled by the SA with the same reqid.
- *
- * @param src source address of SA
- * @param dst dest address of SA
- * @param src_ts traffic selector to match traffic source
- * @param dst_ts traffic selector to match traffic dest
- * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
- * @param spi SPI of SA
- * @param protocol protocol to use to protect traffic (AH/ESP)
- * @param reqid unique ID of an SA to use to enforce policy
- * @param mark mark for this policy
- * @param mode mode of SA (tunnel, transport)
- * @param ipcomp the IPComp transform used
- * @param cpi CPI for IPComp
- * @param routed TRUE, if this policy is routed in the kernel
- * @return SUCCESS if operation completed
- */
- status_t (*add_policy) (kernel_interface_t *this,
- host_t *src, host_t *dst,
- traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts,
- policy_dir_t direction, u_int32_t spi,
- protocol_id_t protocol, u_int32_t reqid,
- mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool routed);
-
- /**
- * Query the use time of a policy.
- *
- * The use time of a policy is the time the policy was used
- * for the last time.
- *
- * @param src_ts traffic selector to match traffic source
- * @param dst_ts traffic selector to match traffic dest
- * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
- * @param mark optional mark
- * @param[out] use_time the time of this SA's last use
- * @return SUCCESS if operation completed
- */
- status_t (*query_policy) (kernel_interface_t *this,
- traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts,
- policy_dir_t direction, mark_t mark,
- u_int32_t *use_time);
-
- /**
- * Remove a policy from the SPD.
- *
- * The kernel interface implements reference counting for policies.
- * If the same policy is installed multiple times (in the case of rekeying),
- * the reference counter is increased. del_policy() decreases the ref counter
- * and removes the policy only when no more references are available.
- *
- * @param src_ts traffic selector to match traffic source
- * @param dst_ts traffic selector to match traffic dest
- * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
- * @param mark optional mark
- * @param unrouted TRUE, if this policy is unrouted from the kernel
- * @return SUCCESS if operation completed
- */
- status_t (*del_policy) (kernel_interface_t *this,
- traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts,
- policy_dir_t direction, mark_t mark,
- bool unrouted);
-
- /**
- * Get our outgoing source address for a destination.
- *
- * Does a route lookup to get the source address used to reach dest.
- * The returned host is allocated and must be destroyed.
- * An optional src address can be used to check if a route is available
- * for given source to dest.
- *
- * @param dest target destination address
- * @param src source address to check, or NULL
- * @return outgoing source address, NULL if unreachable
- */
- host_t* (*get_source_addr)(kernel_interface_t *this,
- host_t *dest, host_t *src);
-
- /**
- * Get the next hop for a destination.
- *
- * Does a route lookup to get the next hop used to reach dest.
- * The returned host is allocated and must be destroyed.
- *
- * @param dest target destination address
- * @return next hop address, NULL if unreachable
- */
- host_t* (*get_nexthop)(kernel_interface_t *this, host_t *dest);
-
- /**
- * Get the interface name of a local address.
- *
- * @param host address to get interface name from
- * @return allocated interface name, or NULL if not found
- */
- char* (*get_interface) (kernel_interface_t *this, host_t *host);
-
- /**
- * Creates an enumerator over all local addresses.
- *
- * This function blocks an internal cached address list until the
- * enumerator gets destroyed.
- * The hosts are read-only, do not modify of free.
- *
- * @param include_down_ifaces TRUE to enumerate addresses from down interfaces
- * @param include_virtual_ips TRUE to enumerate virtual ip addresses
- * @return enumerator over host_t's
- */
- enumerator_t *(*create_address_enumerator) (kernel_interface_t *this,
- bool include_down_ifaces, bool include_virtual_ips);
-
- /**
- * Add a virtual IP to an interface.
- *
- * Virtual IPs are attached to an interface. If an IP is added multiple
- * times, the IP is refcounted and not removed until del_ip() was called
- * as many times as add_ip().
- * The virtual IP is attached to the interface where the iface_ip is found.
- *
- * @param virtual_ip virtual ip address to assign
- * @param iface_ip IP of an interface to attach virtual IP
- * @return SUCCESS if operation completed
- */
- status_t (*add_ip) (kernel_interface_t *this, host_t *virtual_ip,
- host_t *iface_ip);
-
- /**
- * Remove a virtual IP from an interface.
- *
- * The kernel interface uses refcounting, see add_ip().
- *
- * @param virtual_ip virtual ip address to assign
- * @return SUCCESS if operation completed
- */
- status_t (*del_ip) (kernel_interface_t *this, host_t *virtual_ip);
-
- /**
- * Add a route.
- *
- * @param dst_net destination net
- * @param prefixlen destination net prefix length
- * @param gateway gateway for this route
- * @param src_ip sourc ip of the route
- * @param if_name name of the interface the route is bound to
- * @return SUCCESS if operation completed
- * ALREADY_DONE if the route already exists
- */
- status_t (*add_route) (kernel_interface_t *this, chunk_t dst_net, u_int8_t prefixlen,
- host_t *gateway, host_t *src_ip, char *if_name);
-
- /**
- * Delete a route.
- *
- * @param dst_net destination net
- * @param prefixlen destination net prefix length
- * @param gateway gateway for this route
- * @param src_ip sourc ip of the route
- * @param if_name name of the interface the route is bound to
- * @return SUCCESS if operation completed
- */
- status_t (*del_route) (kernel_interface_t *this, chunk_t dst_net, u_int8_t prefixlen,
- host_t *gateway, host_t *src_ip, char *if_name);
-
- /**
- * Set up a bypass policy for a given socket.
- *
- * @param fd socket file descriptor to setup policy for
- * @param family protocol family of the socket
- * @return TRUE of policy set up successfully
- */
- bool (*bypass_socket)(kernel_interface_t *this, int fd, int family);
-
- /**
- * manager methods
- */
-
- /**
- * Tries to find an ip address of a local interface that is included in the
- * supplied traffic selector.
- *
- * @param ts traffic selector
- * @param ip returned ip (has to be destroyed)
- * @return SUCCESS if address found
- */
- status_t (*get_address_by_ts) (kernel_interface_t *this,
- traffic_selector_t *ts, host_t **ip);
-
- /**
- * Register an ipsec kernel interface constructor on the manager.
- *
- * @param create constructor to register
- */
- void (*add_ipsec_interface)(kernel_interface_t *this, kernel_ipsec_constructor_t create);
-
- /**
- * Unregister an ipsec kernel interface constructor.
- *
- * @param create constructor to unregister
- */
- void (*remove_ipsec_interface)(kernel_interface_t *this, kernel_ipsec_constructor_t create);
-
- /**
- * Register a network kernel interface constructor on the manager.
- *
- * @param create constructor to register
- */
- void (*add_net_interface)(kernel_interface_t *this, kernel_net_constructor_t create);
-
- /**
- * Unregister a network kernel interface constructor.
- *
- * @param create constructor to unregister
- */
- void (*remove_net_interface)(kernel_interface_t *this, kernel_net_constructor_t create);
-
- /**
- * Destroys a kernel_interface_manager_t object.
- */
- void (*destroy) (kernel_interface_t *this);
-};
-
-/**
- * Creates an object of type kernel_interface_t.
- */
-kernel_interface_t *kernel_interface_create(void);
-
-#endif /** KERNEL_INTERFACE_H_ @}*/
diff --git a/src/libcharon/kernel/kernel_ipsec.h b/src/libcharon/kernel/kernel_ipsec.h
deleted file mode 100644
index d09265cc9..000000000
--- a/src/libcharon/kernel/kernel_ipsec.h
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Tobias Brunner
- * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup kernel_ipsec kernel_ipsec
- * @{ @ingroup kernel
- */
-
-#ifndef KERNEL_IPSEC_H_
-#define KERNEL_IPSEC_H_
-
-typedef enum ipsec_mode_t ipsec_mode_t;
-typedef enum policy_dir_t policy_dir_t;
-typedef struct kernel_ipsec_t kernel_ipsec_t;
-
-#include <utils/host.h>
-#include <crypto/prf_plus.h>
-#include <config/proposal.h>
-#include <config/child_cfg.h>
-
-/**
- * Mode of a CHILD_SA.
- */
-enum ipsec_mode_t {
- /** transport mode, no inner address */
- MODE_TRANSPORT = 1,
- /** tunnel mode, inner and outer addresses */
- MODE_TUNNEL,
- /** BEET mode, tunnel mode but fixed, bound inner addresses */
- MODE_BEET,
-};
-
-/**
- * enum names for ipsec_mode_t.
- */
-extern enum_name_t *ipsec_mode_names;
-
-/**
- * Direction of a policy. These are equal to those
- * defined in xfrm.h, but we want to stay implementation
- * neutral here.
- */
-enum policy_dir_t {
- /** Policy for inbound traffic */
- POLICY_IN = 0,
- /** Policy for outbound traffic */
- POLICY_OUT = 1,
- /** Policy for forwarded traffic */
- POLICY_FWD = 2,
-};
-
-/**
- * enum names for policy_dir_t.
- */
-extern enum_name_t *policy_dir_names;
-
-/**
- * Interface to the ipsec subsystem of the kernel.
- *
- * The kernel ipsec interface handles the communication with the kernel
- * for SA and policy management. It allows setup of these, and provides
- * further the handling of kernel events.
- * Policy information are cached in the interface. This is necessary to do
- * reference counting. The Linux kernel does not allow the same policy
- * installed twice, but we need this as CHILD_SA exist multiple times
- * when rekeying. Thats why we do reference counting of policies.
- */
-struct kernel_ipsec_t {
-
- /**
- * Get a SPI from the kernel.
- *
- * @param src source address of SA
- * @param dst destination address of SA
- * @param protocol protocol for SA (ESP/AH)
- * @param reqid unique ID for this SA
- * @param spi allocated spi
- * @return SUCCESS if operation completed
- */
- status_t (*get_spi)(kernel_ipsec_t *this, host_t *src, host_t *dst,
- protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi);
-
- /**
- * Get a Compression Parameter Index (CPI) from the kernel.
- *
- * @param src source address of SA
- * @param dst destination address of SA
- * @param reqid unique ID for the corresponding SA
- * @param cpi allocated cpi
- * @return SUCCESS if operation completed
- */
- status_t (*get_cpi)(kernel_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi);
-
- /**
- * Add an SA to the SAD.
- *
- * add_sa() may update an already allocated
- * SPI (via get_spi). In this case, the replace
- * flag must be set.
- * This function does install a single SA for a
- * single protocol in one direction.
- *
- * @param src source address for this SA
- * @param dst destination address for this SA
- * @param spi SPI allocated by us or remote peer
- * @param protocol protocol for this SA (ESP/AH)
- * @param reqid unique ID for this SA
- * @param mark mark for this SA
- * @param lifetime lifetime_cfg_t for this SA
- * @param enc_alg Algorithm to use for encryption (ESP only)
- * @param enc_key key to use for encryption
- * @param int_alg Algorithm to use for integrity protection
- * @param int_key key to use for integrity protection
- * @param mode mode of the SA (tunnel, transport)
- * @param ipcomp IPComp transform to use
- * @param cpi CPI for IPComp
- * @param encap enable UDP encapsulation for NAT traversal
- * @param inbound TRUE if this is an inbound SA
- * @param src_ts traffic selector with BEET source address
- * @param dst_ts traffic selector with BEET destination address
- * @return SUCCESS if operation completed
- */
- status_t (*add_sa) (kernel_ipsec_t *this,
- host_t *src, host_t *dst, u_int32_t spi,
- protocol_id_t protocol, u_int32_t reqid,
- mark_t mark, lifetime_cfg_t *lifetime,
- u_int16_t enc_alg, chunk_t enc_key,
- u_int16_t int_alg, chunk_t int_key,
- ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
- bool encap, bool inbound,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts);
-
- /**
- * Update the hosts on an installed SA.
- *
- * We cannot directly update the destination address as the kernel
- * requires the spi, the protocol AND the destination address (and family)
- * to identify SAs. Therefore if the destination address changed we
- * create a new SA and delete the old one.
- *
- * @param spi SPI of the SA
- * @param protocol protocol for this SA (ESP/AH)
- * @param cpi CPI for IPComp, 0 if no IPComp is used
- * @param src current source address
- * @param dst current destination address
- * @param new_src new source address
- * @param new_dst new destination address
- * @param encap current use of UDP encapsulation
- * @param new_encap new use of UDP encapsulation
- * @param mark optional mark for this SA
- * @return SUCCESS if operation completed, NOT_SUPPORTED if
- * the kernel interface can't update the SA
- */
- status_t (*update_sa)(kernel_ipsec_t *this,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi,
- host_t *src, host_t *dst,
- host_t *new_src, host_t *new_dst,
- bool encap, bool new_encap, mark_t mark);
-
- /**
- * Query the number of bytes processed by an SA from the SAD.
- *
- * @param src source address for this SA
- * @param dst destination address for this SA
- * @param spi SPI allocated by us or remote peer
- * @param protocol protocol for this SA (ESP/AH)
- * @param mark optional mark for this SA
- * @param[out] bytes the number of bytes processed by SA
- * @return SUCCESS if operation completed
- */
- status_t (*query_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, mark_t mark,
- u_int64_t *bytes);
-
- /**
- * Delete a previusly installed SA from the SAD.
- *
- * @param src source address for this SA
- * @param dst destination address for this SA
- * @param spi SPI allocated by us or remote peer
- * @param protocol protocol for this SA (ESP/AH)
- * @param cpi CPI for IPComp or 0
- * @param mark optional mark for this SA
- * @return SUCCESS if operation completed
- */
- status_t (*del_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi,
- mark_t mark);
-
- /**
- * Add a policy to the SPD.
- *
- * A policy is always associated to an SA. Traffic which matches a
- * policy is handled by the SA with the same reqid.
- *
- * @param src source address of SA
- * @param dst dest address of SA
- * @param src_ts traffic selector to match traffic source
- * @param dst_ts traffic selector to match traffic dest
- * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
- * @param spi SPI of SA
- * @param protocol protocol to use to protect traffic (AH/ESP)
- * @param reqid unique ID of an SA to use to enforce policy
- * @param mark mark for this policy
- * @param mode mode of SA (tunnel, transport)
- * @param ipcomp the IPComp transform used
- * @param cpi CPI for IPComp
- * @param routed TRUE, if this policy is routed in the kernel
- * @return SUCCESS if operation completed
- */
- status_t (*add_policy) (kernel_ipsec_t *this,
- host_t *src, host_t *dst,
- traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts,
- policy_dir_t direction, u_int32_t spi,
- protocol_id_t protocol, u_int32_t reqid,
- mark_t mark, ipsec_mode_t mode,
- u_int16_t ipcomp, u_int16_t cpi, bool routed);
-
- /**
- * Query the use time of a policy.
- *
- * The use time of a policy is the time the policy was used for the last
- * time. It is not the system time, but a monotonic timestamp as returned
- * by time_monotonic.
- *
- * @param src_ts traffic selector to match traffic source
- * @param dst_ts traffic selector to match traffic dest
- * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
- * @param mark optional mark
- * @param[out] use_time the monotonic timestamp of this SA's last use
- * @return SUCCESS if operation completed
- */
- status_t (*query_policy) (kernel_ipsec_t *this,
- traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts,
- policy_dir_t direction, mark_t mark,
- u_int32_t *use_time);
-
- /**
- * Remove a policy from the SPD.
- *
- * The kernel interface implements reference counting for policies.
- * If the same policy is installed multiple times (in the case of rekeying),
- * the reference counter is increased. del_policy() decreases the ref counter
- * and removes the policy only when no more references are available.
- *
- * @param src_ts traffic selector to match traffic source
- * @param dst_ts traffic selector to match traffic dest
- * @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
- * @param mark optional mark
- * @param unrouted TRUE, if this policy is unrouted from the kernel
- * @return SUCCESS if operation completed
- */
- status_t (*del_policy) (kernel_ipsec_t *this,
- traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts,
- policy_dir_t direction, mark_t mark,
- bool unrouted);
-
- /**
- * Install a bypass policy for the given socket.
- *
- * @param fd socket file descriptor to setup policy for
- * @param family protocol family of the socket
- * @return TRUE of policy set up successfully
- */
- bool (*bypass_socket)(kernel_ipsec_t *this, int fd, int family);
-
- /**
- * Destroy the implementation.
- */
- void (*destroy) (kernel_ipsec_t *this);
-};
-
-#endif /** KERNEL_IPSEC_H_ @}*/
diff --git a/src/libcharon/kernel/kernel_net.h b/src/libcharon/kernel/kernel_net.h
deleted file mode 100644
index efb221f88..000000000
--- a/src/libcharon/kernel/kernel_net.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup kernel_net kernel_net
- * @{ @ingroup kernel
- */
-
-#ifndef KERNEL_NET_H_
-#define KERNEL_NET_H_
-
-typedef struct kernel_net_t kernel_net_t;
-
-#include <utils/enumerator.h>
-#include <utils/host.h>
-
-/**
- * Interface to the network subsystem of the kernel.
- *
- * The kernel network interface handles the communication with the kernel
- * for interface and IP address management.
- */
-struct kernel_net_t {
-
- /**
- * Get our outgoing source address for a destination.
- *
- * Does a route lookup to get the source address used to reach dest.
- * The returned host is allocated and must be destroyed.
- * An optional src address can be used to check if a route is available
- * for given source to dest.
- *
- * @param dest target destination address
- * @param src source address to check, or NULL
- * @return outgoing source address, NULL if unreachable
- */
- host_t* (*get_source_addr)(kernel_net_t *this, host_t *dest, host_t *src);
-
- /**
- * Get the next hop for a destination.
- *
- * Does a route lookup to get the next hop used to reach dest.
- * The returned host is allocated and must be destroyed.
- *
- * @param dest target destination address
- * @return next hop address, NULL if unreachable
- */
- host_t* (*get_nexthop)(kernel_net_t *this, host_t *dest);
-
- /**
- * Get the interface name of a local address.
- *
- * @param host address to get interface name from
- * @return allocated interface name, or NULL if not found
- */
- char* (*get_interface) (kernel_net_t *this, host_t *host);
-
- /**
- * Creates an enumerator over all local addresses.
- *
- * This function blocks an internal cached address list until the
- * enumerator gets destroyed.
- * The hosts are read-only, do not modify of free.
- *
- * @param include_down_ifaces TRUE to enumerate addresses from down interfaces
- * @param include_virtual_ips TRUE to enumerate virtual ip addresses
- * @return enumerator over host_t's
- */
- enumerator_t *(*create_address_enumerator) (kernel_net_t *this,
- bool include_down_ifaces, bool include_virtual_ips);
-
- /**
- * Add a virtual IP to an interface.
- *
- * Virtual IPs are attached to an interface. If an IP is added multiple
- * times, the IP is refcounted and not removed until del_ip() was called
- * as many times as add_ip().
- * The virtual IP is attached to the interface where the iface_ip is found.
- *
- * @param virtual_ip virtual ip address to assign
- * @param iface_ip IP of an interface to attach virtual IP
- * @return SUCCESS if operation completed
- */
- status_t (*add_ip) (kernel_net_t *this, host_t *virtual_ip,
- host_t *iface_ip);
-
- /**
- * Remove a virtual IP from an interface.
- *
- * The kernel interface uses refcounting, see add_ip().
- *
- * @param virtual_ip virtual ip address to assign
- * @return SUCCESS if operation completed
- */
- status_t (*del_ip) (kernel_net_t *this, host_t *virtual_ip);
-
- /**
- * Add a route.
- *
- * @param dst_net destination net
- * @param prefixlen destination net prefix length
- * @param gateway gateway for this route
- * @param src_ip sourc ip of the route
- * @param if_name name of the interface the route is bound to
- * @return SUCCESS if operation completed
- * ALREADY_DONE if the route already exists
- */
- status_t (*add_route) (kernel_net_t *this, chunk_t dst_net, u_int8_t prefixlen,
- host_t *gateway, host_t *src_ip, char *if_name);
-
- /**
- * Delete a route.
- *
- * @param dst_net destination net
- * @param prefixlen destination net prefix length
- * @param gateway gateway for this route
- * @param src_ip sourc ip of the route
- * @param if_name name of the interface the route is bound to
- * @return SUCCESS if operation completed
- */
- status_t (*del_route) (kernel_net_t *this, chunk_t dst_net, u_int8_t prefixlen,
- host_t *gateway, host_t *src_ip, char *if_name);
-
- /**
- * Destroy the implementation.
- */
- void (*destroy) (kernel_net_t *this);
-};
-
-#endif /** KERNEL_NET_H_ @}*/
diff --git a/src/libcharon/network/receiver.c b/src/libcharon/network/receiver.c
index 63a8cab58..d8cebe192 100644
--- a/src/libcharon/network/receiver.c
+++ b/src/libcharon/network/receiver.c
@@ -146,7 +146,7 @@ static void send_notify(message_t *request, notify_type_t type, chunk_t data)
ike_sa_id->switch_initiator(ike_sa_id);
response->set_ike_sa_id(response, ike_sa_id);
response->add_notify(response, FALSE, type, data);
- if (response->generate(response, NULL, NULL, &packet) == SUCCESS)
+ if (response->generate(response, NULL, &packet) == SUCCESS)
{
charon->sender->send(charon->sender, packet);
response->destroy(response);
@@ -274,9 +274,17 @@ static job_requeue_t receive_packets(private_receiver_t *this)
{
packet_t *packet;
message_t *message;
+ status_t status;
/* read in a packet */
- if (charon->socket->receive(charon->socket, &packet) != SUCCESS)
+ status = charon->socket->receive(charon->socket, &packet);
+ if (status == NOT_SUPPORTED)
+ {
+ /* the processor destroys this job */
+ this->job = NULL;
+ return JOB_REQUEUE_NONE;
+ }
+ else if (status != SUCCESS)
{
DBG2(DBG_NET, "receiving from socket failed!");
return JOB_REQUEUE_FAIR;
@@ -353,22 +361,25 @@ static job_requeue_t receive_packets(private_receiver_t *this)
{
DBG1(DBG_NET, "using receive delay: %dms",
this->receive_delay);
- charon->scheduler->schedule_job_ms(charon->scheduler,
+ lib->scheduler->schedule_job_ms(lib->scheduler,
(job_t*)process_message_job_create(message),
this->receive_delay);
return JOB_REQUEUE_DIRECT;
}
}
}
- charon->processor->queue_job(charon->processor,
- (job_t*)process_message_job_create(message));
+ lib->processor->queue_job(lib->processor,
+ (job_t*)process_message_job_create(message));
return JOB_REQUEUE_DIRECT;
}
METHOD(receiver_t, destroy, void,
private_receiver_t *this)
{
- this->job->cancel(this->job);
+ if (this->job)
+ {
+ this->job->cancel(this->job);
+ }
this->rng->destroy(this->rng);
this->hasher->destroy(this->hasher);
free(this);
@@ -383,7 +394,9 @@ receiver_t *receiver_create()
u_int32_t now = time_monotonic(NULL);
INIT(this,
- .public.destroy = _destroy,
+ .public = {
+ .destroy = _destroy,
+ },
.secret_switch = now,
.secret_offset = random() % now,
);
@@ -424,7 +437,7 @@ receiver_t *receiver_create()
this->job = callback_job_create((callback_job_cb_t)receive_packets,
this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
}
diff --git a/src/libcharon/network/sender.c b/src/libcharon/network/sender.c
index bb6d50605..4177fb3e1 100644
--- a/src/libcharon/network/sender.c
+++ b/src/libcharon/network/sender.c
@@ -195,7 +195,7 @@ sender_t * sender_create()
"charon.send_delay_response", TRUE),
);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
}
diff --git a/src/libcharon/network/socket.h b/src/libcharon/network/socket.h
index 5c5a4edfb..51b26920f 100644
--- a/src/libcharon/network/socket.h
+++ b/src/libcharon/network/socket.h
@@ -1,6 +1,7 @@
/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi
+ * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -30,6 +31,11 @@ typedef struct socket_t socket_t;
#include <utils/enumerator.h>
/**
+ * Constructor prototype for sockets.
+ */
+typedef socket_t *(*socket_constructor_t)();
+
+/**
* Socket interface definition.
*/
struct socket_t {
@@ -42,8 +48,8 @@ struct socket_t {
*
* @param packet pinter gets address from allocated packet_t
* @return
- * - SUCCESS when packet successfully received
- * - FAILED when unable to receive
+ * - SUCCESS when packet successfully received
+ * - FAILED when unable to receive
*/
status_t (*receive) (socket_t *this, packet_t **packet);
@@ -55,10 +61,15 @@ struct socket_t {
*
* @param packet packet_t to send
* @return
- * - SUCCESS when packet successfully sent
- * - FAILED when unable to send
+ * - SUCCESS when packet successfully sent
+ * - FAILED when unable to send
*/
status_t (*send) (socket_t *this, packet_t *packet);
+
+ /**
+ * Destroy a socket implementation.
+ */
+ void (*destroy) (socket_t *this);
};
#endif /** SOCKET_H_ @}*/
diff --git a/src/libcharon/network/socket_manager.c b/src/libcharon/network/socket_manager.c
index 0dbce4b1b..72a454301 100644
--- a/src/libcharon/network/socket_manager.c
+++ b/src/libcharon/network/socket_manager.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -33,11 +35,21 @@ struct private_socket_manager_t {
socket_manager_t public;
/**
- * List of registered socket
+ * List of registered socket constructors
*/
linked_list_t *sockets;
/**
+ * Instantiated socket implementation
+ */
+ socket_t *socket;
+
+ /**
+ * The constructor used to create the current socket
+ */
+ socket_constructor_t create;
+
+ /**
* Lock for sockets list
*/
rwlock_t *lock;
@@ -46,11 +58,9 @@ struct private_socket_manager_t {
METHOD(socket_manager_t, receiver, status_t,
private_socket_manager_t *this, packet_t **packet)
{
- socket_t *socket;
status_t status;
-
this->lock->read_lock(this->lock);
- if (this->sockets->get_first(this->sockets, (void**)&socket) != SUCCESS)
+ if (!this->socket)
{
DBG1(DBG_NET, "no socket implementation registered, receiving failed");
this->lock->unlock(this->lock);
@@ -58,7 +68,7 @@ METHOD(socket_manager_t, receiver, status_t,
}
/* receive is blocking and the thread can be cancelled */
thread_cleanup_push((thread_cleanup_t)this->lock->unlock, this->lock);
- status = socket->receive(socket, packet);
+ status = this->socket->receive(this->socket, packet);
thread_cleanup_pop(TRUE);
return status;
}
@@ -66,40 +76,67 @@ METHOD(socket_manager_t, receiver, status_t,
METHOD(socket_manager_t, sender, status_t,
private_socket_manager_t *this, packet_t *packet)
{
- socket_t *socket;
status_t status;
-
this->lock->read_lock(this->lock);
- if (this->sockets->get_first(this->sockets, (void**)&socket) != SUCCESS)
+ if (!this->socket)
{
DBG1(DBG_NET, "no socket implementation registered, sending failed");
this->lock->unlock(this->lock);
return NOT_SUPPORTED;
}
- status = socket->send(socket, packet);
+ status = this->socket->send(this->socket, packet);
this->lock->unlock(this->lock);
return status;
}
+static void create_socket(private_socket_manager_t *this)
+{
+ socket_constructor_t create;
+ /* remove constructors in order to avoid trying to create broken ones
+ * multiple times */
+ while (this->sockets->remove_first(this->sockets,
+ (void**)&create) == SUCCESS)
+ {
+ this->socket = create();
+ if (this->socket)
+ {
+ this->create = create;
+ break;
+ }
+ }
+}
+
METHOD(socket_manager_t, add_socket, void,
- private_socket_manager_t *this, socket_t *socket)
+ private_socket_manager_t *this, socket_constructor_t create)
{
this->lock->write_lock(this->lock);
- this->sockets->insert_last(this->sockets, socket);
+ this->sockets->insert_last(this->sockets, create);
+ if (!this->socket)
+ {
+ create_socket(this);
+ }
this->lock->unlock(this->lock);
}
METHOD(socket_manager_t, remove_socket, void,
- private_socket_manager_t *this, socket_t *socket)
+ private_socket_manager_t *this, socket_constructor_t create)
{
this->lock->write_lock(this->lock);
- this->sockets->remove(this->sockets, socket, NULL);
+ this->sockets->remove(this->sockets, create, NULL);
+ if (this->create == create)
+ {
+ this->socket->destroy(this->socket);
+ this->socket = NULL;
+ this->create = NULL;
+ create_socket(this);
+ }
this->lock->unlock(this->lock);
}
METHOD(socket_manager_t, destroy, void,
private_socket_manager_t *this)
{
+ DESTROY_IF(this->socket);
this->sockets->destroy(this->sockets);
this->lock->destroy(this->lock);
free(this);
diff --git a/src/libcharon/network/socket_manager.h b/src/libcharon/network/socket_manager.h
index b33d5c71c..94185d21c 100644
--- a/src/libcharon/network/socket_manager.h
+++ b/src/libcharon/network/socket_manager.h
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -51,14 +53,18 @@ struct socket_manager_t {
status_t (*send) (socket_manager_t *this, packet_t *packet);
/**
- * Register a socket implementation.
+ * Register a socket constructor.
+ *
+ * @param create constructor for the socket
*/
- void (*add_socket)(socket_manager_t *this, socket_t *socket);
+ void (*add_socket)(socket_manager_t *this, socket_constructor_t create);
/**
- * Unregister a registered socket implementation.
+ * Unregister a registered socket constructor.
+ *
+ * @param create constructor for the socket
*/
- void (*remove_socket)(socket_manager_t *this, socket_t *socket);
+ void (*remove_socket)(socket_manager_t *this, socket_constructor_t create);
/**
* Destroy a socket_manager_t.
diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in
index 4cb047929..426d1a689 100644
--- a/src/libcharon/plugins/addrblock/Makefile.in
+++ b/src/libcharon/plugins/addrblock/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -168,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/addrblock/addrblock_plugin.c b/src/libcharon/plugins/addrblock/addrblock_plugin.c
index 1c407035d..5fdb36c5c 100644
--- a/src/libcharon/plugins/addrblock/addrblock_plugin.c
+++ b/src/libcharon/plugins/addrblock/addrblock_plugin.c
@@ -61,7 +61,11 @@ plugin_t *addrblock_plugin_create()
private_addrblock_plugin_t *this;
INIT(this,
- .public.plugin.destroy = _destroy,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
.validator = addrblock_validator_create(),
.narrower = addrblock_narrow_create(),
);
diff --git a/src/libcharon/plugins/android/Makefile.in b/src/libcharon/plugins/android/Makefile.in
index 6e4903ee1..d80868798 100644
--- a/src/libcharon/plugins/android/Makefile.in
+++ b/src/libcharon/plugins/android/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -168,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/android/android_plugin.c b/src/libcharon/plugins/android/android_plugin.c
index e2c8572ef..3d82d8f60 100644
--- a/src/libcharon/plugins/android/android_plugin.c
+++ b/src/libcharon/plugins/android/android_plugin.c
@@ -79,8 +79,10 @@ plugin_t *android_plugin_create()
private_android_plugin_t *this;
INIT(this,
- .public.plugin = {
- .destroy = _destroy,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
},
.logger = android_logger_create(),
.handler = android_handler_create(),
diff --git a/src/libcharon/plugins/android/android_service.c b/src/libcharon/plugins/android/android_service.c
index 538c4a9a2..f9a8e1ea1 100644
--- a/src/libcharon/plugins/android/android_service.c
+++ b/src/libcharon/plugins/android/android_service.c
@@ -141,7 +141,7 @@ METHOD(listener_t, child_updown, bool,
* callback, but from a different thread. we also delay it to avoid
* a race condition during a regular shutdown */
job = callback_job_create(shutdown_callback, NULL, NULL, NULL);
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, 1);
+ lib->scheduler->schedule_job(lib->scheduler, (job_t*)job, 1);
return FALSE;
}
}
@@ -378,7 +378,7 @@ android_service_t *android_service_create(android_creds_t *creds)
charon->bus->add_listener(charon->bus, &this->public.listener);
this->job = callback_job_create((callback_job_cb_t)initiate, this,
NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
}
diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in
index b34654fb7..e843c42e8 100644
--- a/src/libcharon/plugins/dhcp/Makefile.in
+++ b/src/libcharon/plugins/dhcp/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -165,6 +166,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -196,14 +199,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -218,24 +224,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -243,7 +256,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/dhcp/dhcp_plugin.c b/src/libcharon/plugins/dhcp/dhcp_plugin.c
index 829fd6356..fccc99ba5 100644
--- a/src/libcharon/plugins/dhcp/dhcp_plugin.c
+++ b/src/libcharon/plugins/dhcp/dhcp_plugin.c
@@ -62,7 +62,11 @@ plugin_t *dhcp_plugin_create()
private_dhcp_plugin_t *this;
INIT(this,
- .public.plugin.destroy = _destroy,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
.socket = dhcp_socket_create(),
);
diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c
index f61b3a60e..e1e83d648 100644
--- a/src/libcharon/plugins/dhcp/dhcp_socket.c
+++ b/src/libcharon/plugins/dhcp/dhcp_socket.c
@@ -31,6 +31,7 @@
#include <threading/condvar.h>
#include <threading/thread.h>
+#include <hydra.h>
#include <daemon.h>
#include <processing/jobs/callback_job.h>
@@ -205,8 +206,8 @@ static int prepare_dhcp(private_dhcp_socket_t *this,
else
{
/* act as relay agent */
- src = charon->kernel_interface->get_source_addr(
- charon->kernel_interface, this->dst, NULL);
+ src = hydra->kernel_interface->get_source_addr(hydra->kernel_interface,
+ this->dst, NULL);
if (src)
{
memcpy(&dhcp->gateway_address, src->get_address(src).ptr,
@@ -462,8 +463,6 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
offer = host_create_from_chunk(AF_INET,
chunk_from_thing(dhcp->your_address), 0);
- server = host_create_from_chunk(AF_INET,
- chunk_from_thing(dhcp->server_address), DHCP_SERVER_PORT);
this->mutex->lock(this->mutex);
enumerator = this->discover->create_enumerator(this->discover);
@@ -471,11 +470,8 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
{
if (transaction->get_id(transaction) == dhcp->transaction_id)
{
- DBG1(DBG_CFG, "received DHCP OFFER %H from %H", offer, server);
this->discover->remove_at(this->discover, enumerator);
this->request->insert_last(this->request, transaction);
- transaction->set_address(transaction, offer->clone(offer));
- transaction->set_server(transaction, server->clone(server));
break;
}
}
@@ -504,9 +500,22 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
chunk_create((char*)&option->data[pos], 4));
}
}
+ if (option->type == DHCP_SERVER_ID && option->len == 4)
+ {
+ server = host_create_from_chunk(AF_INET,
+ chunk_create(option->data, 4), DHCP_SERVER_PORT);
+ }
optlen -= optsize;
optpos += optsize;
}
+ if (!server)
+ {
+ server = host_create_from_chunk(AF_INET,
+ chunk_from_thing(dhcp->server_address), DHCP_SERVER_PORT);
+ }
+ DBG1(DBG_CFG, "received DHCP OFFER %H from %H", offer, server);
+ transaction->set_address(transaction, offer->clone(offer));
+ transaction->set_server(transaction, server->clone(server));
}
this->mutex->unlock(this->mutex);
this->condvar->broadcast(this->condvar);
@@ -751,7 +760,7 @@ dhcp_socket_t *dhcp_socket_create()
this->job = callback_job_create((callback_job_cb_t)receive_dhcp,
this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in
index 14bf3f15d..c0750786d 100644
--- a/src/libcharon/plugins/eap_aka/Makefile.in
+++ b/src/libcharon/plugins/eap_aka/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -168,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
index b41b59616..41f69546e 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
+++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -169,6 +170,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -200,14 +203,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -222,24 +228,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -247,7 +260,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in
index 57952f621..02d659197 100644
--- a/src/libcharon/plugins/eap_gtc/Makefile.in
+++ b/src/libcharon/plugins/eap_gtc/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -166,6 +167,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -197,14 +200,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -219,24 +225,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -244,7 +257,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in
index d78957438..46011694a 100644
--- a/src/libcharon/plugins/eap_identity/Makefile.in
+++ b/src/libcharon/plugins/eap_identity/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -168,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_identity/eap_identity.c b/src/libcharon/plugins/eap_identity/eap_identity.c
index ab082a955..03066b2f8 100644
--- a/src/libcharon/plugins/eap_identity/eap_identity.c
+++ b/src/libcharon/plugins/eap_identity/eap_identity.c
@@ -59,11 +59,8 @@ struct eap_identity_header_t {
u_int8_t data[];
} __attribute__((__packed__));
-/**
- * Implementation of eap_method_t.process for the peer
- */
-static status_t process_peer(private_eap_identity_t *this,
- eap_payload_t *in, eap_payload_t **out)
+METHOD(eap_method_t, process_peer, status_t,
+ private_eap_identity_t *this, eap_payload_t *in, eap_payload_t **out)
{
chunk_t id;
eap_identity_header_t *hdr;
@@ -74,7 +71,7 @@ static status_t process_peer(private_eap_identity_t *this,
hdr = alloca(len);
hdr->code = EAP_RESPONSE;
- hdr->identifier = in->get_identifier(in);
+ hdr->identifier = in ? in->get_identifier(in) : 0;
hdr->length = htons(len);
hdr->type = EAP_IDENTITY;
memcpy(hdr->data, id.ptr, id.len);
@@ -83,20 +80,15 @@ static status_t process_peer(private_eap_identity_t *this,
return SUCCESS;
}
-/**
- * Implementation of eap_method_t.initiate for the peer
- */
-static status_t initiate_peer(private_eap_identity_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate_peer, status_t,
+ private_eap_identity_t *this, eap_payload_t **out)
{
/* peer never initiates */
return FAILED;
}
-/**
- * Implementation of eap_method_t.process for the server
- */
-static status_t process_server(private_eap_identity_t *this,
- eap_payload_t *in, eap_payload_t **out)
+METHOD(eap_method_t, process_server, status_t,
+ private_eap_identity_t *this, eap_payload_t *in, eap_payload_t **out)
{
chunk_t data;
@@ -108,10 +100,8 @@ static status_t process_server(private_eap_identity_t *this,
return SUCCESS;
}
-/**
- * Implementation of eap_method_t.initiate for the server
- */
-static status_t initiate_server(private_eap_identity_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate_server, status_t,
+ private_eap_identity_t *this, eap_payload_t **out)
{
eap_identity_header_t hdr;
@@ -125,19 +115,15 @@ static status_t initiate_server(private_eap_identity_t *this, eap_payload_t **ou
return NEED_MORE;
}
-/**
- * Implementation of eap_method_t.get_type.
- */
-static eap_type_t get_type(private_eap_identity_t *this, u_int32_t *vendor)
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_identity_t *this, u_int32_t *vendor)
{
*vendor = 0;
return EAP_IDENTITY;
}
-/**
- * Implementation of eap_method_t.get_msk.
- */
-static status_t get_msk(private_eap_identity_t *this, chunk_t *msk)
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_identity_t *this, chunk_t *msk)
{
if (this->identity.ptr)
{
@@ -147,56 +133,42 @@ static status_t get_msk(private_eap_identity_t *this, chunk_t *msk)
return FAILED;
}
-/**
- * Implementation of eap_method_t.is_mutual.
- */
-static bool is_mutual(private_eap_identity_t *this)
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_identity_t *this)
{
return FALSE;
}
-/**
- * Implementation of eap_method_t.destroy.
- */
-static void destroy(private_eap_identity_t *this)
+METHOD(eap_method_t, destroy, void,
+ private_eap_identity_t *this)
{
this->peer->destroy(this->peer);
free(this->identity.ptr);
free(this);
}
-/**
- * Generic constructor
- */
-static private_eap_identity_t *eap_identity_create(identification_t *server,
- identification_t *peer)
-{
- private_eap_identity_t *this = malloc_thing(private_eap_identity_t);
-
- this->public.eap_method_interface.initiate = NULL;
- this->public.eap_method_interface.process = NULL;
- this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
- this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
- this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
- this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
-
- this->peer = peer->clone(peer);
- this->identity = chunk_empty;
-
- return this;
-}
-
/*
* Described in header.
*/
eap_identity_t *eap_identity_create_peer(identification_t *server,
identification_t *peer)
{
- private_eap_identity_t *this = eap_identity_create(server, peer);
-
- /* public functions */
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_peer;
+ private_eap_identity_t *this;
+
+ INIT(this,
+ .public = {
+ .eap_method = {
+ .initiate = _initiate_peer,
+ .process = _process_peer,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .destroy = _destroy,
+ },
+ },
+ .peer = peer->clone(peer),
+ .identity = chunk_empty,
+ );
return &this->public;
}
@@ -207,11 +179,22 @@ eap_identity_t *eap_identity_create_peer(identification_t *server,
eap_identity_t *eap_identity_create_server(identification_t *server,
identification_t *peer)
{
- private_eap_identity_t *this = eap_identity_create(server, peer);
-
- /* public functions */
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_server;
+ private_eap_identity_t *this;
+
+ INIT(this,
+ .public = {
+ .eap_method = {
+ .initiate = _initiate_server,
+ .process = _process_server,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .destroy = _destroy,
+ },
+ },
+ .peer = peer->clone(peer),
+ .identity = chunk_empty,
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_identity/eap_identity.h b/src/libcharon/plugins/eap_identity/eap_identity.h
index 7364a8bda..9a7f28574 100644
--- a/src/libcharon/plugins/eap_identity/eap_identity.h
+++ b/src/libcharon/plugins/eap_identity/eap_identity.h
@@ -33,7 +33,7 @@ struct eap_identity_t {
/**
* Implemented eap_method_t interface.
*/
- eap_method_t eap_method_interface;
+ eap_method_t eap_method;
};
/**
diff --git a/src/libcharon/plugins/eap_identity/eap_identity_plugin.c b/src/libcharon/plugins/eap_identity/eap_identity_plugin.c
index 082997154..079c27909 100644
--- a/src/libcharon/plugins/eap_identity/eap_identity_plugin.c
+++ b/src/libcharon/plugins/eap_identity/eap_identity_plugin.c
@@ -14,15 +14,12 @@
*/
#include "eap_identity_plugin.h"
-
#include "eap_identity.h"
#include <daemon.h>
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(eap_identity_plugin_t *this)
+METHOD(plugin_t, destroy, void,
+ eap_identity_plugin_t *this)
{
charon->eap->remove_method(charon->eap,
(eap_constructor_t)eap_identity_create_server);
@@ -36,9 +33,13 @@ static void destroy(eap_identity_plugin_t *this)
*/
plugin_t *eap_identity_plugin_create()
{
- eap_identity_plugin_t *this = malloc_thing(eap_identity_plugin_t);
+ eap_identity_plugin_t *this;
- this->plugin.destroy = (void(*)(plugin_t*))destroy;
+ INIT(this,
+ .plugin = {
+ .destroy = _destroy,
+ },
+ );
charon->eap->add_method(charon->eap, EAP_IDENTITY, 0, EAP_SERVER,
(eap_constructor_t)eap_identity_create_server);
diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in
index 5bfc59fa4..2e307147f 100644
--- a/src/libcharon/plugins/eap_md5/Makefile.in
+++ b/src/libcharon/plugins/eap_md5/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -166,6 +167,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -197,14 +200,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -219,24 +225,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -244,7 +257,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_md5/eap_md5.c b/src/libcharon/plugins/eap_md5/eap_md5.c
index 3554ae12e..f70754abb 100644
--- a/src/libcharon/plugins/eap_md5/eap_md5.c
+++ b/src/libcharon/plugins/eap_md5/eap_md5.c
@@ -47,7 +47,7 @@ struct private_eap_md5_t {
chunk_t challenge;
/**
- * EAP message identififier
+ * EAP message identifier
*/
u_int8_t identifier;
};
@@ -105,19 +105,15 @@ static status_t hash_challenge(private_eap_md5_t *this, chunk_t *response,
return SUCCESS;
}
-/**
- * Implementation of eap_method_t.initiate for the peer
- */
-static status_t initiate_peer(private_eap_md5_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate_peer, status_t,
+ private_eap_md5_t *this, eap_payload_t **out)
{
/* peer never initiates */
return FAILED;
}
-/**
- * Implementation of eap_method_t.initiate for the server
- */
-static status_t initiate_server(private_eap_md5_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate_server, status_t,
+ private_eap_md5_t *this, eap_payload_t **out)
{
rng_t *rng;
eap_md5_header_t *req;
@@ -142,11 +138,8 @@ static status_t initiate_server(private_eap_md5_t *this, eap_payload_t **out)
return NEED_MORE;
}
-/**
- * Implementation of eap_method_t.process for the peer
- */
-static status_t process_peer(private_eap_md5_t *this,
- eap_payload_t *in, eap_payload_t **out)
+METHOD(eap_method_t, process_peer, status_t,
+ private_eap_md5_t *this, eap_payload_t *in, eap_payload_t **out)
{
chunk_t response;
chunk_t data;
@@ -177,11 +170,8 @@ static status_t process_peer(private_eap_md5_t *this,
return NEED_MORE;
}
-/**
- * Implementation of eap_method_t.process for the server
- */
-static status_t process_server(private_eap_md5_t *this,
- eap_payload_t *in, eap_payload_t **out)
+METHOD(eap_method_t, process_server, status_t,
+ private_eap_md5_t *this, eap_payload_t *in, eap_payload_t **out)
{
chunk_t response, expected;
chunk_t data;
@@ -209,35 +199,27 @@ static status_t process_server(private_eap_md5_t *this,
return SUCCESS;
}
-/**
- * Implementation of eap_method_t.get_type.
- */
-static eap_type_t get_type(private_eap_md5_t *this, u_int32_t *vendor)
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_md5_t *this, u_int32_t *vendor)
{
*vendor = 0;
return EAP_MD5;
}
-/**
- * Implementation of eap_method_t.get_msk.
- */
-static status_t get_msk(private_eap_md5_t *this, chunk_t *msk)
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_md5_t *this, chunk_t *msk)
{
return FAILED;
}
-/**
- * Implementation of eap_method_t.is_mutual.
- */
-static bool is_mutual(private_eap_md5_t *this)
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_md5_t *this)
{
return FALSE;
}
-/**
- * Implementation of eap_method_t.destroy.
- */
-static void destroy(private_eap_md5_t *this)
+METHOD(eap_method_t, destroy, void,
+ private_eap_md5_t *this)
{
this->peer->destroy(this->peer);
this->server->destroy(this->server);
@@ -245,39 +227,27 @@ static void destroy(private_eap_md5_t *this)
free(this);
}
-/**
- * Generic constructor
- */
-static private_eap_md5_t *eap_md5_create_generic(identification_t *server,
- identification_t *peer)
-{
- private_eap_md5_t *this = malloc_thing(private_eap_md5_t);
-
- this->public.eap_method_interface.initiate = NULL;
- this->public.eap_method_interface.process = NULL;
- this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
- this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
- this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
- this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
-
- /* private data */
- this->peer = peer->clone(peer);
- this->server = server->clone(server);
- this->challenge = chunk_empty;
- this->identifier = 0;
-
- return this;
-}
-
/*
- * see header
+ * See header
*/
eap_md5_t *eap_md5_create_server(identification_t *server, identification_t *peer)
{
- private_eap_md5_t *this = eap_md5_create_generic(server, peer);
-
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_server;
+ private_eap_md5_t *this;
+
+ INIT(this,
+ .public = {
+ .eap_method = {
+ .initiate = _initiate_server,
+ .process = _process_server,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .destroy = _destroy,
+ },
+ },
+ .peer = peer->clone(peer),
+ .server = server->clone(server),
+ );
/* generate a non-zero identifier */
do {
@@ -288,14 +258,26 @@ eap_md5_t *eap_md5_create_server(identification_t *server, identification_t *pee
}
/*
- * see header
+ * See header
*/
eap_md5_t *eap_md5_create_peer(identification_t *server, identification_t *peer)
{
- private_eap_md5_t *this = eap_md5_create_generic(server, peer);
-
- this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer;
- this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_peer;
+ private_eap_md5_t *this;
+
+ INIT(this,
+ .public = {
+ .eap_method = {
+ .initiate = _initiate_peer,
+ .process = _process_peer,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .destroy = _destroy,
+ },
+ },
+ .peer = peer->clone(peer),
+ .server = server->clone(server),
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_md5/eap_md5.h b/src/libcharon/plugins/eap_md5/eap_md5.h
index 3cff0dd79..c6687149a 100644
--- a/src/libcharon/plugins/eap_md5/eap_md5.h
+++ b/src/libcharon/plugins/eap_md5/eap_md5.h
@@ -33,7 +33,7 @@ struct eap_md5_t {
/**
* Implemented eap_method_t interface.
*/
- eap_method_t eap_method_interface;
+ eap_method_t eap_method;
};
/**
diff --git a/src/libcharon/plugins/eap_md5/eap_md5_plugin.c b/src/libcharon/plugins/eap_md5/eap_md5_plugin.c
index e716dc6e8..39a6f5731 100644
--- a/src/libcharon/plugins/eap_md5/eap_md5_plugin.c
+++ b/src/libcharon/plugins/eap_md5/eap_md5_plugin.c
@@ -14,15 +14,12 @@
*/
#include "eap_md5_plugin.h"
-
#include "eap_md5.h"
#include <daemon.h>
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(eap_md5_plugin_t *this)
+METHOD(plugin_t, destroy, void,
+ eap_md5_plugin_t *this)
{
charon->eap->remove_method(charon->eap,
(eap_constructor_t)eap_md5_create_server);
@@ -36,9 +33,13 @@ static void destroy(eap_md5_plugin_t *this)
*/
plugin_t *eap_md5_plugin_create()
{
- eap_md5_plugin_t *this = malloc_thing(eap_md5_plugin_t);
+ eap_md5_plugin_t *this;
- this->plugin.destroy = (void(*)(plugin_t*))destroy;
+ INIT(this,
+ .plugin = {
+ .destroy = _destroy,
+ },
+ );
charon->eap->add_method(charon->eap, EAP_MD5, 0, EAP_SERVER,
(eap_constructor_t)eap_md5_create_server);
diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in
index d61cc9e5d..635cfe6ec 100644
--- a/src/libcharon/plugins/eap_mschapv2/Makefile.in
+++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -168,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
index 3cd8d994c..4f39c8608 100644
--- a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
+++ b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
@@ -818,7 +818,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
eap_mschapv2_header_t *eap;
chunk_t data;
char *message, *token, *msg = NULL;
- int message_len, error = 0, retryable;
+ int message_len, error = 0, retriable;
chunk_t challenge = chunk_empty;
data = in->get_data(in);
@@ -847,7 +847,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
else if (strneq(token, "R=", 2))
{
token += 2;
- retryable = atoi(token);
+ retriable = atoi(token);
}
else if (strneq(token, "C=", 2))
{
@@ -880,17 +880,17 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
mschapv2_error_names, error, sanitize(msg));
/**
- * at this point, if the error is retryable, we MAY retry the authentication
+ * at this point, if the error is retriable, we MAY retry the authentication
* or MAY send a Change Password packet.
*
- * if the error is not retryable (or if we do neither of the above), we
+ * if the error is not retriable (or if we do neither of the above), we
* SHOULD send a Failure Response packet.
* windows clients don't do that, and since windows server 2008 r2 behaves
* pretty odd if we do send a Failure Response, we just don't send one
* either. windows 7 actually sends a delete notify (which, according to the
* logs, results in an error on windows server 2008 r2).
*
- * btw, windows server 2008 r2 does not send non-retryable errors for e.g.
+ * btw, windows server 2008 r2 does not send non-retriable errors for e.g.
* a disabled account but returns the windows error code in a notify payload
* of type 12345.
*/
diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in
index bb372d13c..1d771d9a4 100644
--- a/src/libcharon/plugins/eap_radius/Makefile.in
+++ b/src/libcharon/plugins/eap_radius/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -169,6 +170,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -200,14 +203,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -222,24 +228,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -247,7 +260,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_radius/eap_radius.c b/src/libcharon/plugins/eap_radius/eap_radius.c
index 65b868bc6..157034fe5 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius.c
@@ -20,6 +20,8 @@
#include <daemon.h>
+#define TUNNEL_TYPE_ESP 9
+
typedef struct private_eap_radius_t private_eap_radius_t;
/**
@@ -71,6 +73,11 @@ struct private_eap_radius_t {
* Handle the Class attribute as group membership information?
*/
bool class_group;
+
+ /**
+ * Handle the Filter-Id attribute as IPsec CHILD_SA name?
+ */
+ bool filter_id;
};
/**
@@ -211,6 +218,62 @@ static void process_class(private_eap_radius_t *this, radius_message_t *msg)
enumerator->destroy(enumerator);
}
+/**
+ * Handle the Filter-Id attribute as IPsec CHILD_SA name
+ */
+static void process_filter_id(private_eap_radius_t *this, radius_message_t *msg)
+{
+ enumerator_t *enumerator;
+ int type;
+ u_int8_t tunnel_tag;
+ u_int32_t tunnel_type;
+ chunk_t filter_id = chunk_empty, data;
+ bool is_esp_tunnel = FALSE;
+
+ enumerator = msg->create_enumerator(msg);
+ while (enumerator->enumerate(enumerator, &type, &data))
+ {
+ switch (type)
+ {
+ case RAT_TUNNEL_TYPE:
+ if (data.len != 4)
+ {
+ continue;
+ }
+ tunnel_tag = *data.ptr;
+ *data.ptr = 0x00;
+ tunnel_type = untoh32(data.ptr);
+ DBG1(DBG_IKE, "received RADIUS attribute Tunnel-Type: "
+ "tag = %u, value = %u", tunnel_tag, tunnel_type);
+ is_esp_tunnel = (tunnel_type == TUNNEL_TYPE_ESP);
+ break;
+ case RAT_FILTER_ID:
+ filter_id = data;
+ DBG1(DBG_IKE, "received RADIUS attribute Filter-Id: "
+ "'%.*s'", filter_id.len, filter_id.ptr);
+ break;
+ default:
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (is_esp_tunnel && filter_id.len)
+ {
+ identification_t *id;
+ ike_sa_t *ike_sa;
+ auth_cfg_t *auth;
+
+ ike_sa = charon->bus->get_sa(charon->bus);
+ if (ike_sa)
+ {
+ auth = ike_sa->get_auth_cfg(ike_sa, FALSE);
+ id = identification_create_from_data(filter_id);
+ auth->add(auth, AUTH_RULE_GROUP, id);
+ }
+ }
+}
+
METHOD(eap_method_t, process, status_t,
private_eap_radius_t *this, eap_payload_t *in, eap_payload_t **out)
{
@@ -247,12 +310,17 @@ METHOD(eap_method_t, process, status_t,
{
process_class(this, response);
}
+ if (this->filter_id)
+ {
+ process_filter_id(this, response);
+ }
+ DBG1(DBG_IKE, "RADIUS authentication of '%Y' successful",
+ this->peer);
status = SUCCESS;
break;
case RMC_ACCESS_REJECT:
default:
- DBG1(DBG_CFG, "received %N from RADIUS server",
- radius_message_code_names, response->get_code(response));
+ DBG1(DBG_IKE, "RADIUS authentication of '%Y' failed", this->peer);
status = FAILED;
break;
}
@@ -313,13 +381,15 @@ eap_radius_t *eap_radius_create(identification_t *server, identification_t *peer
private_eap_radius_t *this;
INIT(this,
- .public.eap_method_interface = {
- .initiate = _initiate,
- .process = _process,
- .get_type = _get_type,
- .is_mutual = _is_mutual,
- .get_msk = _get_msk,
- .destroy = _destroy,
+ .public = {
+ .eap_method = {
+ .initiate = _initiate,
+ .process = _process,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .destroy = _destroy,
+ },
},
/* initially EAP_RADIUS, but is set to the method selected by RADIUS */
.type = EAP_RADIUS,
@@ -329,6 +399,9 @@ eap_radius_t *eap_radius_create(identification_t *server, identification_t *peer
"charon.plugins.eap-radius.id_prefix", ""),
.class_group = lib->settings->get_bool(lib->settings,
"charon.plugins.eap-radius.class_group", FALSE),
+ .filter_id = lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-radius.filter_id", FALSE),
+
);
this->client = radius_client_create();
if (!this->client)
diff --git a/src/libcharon/plugins/eap_radius/eap_radius.h b/src/libcharon/plugins/eap_radius/eap_radius.h
index 8eb9e8c2d..e98cb06e3 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius.h
+++ b/src/libcharon/plugins/eap_radius/eap_radius.h
@@ -33,7 +33,7 @@ struct eap_radius_t {
/**
* Implemented eap_method_t interface.
*/
- eap_method_t eap_method_interface;
+ eap_method_t eap_method;
};
/**
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
index 91aae2f62..1c24d77d5 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
@@ -151,7 +151,11 @@ plugin_t *eap_radius_plugin_create()
private_eap_radius_plugin_t *this;
INIT(this,
- .public.plugin.destroy = _destroy,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
.servers = linked_list_create(),
);
diff --git a/src/libcharon/plugins/eap_radius/radius_server.h b/src/libcharon/plugins/eap_radius/radius_server.h
index b820cb583..ba4c94619 100644
--- a/src/libcharon/plugins/eap_radius/radius_server.h
+++ b/src/libcharon/plugins/eap_radius/radius_server.h
@@ -79,6 +79,7 @@ struct radius_server_t {
* @param server server address
* @param port server port
* @param nas_identifier NAS-Identifier to use with this server
+ * @param secret secret to use with this server
* @param sockets number of sockets to create in pool
* @param preference preference boost for this server
*/
diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in
index d0f44e925..d05930bbd 100644
--- a/src/libcharon/plugins/eap_sim/Makefile.in
+++ b/src/libcharon/plugins/eap_sim/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -168,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in
index 2aa0ac832..46a584265 100644
--- a/src/libcharon/plugins/eap_sim_file/Makefile.in
+++ b/src/libcharon/plugins/eap_sim_file/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -169,6 +170,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -200,14 +203,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -222,24 +228,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -247,7 +260,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
index 7d80f8019..2d8556a59 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -170,6 +171,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -201,14 +204,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -223,24 +229,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -248,7 +261,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
index fc26f4497..e59015f82 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -169,6 +170,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -200,14 +203,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -222,24 +228,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -247,7 +260,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
index f2e82df0a..3c66d2f36 100644
--- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -168,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c
index 0f5319792..1cc5352d8 100644
--- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c
+++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c
@@ -85,8 +85,10 @@ plugin_t *eap_simaka_sql_plugin_create()
"charon.plugins.eap-simaka-sql.remove_used", FALSE);
INIT(this,
- .public.plugin = {
- .destroy = _destroy,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
},
.db = db,
.provider = eap_simaka_sql_provider_create(db, remove_used),
diff --git a/src/libcharon/plugins/eap_tls/Makefile.am b/src/libcharon/plugins/eap_tls/Makefile.am
new file mode 100644
index 000000000..29ddd822b
--- /dev/null
+++ b/src/libcharon/plugins/eap_tls/Makefile.am
@@ -0,0 +1,17 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-eap-tls.la
+else
+plugin_LTLIBRARIES = libstrongswan-eap-tls.la
+libstrongswan_eap_tls_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+endif
+
+libstrongswan_eap_tls_la_SOURCES = \
+ eap_tls_plugin.h eap_tls_plugin.c eap_tls.h eap_tls.c
+
+libstrongswan_eap_tls_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in
new file mode 100644
index 000000000..e4b78faf8
--- /dev/null
+++ b/src/libcharon/plugins/eap_tls/Makefile.in
@@ -0,0 +1,605 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/eap_tls
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+@MONOLITHIC_FALSE@libstrongswan_eap_tls_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la
+am_libstrongswan_eap_tls_la_OBJECTS = eap_tls_plugin.lo eap_tls.lo
+libstrongswan_eap_tls_la_OBJECTS = \
+ $(am_libstrongswan_eap_tls_la_OBJECTS)
+libstrongswan_eap_tls_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_eap_tls_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_eap_tls_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_eap_tls_la_rpath =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_eap_tls_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_eap_tls_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+default_pkcs11 = @default_pkcs11@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgid = @ipsecgid@
+ipsecgroup = @ipsecgroup@
+ipsecuid = @ipsecuid@
+ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
+libdir = @libdir@
+libexecdir = @libexecdir@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
+
+AM_CFLAGS = -rdynamic
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-tls.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-tls.la
+@MONOLITHIC_FALSE@libstrongswan_eap_tls_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+libstrongswan_eap_tls_la_SOURCES = \
+ eap_tls_plugin.h eap_tls_plugin.c eap_tls.h eap_tls.c
+
+libstrongswan_eap_tls_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/eap_tls/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/eap_tls/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-eap-tls.la: $(libstrongswan_eap_tls_la_OBJECTS) $(libstrongswan_eap_tls_la_DEPENDENCIES)
+ $(libstrongswan_eap_tls_la_LINK) $(am_libstrongswan_eap_tls_la_rpath) $(libstrongswan_eap_tls_la_OBJECTS) $(libstrongswan_eap_tls_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_tls.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_tls_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pluginLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/eap_tls/eap_tls.c b/src/libcharon/plugins/eap_tls/eap_tls.c
new file mode 100644
index 000000000..efe72c437
--- /dev/null
+++ b/src/libcharon/plugins/eap_tls/eap_tls.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "eap_tls.h"
+
+#include <tls_eap.h>
+
+#include <daemon.h>
+#include <library.h>
+
+typedef struct private_eap_tls_t private_eap_tls_t;
+
+/**
+ * Private data of an eap_tls_t object.
+ */
+struct private_eap_tls_t {
+
+ /**
+ * Public interface.
+ */
+ eap_tls_t public;
+
+ /**
+ * TLS stack, wrapped by EAP helper
+ */
+ tls_eap_t *tls_eap;
+};
+
+/** Maximum number of EAP-TLS messages/fragments allowed */
+#define MAX_MESSAGE_COUNT 32
+/** Default size of a EAP-TLS fragment */
+#define MAX_FRAGMENT_LEN 1024
+
+METHOD(eap_method_t, initiate, status_t,
+ private_eap_tls_t *this, eap_payload_t **out)
+{
+ chunk_t data;
+
+ if (this->tls_eap->initiate(this->tls_eap, &data) == NEED_MORE)
+ {
+ *out = eap_payload_create_data(data);
+ free(data.ptr);
+ return NEED_MORE;
+ }
+ return FAILED;
+}
+
+METHOD(eap_method_t, process, status_t,
+ private_eap_tls_t *this, eap_payload_t *in, eap_payload_t **out)
+{
+ status_t status;
+ chunk_t data;
+
+ data = in->get_data(in);
+ status = this->tls_eap->process(this->tls_eap, data, &data);
+ if (status == NEED_MORE)
+ {
+ *out = eap_payload_create_data(data);
+ free(data.ptr);
+ }
+ return status;
+}
+
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_tls_t *this, u_int32_t *vendor)
+{
+ *vendor = 0;
+ return EAP_TLS;
+}
+
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_tls_t *this, chunk_t *msk)
+{
+ *msk = this->tls_eap->get_msk(this->tls_eap);
+ if (msk->len)
+ {
+ return SUCCESS;
+ }
+ return FAILED;
+}
+
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_tls_t *this)
+{
+ return TRUE;
+}
+
+METHOD(eap_method_t, destroy, void,
+ private_eap_tls_t *this)
+{
+ this->tls_eap->destroy(this->tls_eap);
+ free(this);
+}
+
+/**
+ * Generic private constructor
+ */
+static eap_tls_t *eap_tls_create(identification_t *server,
+ identification_t *peer, bool is_server)
+{
+ private_eap_tls_t *this;
+ size_t frag_size;
+ int max_msg_count;
+ tls_t *tls;
+
+ INIT(this,
+ .public = {
+ .eap_method = {
+ .initiate = _initiate,
+ .process = _process,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .destroy = _destroy,
+ },
+ },
+ );
+
+ frag_size = lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-tls.fragment_size", MAX_FRAGMENT_LEN);
+ max_msg_count = lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-tls.max_message_count", MAX_MESSAGE_COUNT);
+ tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TLS, NULL);
+ this->tls_eap = tls_eap_create(EAP_TLS, tls, frag_size, max_msg_count);
+ if (!this->tls_eap)
+ {
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+eap_tls_t *eap_tls_create_server(identification_t *server,
+ identification_t *peer)
+{
+ return eap_tls_create(server, peer, TRUE);
+}
+
+eap_tls_t *eap_tls_create_peer(identification_t *server,
+ identification_t *peer)
+{
+ return eap_tls_create(server, peer, FALSE);
+}
diff --git a/src/libcharon/plugins/eap_tls/eap_tls.h b/src/libcharon/plugins/eap_tls/eap_tls.h
new file mode 100644
index 000000000..7e080230a
--- /dev/null
+++ b/src/libcharon/plugins/eap_tls/eap_tls.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup eap_tls_i eap_tls
+ * @{ @ingroup eap_tls
+ */
+
+#ifndef EAP_TLS_H_
+#define EAP_TLS_H_
+
+typedef struct eap_tls_t eap_tls_t;
+
+#include <sa/authenticators/eap/eap_method.h>
+
+/**
+ * Implementation of eap_method_t using EAP-TLS.
+ */
+struct eap_tls_t {
+
+ /**
+ * Implements eap_method_t interface.
+ */
+ eap_method_t eap_method;
+};
+
+/**
+ * Creates the EAP method EAP-TLS acting as server.
+ *
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_tls_t object
+ */
+eap_tls_t *eap_tls_create_server(identification_t *server,
+ identification_t *peer);
+
+/**
+ * Creates the EAP method EAP-TLS acting as peer.
+ *
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_tls_t object
+ */
+eap_tls_t *eap_tls_create_peer(identification_t *server,
+ identification_t *peer);
+
+#endif /** EAP_TLS_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tls/eap_tls_plugin.c b/src/libcharon/plugins/eap_tls/eap_tls_plugin.c
new file mode 100644
index 000000000..a7c040bf4
--- /dev/null
+++ b/src/libcharon/plugins/eap_tls/eap_tls_plugin.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "eap_tls_plugin.h"
+
+#include "eap_tls.h"
+
+#include <daemon.h>
+
+
+METHOD(plugin_t, destroy, void,
+ eap_tls_plugin_t *this)
+{
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_tls_create_server);
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_tls_create_peer);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *eap_tls_plugin_create()
+{
+ eap_tls_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .destroy = _destroy,
+ },
+ );
+
+ charon->eap->add_method(charon->eap, EAP_TLS, 0, EAP_SERVER,
+ (eap_constructor_t)eap_tls_create_server);
+ charon->eap->add_method(charon->eap, EAP_TLS, 0, EAP_PEER,
+ (eap_constructor_t)eap_tls_create_peer);
+
+ return &this->plugin;
+}
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.h b/src/libcharon/plugins/eap_tls/eap_tls_plugin.h
index 74c9ae24f..5ea719603 100644
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.h
+++ b/src/libcharon/plugins/eap_tls/eap_tls_plugin.h
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -14,24 +14,24 @@
*/
/**
- * @defgroup kernel_netlink kernel_netlink
+ * @defgroup eap_tls eap_tls
* @ingroup cplugins
*
- * @defgroup kernel_netlink_plugin kernel_netlink_plugin
- * @{ @ingroup kernel_netlink
+ * @defgroup eap_tls_plugin eap_tls_plugin
+ * @{ @ingroup eap_tls
*/
-#ifndef KERNEL_NETLINK_PLUGIN_H_
-#define KERNEL_NETLINK_PLUGIN_H_
+#ifndef EAP_TLS_PLUGIN_H_
+#define EAP_TLS_PLUGIN_H_
#include <plugins/plugin.h>
-typedef struct kernel_netlink_plugin_t kernel_netlink_plugin_t;
+typedef struct eap_tls_plugin_t eap_tls_plugin_t;
/**
- * netlink kernel interface plugin
+ * EAP-TLS plugin
*/
-struct kernel_netlink_plugin_t {
+struct eap_tls_plugin_t {
/**
* implements plugin interface
@@ -39,4 +39,9 @@ struct kernel_netlink_plugin_t {
plugin_t plugin;
};
-#endif /** KERNEL_NETLINK_PLUGIN_H_ @}*/
+/**
+ * Create a eap_tls_plugin instance.
+ */
+plugin_t *eap_tls_plugin_create();
+
+#endif /** EAP_TLS_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tnc/Makefile.am b/src/libcharon/plugins/eap_tnc/Makefile.am
new file mode 100644
index 000000000..9c5a445c5
--- /dev/null
+++ b/src/libcharon/plugins/eap_tnc/Makefile.am
@@ -0,0 +1,17 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-eap-tnc.la
+else
+plugin_LTLIBRARIES = libstrongswan-eap-tnc.la
+libstrongswan_eap_tnc_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+endif
+
+libstrongswan_eap_tnc_la_SOURCES = \
+ eap_tnc_plugin.h eap_tnc_plugin.c eap_tnc.h eap_tnc.c
+
+libstrongswan_eap_tnc_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in
new file mode 100644
index 000000000..fb7108a8a
--- /dev/null
+++ b/src/libcharon/plugins/eap_tnc/Makefile.in
@@ -0,0 +1,605 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/eap_tnc
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+@MONOLITHIC_FALSE@libstrongswan_eap_tnc_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la
+am_libstrongswan_eap_tnc_la_OBJECTS = eap_tnc_plugin.lo eap_tnc.lo
+libstrongswan_eap_tnc_la_OBJECTS = \
+ $(am_libstrongswan_eap_tnc_la_OBJECTS)
+libstrongswan_eap_tnc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_eap_tnc_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_eap_tnc_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_eap_tnc_la_rpath =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_eap_tnc_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_eap_tnc_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+default_pkcs11 = @default_pkcs11@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgid = @ipsecgid@
+ipsecgroup = @ipsecgroup@
+ipsecuid = @ipsecuid@
+ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
+libdir = @libdir@
+libexecdir = @libexecdir@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
+
+AM_CFLAGS = -rdynamic
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-tnc.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-tnc.la
+@MONOLITHIC_FALSE@libstrongswan_eap_tnc_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+libstrongswan_eap_tnc_la_SOURCES = \
+ eap_tnc_plugin.h eap_tnc_plugin.c eap_tnc.h eap_tnc.c
+
+libstrongswan_eap_tnc_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/eap_tnc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/eap_tnc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-eap-tnc.la: $(libstrongswan_eap_tnc_la_OBJECTS) $(libstrongswan_eap_tnc_la_DEPENDENCIES)
+ $(libstrongswan_eap_tnc_la_LINK) $(am_libstrongswan_eap_tnc_la_rpath) $(libstrongswan_eap_tnc_la_OBJECTS) $(libstrongswan_eap_tnc_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_tnc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_tnc_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pluginLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c
new file mode 100644
index 000000000..f0bff0e1f
--- /dev/null
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "eap_tnc.h"
+
+#include <tls_eap.h>
+
+#include <daemon.h>
+#include <library.h>
+
+typedef struct private_eap_tnc_t private_eap_tnc_t;
+
+/**
+ * Private data of an eap_tnc_t object.
+ */
+struct private_eap_tnc_t {
+
+ /**
+ * Public authenticator_t interface.
+ */
+ eap_tnc_t public;
+
+ /**
+ * TLS stack, wrapped by EAP helper
+ */
+ tls_eap_t *tls_eap;
+};
+
+
+/** Maximum number of EAP-TNC messages/fragments allowed */
+#define MAX_MESSAGE_COUNT 10
+/** Default size of a EAP-TNC fragment */
+#define MAX_FRAGMENT_LEN 50000
+
+METHOD(eap_method_t, initiate, status_t,
+ private_eap_tnc_t *this, eap_payload_t **out)
+{
+ chunk_t data;
+
+ if (this->tls_eap->initiate(this->tls_eap, &data) == NEED_MORE)
+ {
+ *out = eap_payload_create_data(data);
+ free(data.ptr);
+ return NEED_MORE;
+ }
+ return FAILED;
+}
+
+METHOD(eap_method_t, process, status_t,
+ private_eap_tnc_t *this, eap_payload_t *in, eap_payload_t **out)
+{
+ status_t status;
+ chunk_t data;
+
+ data = in->get_data(in);
+ status = this->tls_eap->process(this->tls_eap, data, &data);
+ if (status == NEED_MORE)
+ {
+ *out = eap_payload_create_data(data);
+ free(data.ptr);
+ }
+ return status;
+}
+
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_tnc_t *this, u_int32_t *vendor)
+{
+ *vendor = 0;
+ return EAP_TNC;
+}
+
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_tnc_t *this, chunk_t *msk)
+{
+ *msk = this->tls_eap->get_msk(this->tls_eap);
+ if (msk->len)
+ {
+ return SUCCESS;
+ }
+ return FAILED;
+}
+
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_tnc_t *this)
+{
+ return FALSE;
+}
+
+METHOD(eap_method_t, destroy, void,
+ private_eap_tnc_t *this)
+{
+ this->tls_eap->destroy(this->tls_eap);
+ free(this);
+}
+
+/**
+ * Generic private constructor
+ */
+static eap_tnc_t *eap_tnc_create(identification_t *server,
+ identification_t *peer, bool is_server)
+{
+ private_eap_tnc_t *this;
+ size_t frag_size;
+ int max_msg_count;
+ tnccs_t *tnccs;
+
+ INIT(this,
+ .public = {
+ .eap_method = {
+ .initiate = _initiate,
+ .process = _process,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .destroy = _destroy,
+ },
+ },
+ );
+
+ frag_size = lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-tnc.fragment_size", MAX_FRAGMENT_LEN);
+ max_msg_count = lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-tnc.max_message_count", MAX_MESSAGE_COUNT);
+ tnccs = charon->tnccs->create_instance(charon->tnccs, TNCCS_1_1, is_server);
+ this->tls_eap = tls_eap_create(EAP_TNC, (tls_t*)tnccs, frag_size, max_msg_count);
+ if (!this->tls_eap)
+ {
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+eap_tnc_t *eap_tnc_create_server(identification_t *server,
+ identification_t *peer)
+{
+ return eap_tnc_create(server, peer, TRUE);
+}
+
+eap_tnc_t *eap_tnc_create_peer(identification_t *server,
+ identification_t *peer)
+{
+ return eap_tnc_create(server, peer, FALSE);
+}
diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.h b/src/libcharon/plugins/eap_tnc/eap_tnc.h
new file mode 100644
index 000000000..7e166fb60
--- /dev/null
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup eap_tnc_i eap_tnc
+ * @{ @ingroup eap_tnc
+ */
+
+#ifndef EAP_TNC_H_
+#define EAP_TNC_H_
+
+typedef struct eap_tnc_t eap_tnc_t;
+
+#include <sa/authenticators/eap/eap_method.h>
+
+/**
+ * Implementation of the eap_method_t interface using EAP-TNC.
+ */
+struct eap_tnc_t {
+
+ /**
+ * Implemented eap_method_t interface.
+ */
+ eap_method_t eap_method;
+};
+
+/**
+ * Creates the EAP method EAP-TNC acting as server.
+ *
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_tnc_t object
+ */
+eap_tnc_t *eap_tnc_create_server(identification_t *server, identification_t *peer);
+
+/**
+ * Creates the EAP method EAP-TNC acting as peer.
+ *
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_tnc_t object
+ */
+eap_tnc_t *eap_tnc_create_peer(identification_t *server, identification_t *peer);
+
+#endif /** EAP_TNC_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c
new file mode 100644
index 000000000..7430e4cac
--- /dev/null
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "eap_tnc_plugin.h"
+#include "eap_tnc.h"
+
+#include <daemon.h>
+
+METHOD(plugin_t, destroy, void,
+ eap_tnc_plugin_t *this)
+{
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_tnc_create_server);
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_tnc_create_peer);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *eap_tnc_plugin_create()
+{
+ eap_tnc_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .destroy = _destroy,
+ },
+ );
+
+ charon->eap->add_method(charon->eap, EAP_TNC, 0, EAP_SERVER,
+ (eap_constructor_t)eap_tnc_create_server);
+ charon->eap->add_method(charon->eap, EAP_TNC, 0, EAP_PEER,
+ (eap_constructor_t)eap_tnc_create_peer);
+
+ return &this->plugin;
+}
+
diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.h b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.h
index ecccc6303..97298eb5c 100644
--- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.h
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2010 Andreas Steffen
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -14,24 +14,24 @@
*/
/**
- * @defgroup kernel_pfkey kernel_pfkey
+ * @defgroup eap_tnc eap_tnc
* @ingroup cplugins
*
- * @defgroup kernel_pfkey_plugin kernel_pfkey_plugin
- * @{ @ingroup kernel_pfkey
+ * @defgroup eap_tnc_plugin eap_tnc_plugin
+ * @{ @ingroup eap_tnc
*/
-#ifndef KERNEL_PFKEY_PLUGIN_H_
-#define KERNEL_PFKEY_PLUGIN_H_
+#ifndef EAP_TNC_PLUGIN_H_
+#define EAP_TNC_PLUGIN_H_
#include <plugins/plugin.h>
-typedef struct kernel_pfkey_plugin_t kernel_pfkey_plugin_t;
+typedef struct eap_tnc_plugin_t eap_tnc_plugin_t;
/**
- * PF_KEY kernel interface plugin
+ * EAP-TNC plugin
*/
-struct kernel_pfkey_plugin_t {
+struct eap_tnc_plugin_t {
/**
* implements plugin interface
@@ -39,4 +39,4 @@ struct kernel_pfkey_plugin_t {
plugin_t plugin;
};
-#endif /** KERNEL_PFKEY_PLUGIN_H_ @}*/
+#endif /** EAP_TNC_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/eap_ttls/Makefile.am b/src/libcharon/plugins/eap_ttls/Makefile.am
new file mode 100644
index 000000000..94ce5cc1e
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/Makefile.am
@@ -0,0 +1,21 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-eap-ttls.la
+else
+plugin_LTLIBRARIES = libstrongswan-eap-ttls.la
+libstrongswan_eap_ttls_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+endif
+
+libstrongswan_eap_ttls_la_SOURCES = \
+ eap_ttls_plugin.h eap_ttls_plugin.c \
+ eap_ttls_avp.h eap_ttls_avp.c \
+ eap_ttls.h eap_ttls.c \
+ eap_ttls_peer.h eap_ttls_peer.c \
+ eap_ttls_server.h eap_ttls_server.c
+
+libstrongswan_eap_ttls_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in
new file mode 100644
index 000000000..2cdd7701d
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/Makefile.in
@@ -0,0 +1,615 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/eap_ttls
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+@MONOLITHIC_FALSE@libstrongswan_eap_ttls_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la
+am_libstrongswan_eap_ttls_la_OBJECTS = eap_ttls_plugin.lo \
+ eap_ttls_avp.lo eap_ttls.lo eap_ttls_peer.lo \
+ eap_ttls_server.lo
+libstrongswan_eap_ttls_la_OBJECTS = \
+ $(am_libstrongswan_eap_ttls_la_OBJECTS)
+libstrongswan_eap_ttls_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_eap_ttls_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_eap_ttls_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_eap_ttls_la_rpath =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_eap_ttls_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_eap_ttls_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+default_pkcs11 = @default_pkcs11@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgid = @ipsecgid@
+ipsecgroup = @ipsecgroup@
+ipsecuid = @ipsecuid@
+ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
+libdir = @libdir@
+libexecdir = @libexecdir@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
+
+AM_CFLAGS = -rdynamic
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-ttls.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-ttls.la
+@MONOLITHIC_FALSE@libstrongswan_eap_ttls_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+libstrongswan_eap_ttls_la_SOURCES = \
+ eap_ttls_plugin.h eap_ttls_plugin.c \
+ eap_ttls_avp.h eap_ttls_avp.c \
+ eap_ttls.h eap_ttls.c \
+ eap_ttls_peer.h eap_ttls_peer.c \
+ eap_ttls_server.h eap_ttls_server.c
+
+libstrongswan_eap_ttls_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/eap_ttls/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/eap_ttls/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-eap-ttls.la: $(libstrongswan_eap_ttls_la_OBJECTS) $(libstrongswan_eap_ttls_la_DEPENDENCIES)
+ $(libstrongswan_eap_ttls_la_LINK) $(am_libstrongswan_eap_ttls_la_rpath) $(libstrongswan_eap_ttls_la_OBJECTS) $(libstrongswan_eap_ttls_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_ttls.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_ttls_avp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_ttls_peer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_ttls_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_ttls_server.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pluginLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.c b/src/libcharon/plugins/eap_ttls/eap_ttls.c
new file mode 100644
index 000000000..a62af6ea4
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2010 Martin Willi, revosec AG
+ * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "eap_ttls.h"
+#include "eap_ttls_peer.h"
+#include "eap_ttls_server.h"
+
+#include <tls_eap.h>
+
+#include <daemon.h>
+#include <library.h>
+
+typedef struct private_eap_ttls_t private_eap_ttls_t;
+
+/**
+ * Private data of an eap_ttls_t object.
+ */
+struct private_eap_ttls_t {
+
+ /**
+ * Public interface.
+ */
+ eap_ttls_t public;
+
+ /**
+ * TLS stack, wrapped by EAP helper
+ */
+ tls_eap_t *tls_eap;
+};
+
+/** Maximum number of EAP-TTLS messages/fragments allowed */
+#define MAX_MESSAGE_COUNT 32
+/** Default size of a EAP-TTLS fragment */
+#define MAX_FRAGMENT_LEN 1024
+
+METHOD(eap_method_t, initiate, status_t,
+ private_eap_ttls_t *this, eap_payload_t **out)
+{
+ chunk_t data;
+
+ if (this->tls_eap->initiate(this->tls_eap, &data) == NEED_MORE)
+ {
+ *out = eap_payload_create_data(data);
+ free(data.ptr);
+ return NEED_MORE;
+ }
+ return FAILED;
+}
+
+METHOD(eap_method_t, process, status_t,
+ private_eap_ttls_t *this, eap_payload_t *in, eap_payload_t **out)
+{
+ status_t status;
+ chunk_t data;
+
+ data = in->get_data(in);
+ status = this->tls_eap->process(this->tls_eap, data, &data);
+ if (status == NEED_MORE)
+ {
+ *out = eap_payload_create_data(data);
+ free(data.ptr);
+ }
+ return status;
+}
+
+METHOD(eap_method_t, get_type, eap_type_t,
+ private_eap_ttls_t *this, u_int32_t *vendor)
+{
+ *vendor = 0;
+ return EAP_TTLS;
+}
+
+METHOD(eap_method_t, get_msk, status_t,
+ private_eap_ttls_t *this, chunk_t *msk)
+{
+ *msk = this->tls_eap->get_msk(this->tls_eap);
+ if (msk->len)
+ {
+ return SUCCESS;
+ }
+ return FAILED;
+}
+
+METHOD(eap_method_t, is_mutual, bool,
+ private_eap_ttls_t *this)
+{
+ return TRUE;
+}
+
+METHOD(eap_method_t, destroy, void,
+ private_eap_ttls_t *this)
+{
+ this->tls_eap->destroy(this->tls_eap);
+ free(this);
+}
+
+/**
+ * Generic private constructor
+ */
+static eap_ttls_t *eap_ttls_create(identification_t *server,
+ identification_t *peer, bool is_server,
+ tls_application_t *application)
+{
+ private_eap_ttls_t *this;
+ size_t frag_size;
+ int max_msg_count;
+ tls_t *tls;
+
+ INIT(this,
+ .public = {
+ .eap_method = {
+ .initiate = _initiate,
+ .process = _process,
+ .get_type = _get_type,
+ .is_mutual = _is_mutual,
+ .get_msk = _get_msk,
+ .destroy = _destroy,
+ },
+ },
+ );
+ if (is_server && !lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-ttls.request_peer_auth", FALSE))
+ {
+ peer = NULL;
+ }
+ frag_size = lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-ttls.fragment_size", MAX_FRAGMENT_LEN);
+ max_msg_count = lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-ttls.max_message_count", MAX_MESSAGE_COUNT);
+ tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TTLS, application);
+ this->tls_eap = tls_eap_create(EAP_TTLS, tls, frag_size, max_msg_count);
+ if (!this->tls_eap)
+ {
+ application->destroy(application);
+ free(this);
+ return NULL;
+ }
+ return &this->public;
+}
+
+eap_ttls_t *eap_ttls_create_server(identification_t *server,
+ identification_t *peer)
+{
+ return eap_ttls_create(server, peer, TRUE,
+ &eap_ttls_server_create(server, peer)->application);
+}
+
+eap_ttls_t *eap_ttls_create_peer(identification_t *server,
+ identification_t *peer)
+{
+ return eap_ttls_create(server, peer, FALSE,
+ &eap_ttls_peer_create(server, peer)->application);
+}
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.h b/src/libcharon/plugins/eap_ttls/eap_ttls.h
new file mode 100644
index 000000000..6e3bf2ceb
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup eap_ttls_i eap_ttls
+ * @{ @ingroup eap_ttls
+ */
+
+#ifndef EAP_TTLS_H_
+#define EAP_TTLS_H_
+
+typedef struct eap_ttls_t eap_ttls_t;
+
+#include <sa/authenticators/eap/eap_method.h>
+
+/**
+ * Implementation of eap_method_t using EAP-TTLS.
+ */
+struct eap_ttls_t {
+
+ /**
+ * Implements eap_method_t interface.
+ */
+ eap_method_t eap_method;
+};
+
+/**
+ * Creates the EAP method EAP-TTLS acting as server.
+ *
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_ttls_t object
+ */
+eap_ttls_t *eap_ttls_create_server(identification_t *server,
+ identification_t *peer);
+
+/**
+ * Creates the EAP method EAP-TTLS acting as peer.
+ *
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_ttls_t object
+ */
+eap_ttls_t *eap_ttls_create_peer(identification_t *server,
+ identification_t *peer);
+
+#endif /** EAP_TTLS_H_ @}*/
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c
new file mode 100644
index 000000000..0eb5e94be
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "eap_ttls_avp.h"
+
+#include <debug.h>
+
+#define AVP_EAP_MESSAGE 79
+#define AVP_HEADER_LEN 8
+
+typedef struct private_eap_ttls_avp_t private_eap_ttls_avp_t;
+
+/**
+ * Private data of an eap_ttls_avp_t object.
+ */
+struct private_eap_ttls_avp_t {
+
+ /**
+ * Public eap_ttls_avp_t interface.
+ */
+ eap_ttls_avp_t public;
+
+ /**
+ * AVP input buffer
+ */
+ chunk_t input;
+
+ /**
+ * Position in input buffer
+ */
+ size_t inpos;
+
+ /**
+ * process header (TRUE) or body (FALSE)
+ */
+ bool process_header;
+
+ /**
+ * Size of AVP data
+ */
+ size_t data_len;
+};
+
+METHOD(eap_ttls_avp_t, build, void,
+ private_eap_ttls_avp_t *this, tls_writer_t *writer, chunk_t data)
+{
+ char zero_padding[] = { 0x00, 0x00, 0x00 };
+ chunk_t avp_padding;
+ u_int8_t avp_flags;
+ u_int32_t avp_len;
+
+ avp_flags = 0x40;
+ avp_len = 8 + data.len;
+ avp_padding = chunk_create(zero_padding, (4 - data.len) % 4);
+
+ writer->write_uint32(writer, AVP_EAP_MESSAGE);
+ writer->write_uint8(writer, avp_flags);
+ writer->write_uint24(writer, avp_len);
+ writer->write_data(writer, data);
+ writer->write_data(writer, avp_padding);
+}
+
+METHOD(eap_ttls_avp_t, process, status_t,
+ private_eap_ttls_avp_t* this, tls_reader_t *reader, chunk_t *data)
+{
+ size_t len;
+ chunk_t buf;
+
+ if (this->process_header)
+ {
+ tls_reader_t *header;
+ u_int32_t avp_code;
+ u_int8_t avp_flags;
+ u_int32_t avp_len;
+ bool success;
+
+ len = min(reader->remaining(reader), AVP_HEADER_LEN - this->inpos);
+ if (!reader->read_data(reader, len, &buf))
+ {
+ return FAILED;
+ }
+ if (this->input.len == 0)
+ {
+ /* start of a new AVP header */
+ this->input = chunk_alloc(AVP_HEADER_LEN);
+ memcpy(this->input.ptr, buf.ptr, len);
+ this->inpos = len;
+ }
+ else
+ {
+ memcpy(this->input.ptr + this->inpos, buf.ptr, len);
+ this->inpos += len;
+ }
+
+ if (this->inpos < AVP_HEADER_LEN)
+ {
+ return NEED_MORE;
+ }
+
+ /* parse AVP header */
+ header = tls_reader_create(this->input);
+ success = header->read_uint32(header, &avp_code) &&
+ header->read_uint8(header, &avp_flags) &&
+ header->read_uint24(header, &avp_len);
+ header->destroy(header);
+ chunk_free(&this->input);
+ this->inpos = 0;
+
+ if (!success)
+ {
+ DBG1(DBG_IKE, "received invalid AVP header");
+ return FAILED;
+ }
+ if (avp_code != AVP_EAP_MESSAGE)
+ {
+ DBG1(DBG_IKE, "expected AVP_EAP_MESSAGE but received %u", avp_code);
+ return FAILED;
+ }
+ this->process_header = FALSE;
+ this->data_len = avp_len - 8;
+ this->input = chunk_alloc(this->data_len + (4 - avp_len) % 4);
+ }
+
+ /* process AVP data */
+ len = min(reader->remaining(reader), this->input.len - this->inpos);
+ if (!reader->read_data(reader, len, &buf))
+ {
+ return FAILED;
+ }
+ memcpy(this->input.ptr + this->inpos, buf.ptr, len);
+ this->inpos += len;
+ if (this->inpos < this->input.len)
+ {
+ return NEED_MORE;
+ }
+
+ *data = this->input;
+ data->len = this->data_len;
+
+ /* preparing for next AVP */
+ this->input = chunk_empty;
+ this->inpos = 0;
+ this->process_header = TRUE;
+
+ return SUCCESS;
+}
+
+METHOD(eap_ttls_avp_t, destroy, void,
+ private_eap_ttls_avp_t *this)
+{
+ chunk_free(&this->input);
+ free(this);
+}
+
+/**
+ * See header
+ */
+eap_ttls_avp_t *eap_ttls_avp_create(void)
+{
+ private_eap_ttls_avp_t *this;
+
+ INIT(this,
+ .public= {
+ .process = _process,
+ .build = _build,
+ .destroy = _destroy,
+ },
+ .input = chunk_empty,
+ .inpos = 0,
+ .process_header = TRUE,
+ .data_len = 0,
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h
new file mode 100644
index 000000000..cad1d9c56
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup eap_ttls_avp eap_ttls_avp
+ * @{ @ingroup eap_ttls
+ */
+
+#ifndef EAP_TTLS_AVP_H_
+#define EAP_TTLS_AVP_H_
+
+typedef struct eap_ttls_avp_t eap_ttls_avp_t;
+
+#include <library.h>
+
+#include <tls_reader.h>
+#include <tls_writer.h>
+
+/**
+ * EAP-TTLS Attribute-Value Pair (AVP) handler.
+ */
+struct eap_ttls_avp_t {
+
+ /**
+ * Process received EAP-TTLS EAP Message AVP.
+ *
+ * @param reader TLS data buffer
+ * @param data received EAP Message
+ * @return
+ * - SUCCESS if AVP processing succeeded
+ * - FAILED if AVP processing failed
+ * - NEED_MORE if another invocation of process/build needed
+ */
+ status_t (*process)(eap_ttls_avp_t *this, tls_reader_t *reader,
+ chunk_t *data);
+
+ /**
+ * Build EAP-TTLS EAP Message AVP to send out.
+ *
+ * @param writer TLS data buffer to write to
+ * @param data EAP Message to send
+ */
+ void (*build)(eap_ttls_avp_t *this, tls_writer_t *writer, chunk_t data);
+
+ /**
+ * Destroy a eap_ttls_application_t.
+ */
+ void (*destroy)(eap_ttls_avp_t *this);
+};
+
+/**
+ * Create an eap_ttls_avp instance.
+ */
+eap_ttls_avp_t *eap_ttls_avp_create(void);
+
+#endif /** EAP_TTLS_AVP_H_ @}*/
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
new file mode 100644
index 000000000..10d08ca2a
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "eap_ttls_peer.h"
+#include "eap_ttls_avp.h"
+
+#include <debug.h>
+#include <daemon.h>
+
+#include <sa/authenticators/eap/eap_method.h>
+
+typedef struct private_eap_ttls_peer_t private_eap_ttls_peer_t;
+
+/**
+ * Private data of an eap_ttls_peer_t object.
+ */
+struct private_eap_ttls_peer_t {
+
+ /**
+ * Public eap_ttls_peer_t interface.
+ */
+ eap_ttls_peer_t public;
+
+ /**
+ * Server identity
+ */
+ identification_t *server;
+
+ /**
+ * Peer identity
+ */
+ identification_t *peer;
+
+ /**
+ * Current EAP-TTLS state
+ */
+ bool start_phase2;
+
+ /**
+ * Current phase 2 EAP method
+ */
+ eap_method_t *method;
+
+ /**
+ * Pending outbound EAP message
+ */
+ eap_payload_t *out;
+
+ /**
+ * AVP handler
+ */
+ eap_ttls_avp_t *avp;
+};
+
+/**
+ * EAP packet format
+ */
+typedef struct __attribute__((packed)) {
+ u_int8_t code;
+ u_int8_t identifier;
+ u_int16_t length;
+ u_int8_t type;
+ u_int8_t data;
+} eap_packet_t;
+
+#define MAX_RADIUS_ATTRIBUTE_SIZE 253
+
+METHOD(tls_application_t, process, status_t,
+ private_eap_ttls_peer_t *this, tls_reader_t *reader)
+{
+ chunk_t avp_data = chunk_empty;
+ chunk_t eap_data = chunk_empty;
+ status_t status;
+ payload_t *payload;
+ eap_payload_t *in;
+ eap_packet_t *pkt;
+ eap_code_t code;
+ eap_type_t type, received_type;
+ u_int32_t vendor, received_vendor;
+ u_int16_t eap_len;
+ size_t eap_pos = 0;
+ bool concatenated = FALSE;
+
+ do
+ {
+ status = this->avp->process(this->avp, reader, &avp_data);
+ switch (status)
+ {
+ case SUCCESS:
+ break;
+ case NEED_MORE:
+ DBG1(DBG_IKE, "need more AVP data");
+ return NEED_MORE;
+ case FAILED:
+ default:
+ return FAILED;
+ }
+
+ if (eap_data.len == 0)
+ {
+ if (avp_data.len < 4)
+ {
+ DBG1(DBG_IKE, "AVP size to small to contain EAP header");
+ chunk_free(&avp_data);
+ return FAILED;
+ }
+ pkt = (eap_packet_t*)avp_data.ptr;
+ eap_len = untoh16(&pkt->length);
+
+ if (eap_len <= avp_data.len)
+ {
+ /* standard: EAP packet contained in a single AVP */
+ eap_data = avp_data;
+ break;
+ }
+ else if (avp_data.len == MAX_RADIUS_ATTRIBUTE_SIZE)
+ {
+ /* non-standard: EAP packet segmented into multiple AVPs */
+ eap_data = chunk_alloc(eap_len);
+ concatenated = TRUE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "non-radius segmentation of EAP packet into AVPs");
+ chunk_free(&avp_data);
+ return FAILED;
+ }
+ }
+
+ if (avp_data.len > eap_data.len - eap_pos)
+ {
+ DBG1(DBG_IKE, "AVP size to large to fit into EAP packet");
+ chunk_free(&avp_data);
+ chunk_free(&eap_data);
+ return FAILED;
+ }
+ memcpy(eap_data.ptr + eap_pos, avp_data.ptr, avp_data.len);
+ eap_pos += avp_data.len;
+ chunk_free(&avp_data);
+ }
+ while (eap_pos < eap_data.len);
+
+ in = eap_payload_create_data(eap_data);
+ chunk_free(&eap_data);
+ payload = (payload_t*)in;
+
+ if (payload->verify(payload) != SUCCESS)
+ {
+ in->destroy(in);
+ return FAILED;
+ }
+ code = in->get_code(in);
+ received_type = in->get_type(in, &received_vendor);
+ DBG1(DBG_IKE, "received tunneled EAP-TTLS AVP%s [EAP/%N/%N]",
+ concatenated ? "s" : "",
+ eap_code_short_names, code,
+ eap_type_short_names, received_type);
+ if (code != EAP_REQUEST)
+ {
+ DBG1(DBG_IKE, "%N expected", eap_code_names, EAP_REQUEST);
+ in->destroy(in);
+ return FAILED;
+ }
+
+ if (this->method == NULL)
+ {
+ if (received_vendor)
+ {
+ DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d",
+ received_type, received_vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "server requested %N authentication",
+ eap_type_names, received_type);
+ }
+ this->method = charon->eap->create_instance(charon->eap,
+ received_type, received_vendor,
+ EAP_PEER, this->server, this->peer);
+ if (!this->method)
+ {
+ DBG1(DBG_IKE, "EAP method not supported");
+ this->out = eap_payload_create_nak(in->get_identifier(in));
+ in->destroy(in);
+ return NEED_MORE;
+ }
+ }
+
+ type = this->method->get_type(this->method, &vendor);
+
+ if (type != received_type || vendor != received_vendor)
+ {
+ DBG1(DBG_IKE, "received invalid EAP request");
+ in->destroy(in);
+ return FAILED;
+ }
+
+ status = this->method->process(this->method, in, &this->out);
+ in->destroy(in);
+
+ switch (status)
+ {
+ case SUCCESS:
+ this->method->destroy(this->method);
+ this->method = NULL;
+ return NEED_MORE;
+ case NEED_MORE:
+ if (type != EAP_TNC)
+ {
+ this->method->destroy(this->method);
+ this->method = NULL;
+ }
+ return NEED_MORE;
+ case FAILED:
+ default:
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
+ }
+ return FAILED;
+ }
+}
+
+METHOD(tls_application_t, build, status_t,
+ private_eap_ttls_peer_t *this, tls_writer_t *writer)
+{
+ chunk_t data;
+ eap_code_t code;
+ eap_type_t type;
+ u_int32_t vendor;
+
+ if (this->method == NULL && this->start_phase2)
+ {
+ /* generate an EAP Identity response */
+ this->method = charon->eap->create_instance(charon->eap, EAP_IDENTITY,
+ 0, EAP_PEER, this->server, this->peer);
+ if (this->method == NULL)
+ {
+ DBG1(DBG_IKE, "EAP_IDENTITY method not available");
+ return FAILED;
+ }
+ this->method->process(this->method, NULL, &this->out);
+ this->method->destroy(this->method);
+ this->method = NULL;
+ this->start_phase2 = FALSE;
+ }
+
+ if (this->out)
+ {
+ code = this->out->get_code(this->out);
+ type = this->out->get_type(this->out, &vendor);
+ DBG1(DBG_IKE, "sending tunneled EAP-TTLS AVP [EAP/%N/%N]",
+ eap_code_short_names, code, eap_type_short_names, type);
+
+ /* get the raw EAP message data */
+ data = this->out->get_data(this->out);
+ this->avp->build(this->avp, writer, data);
+
+ this->out->destroy(this->out);
+ this->out = NULL;
+ }
+ return INVALID_STATE;
+}
+
+METHOD(tls_application_t, destroy, void,
+ private_eap_ttls_peer_t *this)
+{
+ this->server->destroy(this->server);
+ this->peer->destroy(this->peer);
+ DESTROY_IF(this->method);
+ DESTROY_IF(this->out);
+ this->avp->destroy(this->avp);
+ free(this);
+}
+
+/**
+ * See header
+ */
+eap_ttls_peer_t *eap_ttls_peer_create(identification_t *server,
+ identification_t *peer)
+{
+ private_eap_ttls_peer_t *this;
+
+ INIT(this,
+ .public = {
+ .application = {
+ .process = _process,
+ .build = _build,
+ .destroy = _destroy,
+ },
+ },
+ .server = server->clone(server),
+ .peer = peer->clone(peer),
+ .start_phase2 = TRUE,
+ .avp = eap_ttls_avp_create(),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.h b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.h
new file mode 100644
index 000000000..31fc0d9db
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup eap_ttls_peer eap_ttls_peer
+ * @{ @ingroup eap_ttls
+ */
+
+#ifndef EAP_TTLS_PEER_H_
+#define EAP_TTLS_PEER_H_
+
+typedef struct eap_ttls_peer_t eap_ttls_peer_t;
+
+#include "tls_application.h"
+
+#include <library.h>
+
+/**
+ * TLS application data handler as peer.
+ */
+struct eap_ttls_peer_t {
+
+ /**
+ * Implements the TLS application data handler.
+ */
+ tls_application_t application;
+};
+
+/**
+ * Create an eap_ttls_peer instance.
+ */
+eap_ttls_peer_t *eap_ttls_peer_create(identification_t *server,
+ identification_t *peer);
+
+#endif /** EAP_TTLS_PEER_H_ @}*/
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c
new file mode 100644
index 000000000..48e759dcc
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "eap_ttls_plugin.h"
+
+#include "eap_ttls.h"
+
+#include <daemon.h>
+
+
+METHOD(plugin_t, destroy, void,
+ eap_ttls_plugin_t *this)
+{
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_ttls_create_server);
+ charon->eap->remove_method(charon->eap,
+ (eap_constructor_t)eap_ttls_create_peer);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *eap_ttls_plugin_create()
+{
+ eap_ttls_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .destroy = _destroy,
+ },
+ );
+
+ charon->eap->add_method(charon->eap, EAP_TTLS, 0, EAP_SERVER,
+ (eap_constructor_t)eap_ttls_create_server);
+ charon->eap->add_method(charon->eap, EAP_TTLS, 0, EAP_PEER,
+ (eap_constructor_t)eap_ttls_create_peer);
+
+ return &this->plugin;
+}
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.h b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.h
new file mode 100644
index 000000000..2abc82931
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup eap_ttls eap_ttls
+ * @ingroup cplugins
+ *
+ * @defgroup eap_ttls_plugin eap_ttls_plugin
+ * @{ @ingroup eap_ttls
+ */
+
+#ifndef EAP_TTLS_PLUGIN_H_
+#define EAP_TTLS_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct eap_ttls_plugin_t eap_ttls_plugin_t;
+
+/**
+ * EAP-TTLS plugin
+ */
+struct eap_ttls_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+/**
+ * Create a eap_ttls_plugin instance.
+ */
+plugin_t *eap_ttls_plugin_create();
+
+#endif /** EAP_TTLS_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_server.c b/src/libcharon/plugins/eap_ttls/eap_ttls_server.c
new file mode 100644
index 000000000..835cd7306
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_server.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "eap_ttls_server.h"
+#include "eap_ttls_avp.h"
+
+#include <debug.h>
+#include <daemon.h>
+
+#include <sa/authenticators/eap/eap_method.h>
+
+typedef struct private_eap_ttls_server_t private_eap_ttls_server_t;
+
+/**
+ * Private data of an eap_ttls_server_t object.
+ */
+struct private_eap_ttls_server_t {
+
+ /**
+ * Public eap_ttls_server_t interface.
+ */
+ eap_ttls_server_t public;
+
+ /**
+ * Server identity
+ */
+ identification_t *server;
+
+ /**
+ * Peer identity
+ */
+ identification_t *peer;
+
+ /**
+ * Current EAP-TTLS phase2 state
+ */
+ bool start_phase2;
+
+ /**
+ * Current EAP-TTLS phase2 TNC state
+ */
+ bool start_phase2_tnc;
+
+ /**
+ * Current phase 2 EAP method
+ */
+ eap_method_t *method;
+
+ /**
+ * Pending outbound EAP message
+ */
+ eap_payload_t *out;
+
+ /**
+ * AVP handler
+ */
+ eap_ttls_avp_t *avp;
+};
+
+/**
+ * Start EAP client authentication protocol
+ */
+static status_t start_phase2_auth(private_eap_ttls_server_t *this)
+{
+ char *eap_type_str;
+ eap_type_t type;
+
+ eap_type_str = lib->settings->get_str(lib->settings,
+ "charon.plugins.eap-ttls.phase2_method", "md5");
+ type = eap_type_from_string(eap_type_str);
+ if (type == 0)
+ {
+ DBG1(DBG_IKE, "unrecognized phase2 method \"%s\"", eap_type_str);
+ return FAILED;
+ }
+ DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, type);
+ this->method = charon->eap->create_instance(charon->eap, type, 0,
+ EAP_SERVER, this->server, this->peer);
+ if (this->method == NULL)
+ {
+ DBG1(DBG_IKE, "%N method not available", eap_type_names, type);
+ return FAILED;
+ }
+ if (this->method->initiate(this->method, &this->out) == NEED_MORE)
+ {
+ return NEED_MORE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
+ return FAILED;
+ }
+}
+
+/**
+ * If configured, start EAP-TNC protocol
+ */
+static status_t start_phase2_tnc(private_eap_ttls_server_t *this)
+{
+ if (this->start_phase2_tnc && lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-ttls.phase2_tnc", FALSE))
+ {
+ DBG1(DBG_IKE, "phase2 method %N selected", eap_type_names, EAP_TNC);
+ this->method = charon->eap->create_instance(charon->eap, EAP_TNC,
+ 0, EAP_SERVER, this->server, this->peer);
+ if (this->method == NULL)
+ {
+ DBG1(DBG_IKE, "%N method not available", eap_type_names, EAP_TNC);
+ return FAILED;
+ }
+ this->start_phase2_tnc = FALSE;
+ if (this->method->initiate(this->method, &this->out) == NEED_MORE)
+ {
+ return NEED_MORE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "%N method failed", eap_type_names, EAP_TNC);
+ return FAILED;
+ }
+ }
+ return SUCCESS;
+}
+
+METHOD(tls_application_t, process, status_t,
+ private_eap_ttls_server_t *this, tls_reader_t *reader)
+{
+ chunk_t data = chunk_empty;
+ status_t status;
+ payload_t *payload;
+ eap_payload_t *in;
+ eap_code_t code;
+ eap_type_t type = EAP_NAK, received_type;
+ u_int32_t vendor, received_vendor;
+
+ status = this->avp->process(this->avp, reader, &data);
+ switch (status)
+ {
+ case SUCCESS:
+ break;
+ case NEED_MORE:
+ return NEED_MORE;
+ case FAILED:
+ default:
+ return FAILED;
+ }
+ in = eap_payload_create_data(data);
+ chunk_free(&data);
+ payload = (payload_t*)in;
+
+ if (payload->verify(payload) != SUCCESS)
+ {
+ in->destroy(in);
+ return FAILED;
+ }
+ code = in->get_code(in);
+ received_type = in->get_type(in, &received_vendor);
+ DBG1(DBG_IKE, "received tunneled EAP-TTLS AVP [EAP/%N/%N]",
+ eap_code_short_names, code,
+ eap_type_short_names, received_type);
+ if (code != EAP_RESPONSE)
+ {
+ DBG1(DBG_IKE, "%N expected", eap_code_names, EAP_RESPONSE);
+ in->destroy(in);
+ return FAILED;
+ }
+
+ if (this->method)
+ {
+ type = this->method->get_type(this->method, &vendor);
+
+ if (type != received_type || vendor != received_vendor)
+ {
+ if (received_vendor == 0 && received_type == EAP_NAK)
+ {
+ DBG1(DBG_IKE, "peer does not support %N", eap_type_names, type);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received invalid EAP response");
+ }
+ in->destroy(in);
+ return FAILED;
+ }
+ }
+
+ if (!received_vendor && received_type == EAP_IDENTITY)
+ {
+ chunk_t eap_id;
+
+ if (this->method == NULL)
+ {
+ /* Received an EAP Identity response without a matching request */
+ this->method = charon->eap->create_instance(charon->eap,
+ EAP_IDENTITY, 0, EAP_SERVER,
+ this->server, this->peer);
+ if (this->method == NULL)
+ {
+ DBG1(DBG_IKE, "%N method not available",
+ eap_type_names, EAP_IDENTITY);
+ return FAILED;
+ }
+ }
+
+ if (this->method->process(this->method, in, &this->out) != SUCCESS)
+ {
+
+ DBG1(DBG_IKE, "%N method failed", eap_type_names, EAP_IDENTITY);
+ return FAILED;
+ }
+
+ if (this->method->get_msk(this->method, &eap_id) == SUCCESS)
+ {
+ this->peer->destroy(this->peer);
+ this->peer = identification_create_from_data(eap_id);
+ DBG1(DBG_IKE, "received EAP identity '%Y'", this->peer);
+ }
+
+ in->destroy(in);
+ this->method->destroy(this->method);
+ this->method = NULL;
+
+ /* Start Phase 2 of EAP-TTLS authentication */
+ if (lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-ttls.request_peer_auth", FALSE))
+ {
+ return start_phase2_tnc(this);
+ }
+ else
+ {
+ return start_phase2_auth(this);
+ }
+ }
+
+ if (this->method == 0)
+ {
+ DBG1(DBG_IKE, "no %N phase2 method installed", eap_type_names, EAP_TTLS);
+ in->destroy(in);
+ return FAILED;
+ }
+
+ status = this->method->process(this->method, in, &this->out);
+ in->destroy(in);
+
+ switch (status)
+ {
+ case SUCCESS:
+ DBG1(DBG_IKE, "%N phase2 authentication of '%Y' with %N successful",
+ eap_type_names, EAP_TTLS, this->peer,
+ eap_type_names, type);
+ this->method->destroy(this->method);
+ this->method = NULL;
+
+ /* continue phase2 with EAP-TNC? */
+ return start_phase2_tnc(this);
+ case NEED_MORE:
+ break;
+ case FAILED:
+ default:
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
+ }
+ return FAILED;
+ }
+ return status;
+}
+
+METHOD(tls_application_t, build, status_t,
+ private_eap_ttls_server_t *this, tls_writer_t *writer)
+{
+ chunk_t data;
+ eap_code_t code;
+ eap_type_t type;
+ u_int32_t vendor;
+
+ if (this->method == NULL && this->start_phase2 &&
+ lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-ttls.phase2_piggyback", FALSE))
+ {
+ /* generate an EAP Identity request which will be piggybacked right
+ * onto the TLS Finished message thus initiating EAP-TTLS phase2
+ */
+ this->method = charon->eap->create_instance(charon->eap, EAP_IDENTITY,
+ 0, EAP_SERVER, this->server, this->peer);
+ if (this->method == NULL)
+ {
+ DBG1(DBG_IKE, "%N method not available",
+ eap_type_names, EAP_IDENTITY);
+ return FAILED;
+ }
+ this->method->initiate(this->method, &this->out);
+ this->start_phase2 = FALSE;
+ }
+
+ if (this->out)
+ {
+ code = this->out->get_code(this->out);
+ type = this->out->get_type(this->out, &vendor);
+ DBG1(DBG_IKE, "sending tunneled EAP-TTLS AVP [EAP/%N/%N]",
+ eap_code_short_names, code, eap_type_short_names, type);
+
+ /* get the raw EAP message data */
+ data = this->out->get_data(this->out);
+ this->avp->build(this->avp, writer, data);
+
+ this->out->destroy(this->out);
+ this->out = NULL;
+ }
+ return INVALID_STATE;
+}
+
+METHOD(tls_application_t, destroy, void,
+ private_eap_ttls_server_t *this)
+{
+ this->server->destroy(this->server);
+ this->peer->destroy(this->peer);
+ DESTROY_IF(this->method);
+ DESTROY_IF(this->out);
+ this->avp->destroy(this->avp);
+ free(this);
+}
+
+/**
+ * See header
+ */
+eap_ttls_server_t *eap_ttls_server_create(identification_t *server,
+ identification_t *peer)
+{
+ private_eap_ttls_server_t *this;
+
+ INIT(this,
+ .public = {
+ .application = {
+ .process = _process,
+ .build = _build,
+ .destroy = _destroy,
+ },
+ },
+ .server = server->clone(server),
+ .peer = peer->clone(peer),
+ .start_phase2 = TRUE,
+ .start_phase2_tnc = TRUE,
+ .avp = eap_ttls_avp_create(),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_server.h b/src/libcharon/plugins/eap_ttls/eap_ttls_server.h
new file mode 100644
index 000000000..a66a813ec
--- /dev/null
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_server.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010 HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup eap_ttls_server eap_ttls_server
+ * @{ @ingroup eap_ttls
+ */
+
+#ifndef EAP_TTLS_SERVER_H_
+#define EAP_TTLS_SERVER_H_
+
+typedef struct eap_ttls_server_t eap_ttls_server_t;
+
+#include "tls_application.h"
+
+#include <library.h>
+
+/**
+ * TLS application data handler as server.
+ */
+struct eap_ttls_server_t {
+
+ /**
+ * Implements the TLS application data handler.
+ */
+ tls_application_t application;
+};
+
+/**
+ * Create an eap_ttls_server instance.
+ */
+eap_ttls_server_t *eap_ttls_server_create(identification_t *server,
+ identification_t *peer);
+
+#endif /** EAP_TTLS_SERVER_H_ @}*/
diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in
index 47952b99e..bfd50d6da 100644
--- a/src/libcharon/plugins/farp/Makefile.in
+++ b/src/libcharon/plugins/farp/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -165,6 +166,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -196,14 +199,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -218,24 +224,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -243,7 +256,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/farp/farp_plugin.c b/src/libcharon/plugins/farp/farp_plugin.c
index 01c2a39c8..d83bc1fd2 100644
--- a/src/libcharon/plugins/farp/farp_plugin.c
+++ b/src/libcharon/plugins/farp/farp_plugin.c
@@ -60,7 +60,11 @@ plugin_t *farp_plugin_create()
private_farp_plugin_t *this;
INIT(this,
- .public.plugin.destroy = _destroy,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
.listener = farp_listener_create(),
);
diff --git a/src/libcharon/plugins/farp/farp_spoofer.c b/src/libcharon/plugins/farp/farp_spoofer.c
index 20bb44fd3..a904a6538 100644
--- a/src/libcharon/plugins/farp/farp_spoofer.c
+++ b/src/libcharon/plugins/farp/farp_spoofer.c
@@ -191,7 +191,7 @@ farp_spoofer_t *farp_spoofer_create(farp_listener_t *listener)
this->job = callback_job_create((callback_job_cb_t)receive_arp,
this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
}
diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in
index 5ca9b464b..3600eb7c6 100644
--- a/src/libcharon/plugins/ha/Makefile.in
+++ b/src/libcharon/plugins/ha/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -167,6 +168,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -198,14 +201,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -220,24 +226,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -245,7 +258,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/ha/ha_cache.c b/src/libcharon/plugins/ha/ha_cache.c
index 1ebc33ca4..9ff3fd5ff 100644
--- a/src/libcharon/plugins/ha/ha_cache.c
+++ b/src/libcharon/plugins/ha/ha_cache.c
@@ -354,7 +354,7 @@ ha_cache_t *ha_cache_create(ha_kernel_t *kernel, ha_socket_t *socket,
if (sync)
{
/* request a resync as soon as we are up */
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)
+ lib->scheduler->schedule_job(lib->scheduler, (job_t*)
callback_job_create((callback_job_cb_t)request_resync,
this, NULL, NULL), 1);
}
diff --git a/src/libcharon/plugins/ha/ha_ctl.c b/src/libcharon/plugins/ha/ha_ctl.c
index e188a8484..980c0551a 100644
--- a/src/libcharon/plugins/ha/ha_ctl.c
+++ b/src/libcharon/plugins/ha/ha_ctl.c
@@ -114,6 +114,7 @@ METHOD(ha_ctl_t, destroy, void,
ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache)
{
private_ha_ctl_t *this;
+ mode_t old;
INIT(this,
.public = {
@@ -125,16 +126,23 @@ ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache)
if (access(HA_FIFO, R_OK|W_OK) != 0)
{
- if (mkfifo(HA_FIFO, 600) != 0)
+ old = umask(~(S_IRWXU | S_IRWXG));
+ if (mkfifo(HA_FIFO, S_IRUSR | S_IWUSR) != 0)
{
DBG1(DBG_CFG, "creating HA FIFO %s failed: %s",
HA_FIFO, strerror(errno));
}
+ umask(old);
+ }
+ if (chown(HA_FIFO, charon->uid, charon->gid) != 0)
+ {
+ DBG1(DBG_CFG, "changing HA FIFO permissions failed: %s",
+ strerror(errno));
}
this->job = callback_job_create((callback_job_cb_t)dispatch_fifo,
this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
}
diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c
index 3bc426ea0..b46a221bd 100644
--- a/src/libcharon/plugins/ha/ha_dispatcher.c
+++ b/src/libcharon/plugins/ha/ha_dispatcher.c
@@ -136,7 +136,7 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
diffie_hellman_t dh = { .get_shared_secret = get_shared_secret,
.destroy = (void*)&secret };
- proposal = proposal_create(PROTO_IKE);
+ proposal = proposal_create(PROTO_IKE, 0);
keymat = ike_sa->get_keymat(ike_sa);
if (integ)
{
@@ -549,7 +549,7 @@ static void process_child_add(private_ha_dispatcher_t *this,
child_sa->set_protocol(child_sa, PROTO_ESP);
child_sa->set_ipcomp(child_sa, ipcomp);
- proposal = proposal_create(PROTO_ESP);
+ proposal = proposal_create(PROTO_ESP, 0);
if (integ)
{
proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM, integ, 0);
@@ -869,7 +869,7 @@ ha_dispatcher_t *ha_dispatcher_create(ha_socket_t *socket,
);
this->job = callback_job_create((callback_job_cb_t)dispatch,
this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
}
diff --git a/src/libcharon/plugins/ha/ha_kernel.c b/src/libcharon/plugins/ha/ha_kernel.c
index 10a63453a..56bdbf454 100644
--- a/src/libcharon/plugins/ha/ha_kernel.c
+++ b/src/libcharon/plugins/ha/ha_kernel.c
@@ -216,6 +216,11 @@ static void disable_all(private_ha_kernel_t *this)
enumerator = enumerator_create_directory(CLUSTERIP_DIR);
while (enumerator->enumerate(enumerator, NULL, &file, NULL))
{
+ if (chown(file, charon->uid, charon->gid) != 0)
+ {
+ DBG1(DBG_CFG, "changing ClusterIP permissions failed: %s",
+ strerror(errno));
+ }
active = get_active(this, file);
for (i = 1; i <= this->count; i++)
{
diff --git a/src/libcharon/plugins/ha/ha_plugin.c b/src/libcharon/plugins/ha/ha_plugin.c
index e722b4f3a..581294e60 100644
--- a/src/libcharon/plugins/ha/ha_plugin.c
+++ b/src/libcharon/plugins/ha/ha_plugin.c
@@ -142,7 +142,11 @@ plugin_t *ha_plugin_create()
}
INIT(this,
- .public.plugin.destroy = _destroy,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
);
if (secret)
diff --git a/src/libcharon/plugins/ha/ha_segments.c b/src/libcharon/plugins/ha/ha_segments.c
index be2d7e428..19e0f692e 100644
--- a/src/libcharon/plugins/ha/ha_segments.c
+++ b/src/libcharon/plugins/ha/ha_segments.c
@@ -283,7 +283,7 @@ static void start_watchdog(private_ha_segments_t *this)
{
this->job = callback_job_create((callback_job_cb_t)watchdog,
this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
}
METHOD(ha_segments_t, handle_status, void,
@@ -345,7 +345,7 @@ static job_requeue_t send_status(private_ha_segments_t *this)
message->destroy(message);
/* schedule next invocation */
- charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*)
+ lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)
callback_job_create((callback_job_cb_t)
send_status, this, NULL, NULL),
this->heartbeat_delay);
@@ -382,7 +382,9 @@ ha_segments_t *ha_segments_create(ha_socket_t *socket, ha_kernel_t *kernel,
INIT(this,
.public = {
- .listener.alert = _alert_hook,
+ .listener = {
+ .alert = _alert_hook,
+ },
.activate = _activate,
.deactivate = _deactivate,
.handle_status = _handle_status,
diff --git a/src/libcharon/plugins/ha/ha_socket.c b/src/libcharon/plugins/ha/ha_socket.c
index 21e6eb6d5..614c70ed3 100644
--- a/src/libcharon/plugins/ha/ha_socket.c
+++ b/src/libcharon/plugins/ha/ha_socket.c
@@ -107,7 +107,7 @@ METHOD(ha_socket_t, push, void,
job = callback_job_create((callback_job_cb_t)send_message,
data, (void*)job_data_destroy, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)job);
+ lib->processor->queue_job(lib->processor, (job_t*)job);
return;
}
DBG1(DBG_CFG, "pushing HA message failed: %s", strerror(errno));
diff --git a/src/libcharon/plugins/kernel_klips/Makefile.am b/src/libcharon/plugins/kernel_klips/Makefile.am
deleted file mode 100644
index 540bbe106..000000000
--- a/src/libcharon/plugins/kernel_klips/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
-
-AM_CFLAGS = -rdynamic
-
-if MONOLITHIC
-noinst_LTLIBRARIES = libstrongswan-kernel-klips.la
-else
-plugin_LTLIBRARIES = libstrongswan-kernel-klips.la
-endif
-
-libstrongswan_kernel_klips_la_SOURCES = \
- kernel_klips_plugin.h kernel_klips_plugin.c \
- kernel_klips_ipsec.h kernel_klips_ipsec.c pfkeyv2.h
-
-libstrongswan_kernel_klips_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c b/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c
deleted file mode 100644
index 6b5aeb342..000000000
--- a/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.c
+++ /dev/null
@@ -1,2660 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <stdint.h>
-#include "pfkeyv2.h"
-#include <linux/udp.h>
-#include <net/if.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-
-#include "kernel_klips_ipsec.h"
-
-#include <daemon.h>
-#include <threading/thread.h>
-#include <threading/mutex.h>
-#include <processing/jobs/callback_job.h>
-#include <processing/jobs/acquire_job.h>
-#include <processing/jobs/rekey_child_sa_job.h>
-#include <processing/jobs/delete_child_sa_job.h>
-#include <processing/jobs/update_sa_job.h>
-
-/** default timeout for generated SPIs (in seconds) */
-#define SPI_TIMEOUT 30
-
-/** buffer size for PF_KEY messages */
-#define PFKEY_BUFFER_SIZE 2048
-
-/** PF_KEY messages are 64 bit aligned */
-#define PFKEY_ALIGNMENT 8
-/** aligns len to 64 bits */
-#define PFKEY_ALIGN(len) (((len) + PFKEY_ALIGNMENT - 1) & ~(PFKEY_ALIGNMENT - 1))
-/** calculates the properly padded length in 64 bit chunks */
-#define PFKEY_LEN(len) ((PFKEY_ALIGN(len) / PFKEY_ALIGNMENT))
-/** calculates user mode length i.e. in bytes */
-#define PFKEY_USER_LEN(len) ((len) * PFKEY_ALIGNMENT)
-
-/** given a PF_KEY message header and an extension this updates the length in the header */
-#define PFKEY_EXT_ADD(msg, ext) ((msg)->sadb_msg_len += ((struct sadb_ext*)ext)->sadb_ext_len)
-/** given a PF_KEY message header this returns a pointer to the next extension */
-#define PFKEY_EXT_ADD_NEXT(msg) ((struct sadb_ext*)(((char*)(msg)) + PFKEY_USER_LEN((msg)->sadb_msg_len)))
-/** copy an extension and append it to a PF_KEY message */
-#define PFKEY_EXT_COPY(msg, ext) (PFKEY_EXT_ADD(msg, memcpy(PFKEY_EXT_ADD_NEXT(msg), ext, PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len))))
-/** given a PF_KEY extension this returns a pointer to the next extension */
-#define PFKEY_EXT_NEXT(ext) ((struct sadb_ext*)(((char*)(ext)) + PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len)))
-/** given a PF_KEY extension this returns a pointer to the next extension also updates len (len in 64 bit words) */
-#define PFKEY_EXT_NEXT_LEN(ext,len) ((len) -= (ext)->sadb_ext_len, PFKEY_EXT_NEXT(ext))
-/** true if ext has a valid length and len is large enough to contain ext (assuming len in 64 bit words) */
-#define PFKEY_EXT_OK(ext,len) ((len) >= PFKEY_LEN(sizeof(struct sadb_ext)) && \
- (ext)->sadb_ext_len >= PFKEY_LEN(sizeof(struct sadb_ext)) && \
- (ext)->sadb_ext_len <= (len))
-
-/** special SPI values used for policies in KLIPS */
-#define SPI_PASS 256
-#define SPI_DROP 257
-#define SPI_REJECT 258
-#define SPI_HOLD 259
-#define SPI_TRAP 260
-#define SPI_TRAPSUBNET 261
-
-/** the prefix of the name of KLIPS ipsec devices */
-#define IPSEC_DEV_PREFIX "ipsec"
-/** this is the default number of ipsec devices */
-#define DEFAULT_IPSEC_DEV_COUNT 4
-/** TRUE if the given name matches an ipsec device */
-#define IS_IPSEC_DEV(name) (strneq((name), IPSEC_DEV_PREFIX, sizeof(IPSEC_DEV_PREFIX) - 1))
-
-/** the following stuff is from ipsec_tunnel.h */
-struct ipsectunnelconf
-{
- __u32 cf_cmd;
- union
- {
- char cfu_name[12];
- } cf_u;
-#define cf_name cf_u.cfu_name
-};
-
-#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
-#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
-#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
-
-typedef struct private_kernel_klips_ipsec_t private_kernel_klips_ipsec_t;
-
-/**
- * Private variables and functions of kernel_klips class.
- */
-struct private_kernel_klips_ipsec_t
-{
- /**
- * Public part of the kernel_klips_t object.
- */
- kernel_klips_ipsec_t public;
-
- /**
- * mutex to lock access to various lists
- */
- mutex_t *mutex;
-
- /**
- * List of installed policies (policy_entry_t)
- */
- linked_list_t *policies;
-
- /**
- * List of allocated SPIs without installed SA (sa_entry_t)
- */
- linked_list_t *allocated_spis;
-
- /**
- * List of installed SAs (sa_entry_t)
- */
- linked_list_t *installed_sas;
-
- /**
- * whether to install routes along policies
- */
- bool install_routes;
-
- /**
- * List of ipsec devices (ipsec_dev_t)
- */
- linked_list_t *ipsec_devices;
-
- /**
- * job receiving PF_KEY events
- */
- callback_job_t *job;
-
- /**
- * mutex to lock access to the PF_KEY socket
- */
- mutex_t *mutex_pfkey;
-
- /**
- * PF_KEY socket to communicate with the kernel
- */
- int socket;
-
- /**
- * PF_KEY socket to receive acquire and expire events
- */
- int socket_events;
-
- /**
- * sequence number for messages sent to the kernel
- */
- int seq;
-
-};
-
-
-typedef struct ipsec_dev_t ipsec_dev_t;
-
-/**
- * ipsec device
- */
-struct ipsec_dev_t {
- /** name of the virtual ipsec interface */
- char name[IFNAMSIZ];
-
- /** name of the physical interface */
- char phys_name[IFNAMSIZ];
-
- /** by how many CHILD_SA's this ipsec device is used */
- u_int refcount;
-};
-
-/**
- * compare the given name with the virtual device name
- */
-static inline bool ipsec_dev_match_byname(ipsec_dev_t *current, char *name)
-{
- return name && streq(current->name, name);
-}
-
-/**
- * compare the given name with the physical device name
- */
-static inline bool ipsec_dev_match_byphys(ipsec_dev_t *current, char *name)
-{
- return name && streq(current->phys_name, name);
-}
-
-/**
- * matches free ipsec devices
- */
-static inline bool ipsec_dev_match_free(ipsec_dev_t *current)
-{
- return current->refcount == 0;
-}
-
-/**
- * tries to find an ipsec_dev_t object by name
- */
-static status_t find_ipsec_dev(private_kernel_klips_ipsec_t *this, char *name,
- ipsec_dev_t **dev)
-{
- linked_list_match_t match = (linked_list_match_t)(IS_IPSEC_DEV(name) ?
- ipsec_dev_match_byname : ipsec_dev_match_byphys);
- return this->ipsec_devices->find_first(this->ipsec_devices, match,
- (void**)dev, name);
-}
-
-/**
- * attach an ipsec device to a physical interface
- */
-static status_t attach_ipsec_dev(char* name, char *phys_name)
-{
- int sock;
- struct ifreq req;
- struct ipsectunnelconf *itc = (struct ipsectunnelconf*)&req.ifr_data;
- short phys_flags;
- int mtu;
-
- DBG2(DBG_KNL, "attaching virtual interface %s to %s", name, phys_name);
-
- if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) <= 0)
- {
- return FAILED;
- }
-
- strncpy(req.ifr_name, phys_name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req) < 0)
- {
- close(sock);
- return FAILED;
- }
- phys_flags = req.ifr_flags;
-
- strncpy(req.ifr_name, name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req) < 0)
- {
- close(sock);
- return FAILED;
- }
-
- if (req.ifr_flags & IFF_UP)
- {
- /* if it's already up, it is already attached, detach it first */
- ioctl(sock, IPSEC_DEL_DEV, &req);
- }
-
- /* attach it */
- strncpy(req.ifr_name, name, IFNAMSIZ);
- strncpy(itc->cf_name, phys_name, sizeof(itc->cf_name));
- ioctl(sock, IPSEC_SET_DEV, &req);
-
- /* copy address from physical to virtual */
- strncpy(req.ifr_name, phys_name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFADDR, &req) == 0)
- {
- strncpy(req.ifr_name, name, IFNAMSIZ);
- ioctl(sock, SIOCSIFADDR, &req);
- }
-
- /* copy net mask from physical to virtual */
- strncpy(req.ifr_name, phys_name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFNETMASK, &req) == 0)
- {
- strncpy(req.ifr_name, name, IFNAMSIZ);
- ioctl(sock, SIOCSIFNETMASK, &req);
- }
-
- /* copy other flags and addresses */
- strncpy(req.ifr_name, name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req) == 0)
- {
- if (phys_flags & IFF_POINTOPOINT)
- {
- req.ifr_flags |= IFF_POINTOPOINT;
- req.ifr_flags &= ~IFF_BROADCAST;
- ioctl(sock, SIOCSIFFLAGS, &req);
-
- strncpy(req.ifr_name, phys_name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFDSTADDR, &req) == 0)
- {
- strncpy(req.ifr_name, name, IFNAMSIZ);
- ioctl(sock, SIOCSIFDSTADDR, &req);
- }
- }
- else if (phys_flags & IFF_BROADCAST)
- {
- req.ifr_flags &= ~IFF_POINTOPOINT;
- req.ifr_flags |= IFF_BROADCAST;
- ioctl(sock, SIOCSIFFLAGS, &req);
-
- strncpy(req.ifr_name, phys_name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFBRDADDR, &req)==0)
- {
- strncpy(req.ifr_name, name, IFNAMSIZ);
- ioctl(sock, SIOCSIFBRDADDR, &req);
- }
- }
- else
- {
- req.ifr_flags &= ~IFF_POINTOPOINT;
- req.ifr_flags &= ~IFF_BROADCAST;
- ioctl(sock, SIOCSIFFLAGS, &req);
- }
- }
-
- mtu = lib->settings->get_int(lib->settings,
- "charon.plugins.kernel-klips.ipsec_dev_mtu", 0);
- if (mtu <= 0)
- {
- /* guess MTU as physical MTU - ESP overhead [- NAT-T overhead]
- * ESP overhead : 73 bytes
- * NAT-T overhead : 8 bytes ==> 81 bytes
- *
- * assuming tunnel mode with AES encryption and integrity
- * outer IP header : 20 bytes
- * (NAT-T UDP header: 8 bytes)
- * ESP header : 8 bytes
- * IV : 16 bytes
- * padding : 15 bytes (worst-case)
- * pad len / NH : 2 bytes
- * auth data : 12 bytes
- */
- strncpy(req.ifr_name, phys_name, IFNAMSIZ);
- ioctl(sock, SIOCGIFMTU, &req);
- mtu = req.ifr_mtu - 81;
- }
-
- /* set MTU */
- strncpy(req.ifr_name, name, IFNAMSIZ);
- req.ifr_mtu = mtu;
- ioctl(sock, SIOCSIFMTU, &req);
-
- /* bring ipsec device UP */
- if (ioctl(sock, SIOCGIFFLAGS, &req) == 0)
- {
- req.ifr_flags |= IFF_UP;
- ioctl(sock, SIOCSIFFLAGS, &req);
- }
-
- close(sock);
- return SUCCESS;
-}
-
-/**
- * detach an ipsec device from a physical interface
- */
-static status_t detach_ipsec_dev(char* name, char *phys_name)
-{
- int sock;
- struct ifreq req;
-
- DBG2(DBG_KNL, "detaching virtual interface %s from %s", name,
- strlen(phys_name) ? phys_name : "any physical interface");
-
- if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) <= 0)
- {
- return FAILED;
- }
-
- strncpy(req.ifr_name, name, IFNAMSIZ);
- if (ioctl(sock, SIOCGIFFLAGS, &req) < 0)
- {
- close(sock);
- return FAILED;
- }
-
- /* shutting interface down */
- if (req.ifr_flags & IFF_UP)
- {
- req.ifr_flags &= ~IFF_UP;
- ioctl(sock, SIOCSIFFLAGS, &req);
- }
-
- /* unset address */
- memset(&req.ifr_addr, 0, sizeof(req.ifr_addr));
- req.ifr_addr.sa_family = AF_INET;
- ioctl(sock, SIOCSIFADDR, &req);
-
- /* detach interface */
- ioctl(sock, IPSEC_DEL_DEV, &req);
-
- close(sock);
- return SUCCESS;
-}
-
-/**
- * destroy an ipsec_dev_t object
- */
-static void ipsec_dev_destroy(ipsec_dev_t *this)
-{
- detach_ipsec_dev(this->name, this->phys_name);
- free(this);
-}
-
-
-typedef struct route_entry_t route_entry_t;
-
-/**
- * installed routing entry
- */
-struct route_entry_t {
- /** Name of the interface the route is bound to */
- char *if_name;
-
- /** Source ip of the route */
- host_t *src_ip;
-
- /** Gateway for this route */
- host_t *gateway;
-
- /** Destination net */
- chunk_t dst_net;
-
- /** Destination net prefixlen */
- u_int8_t prefixlen;
-};
-
-/**
- * destroy an route_entry_t object
- */
-static void route_entry_destroy(route_entry_t *this)
-{
- free(this->if_name);
- this->src_ip->destroy(this->src_ip);
- this->gateway->destroy(this->gateway);
- chunk_free(&this->dst_net);
- free(this);
-}
-
-typedef struct policy_entry_t policy_entry_t;
-
-/**
- * installed kernel policy.
- */
-struct policy_entry_t {
-
- /** reqid of this policy, if setup as trap */
- u_int32_t reqid;
-
- /** direction of this policy: in, out, forward */
- u_int8_t direction;
-
- /** parameters of installed policy */
- struct {
- /** subnet and port */
- host_t *net;
- /** subnet mask */
- u_int8_t mask;
- /** protocol */
- u_int8_t proto;
- } src, dst;
-
- /** associated route installed for this policy */
- route_entry_t *route;
-
- /** by how many CHILD_SA's this policy is actively used */
- u_int activecount;
-
- /** by how many CHILD_SA's this policy is trapped */
- u_int trapcount;
-};
-
-/**
- * convert a numerical netmask to a host_t
- */
-static host_t *mask2host(int family, u_int8_t mask)
-{
- static const u_char bitmask[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
- chunk_t chunk = chunk_alloca(family == AF_INET ? 4 : 16);
- int bytes = mask / 8, bits = mask % 8;
- memset(chunk.ptr, 0xFF, bytes);
- memset(chunk.ptr + bytes, 0, chunk.len - bytes);
- if (bits)
- {
- chunk.ptr[bytes] = bitmask[bits];
- }
- return host_create_from_chunk(family, chunk, 0);
-}
-
-/**
- * check if a host is in a subnet (host with netmask in bits)
- */
-static bool is_host_in_net(host_t *host, host_t *net, u_int8_t mask)
-{
- static const u_char bitmask[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
- chunk_t host_chunk, net_chunk;
- int bytes = mask / 8, bits = mask % 8;
-
- host_chunk = host->get_address(host);
- net_chunk = net->get_address(net);
-
- if (host_chunk.len != net_chunk.len)
- {
- return FALSE;
- }
-
- if (memeq(host_chunk.ptr, net_chunk.ptr, bytes))
- {
- return (bits == 0) ||
- (host_chunk.ptr[bytes] & bitmask[bits]) ==
- (net_chunk.ptr[bytes] & bitmask[bits]);
- }
-
- return FALSE;
-}
-
-/**
- * create a policy_entry_t object
- */
-static policy_entry_t *create_policy_entry(traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t dir)
-{
- policy_entry_t *policy = malloc_thing(policy_entry_t);
- policy->reqid = 0;
- policy->direction = dir;
- policy->route = NULL;
- policy->activecount = 0;
- policy->trapcount = 0;
-
- src_ts->to_subnet(src_ts, &policy->src.net, &policy->src.mask);
- dst_ts->to_subnet(dst_ts, &policy->dst.net, &policy->dst.mask);
-
- /* src or dest proto may be "any" (0), use more restrictive one */
- policy->src.proto = max(src_ts->get_protocol(src_ts), dst_ts->get_protocol(dst_ts));
- policy->src.proto = policy->src.proto ? policy->src.proto : 0;
- policy->dst.proto = policy->src.proto;
-
- return policy;
-}
-
-/**
- * destroy a policy_entry_t object
- */
-static void policy_entry_destroy(policy_entry_t *this)
-{
- DESTROY_IF(this->src.net);
- DESTROY_IF(this->dst.net);
- if (this->route)
- {
- route_entry_destroy(this->route);
- }
- free(this);
-}
-
-/**
- * compares two policy_entry_t
- */
-static inline bool policy_entry_equals(policy_entry_t *current, policy_entry_t *policy)
-{
- return current->direction == policy->direction &&
- current->src.proto == policy->src.proto &&
- current->dst.proto == policy->dst.proto &&
- current->src.mask == policy->src.mask &&
- current->dst.mask == policy->dst.mask &&
- current->src.net->equals(current->src.net, policy->src.net) &&
- current->dst.net->equals(current->dst.net, policy->dst.net);
-}
-
-static inline bool policy_entry_match_byaddrs(policy_entry_t *current, host_t *src,
- host_t *dst)
-{
- return is_host_in_net(src, current->src.net, current->src.mask) &&
- is_host_in_net(dst, current->dst.net, current->dst.mask);
-}
-
-typedef struct sa_entry_t sa_entry_t;
-
-/**
- * used for two things:
- * - allocated SPIs that have not yet resulted in an installed SA
- * - installed inbound SAs with enabled UDP encapsulation
- */
-struct sa_entry_t {
-
- /** protocol of this SA */
- protocol_id_t protocol;
-
- /** reqid of this SA */
- u_int32_t reqid;
-
- /** SPI of this SA */
- u_int32_t spi;
-
- /** src address of this SA */
- host_t *src;
-
- /** dst address of this SA */
- host_t *dst;
-
- /** TRUE if this SA uses UDP encapsulation */
- bool encap;
-
- /** TRUE if this SA is inbound */
- bool inbound;
-};
-
-/**
- * create an sa_entry_t object
- */
-static sa_entry_t *create_sa_entry(protocol_id_t protocol, u_int32_t spi,
- u_int32_t reqid, host_t *src, host_t *dst,
- bool encap, bool inbound)
-{
- sa_entry_t *sa = malloc_thing(sa_entry_t);
- sa->protocol = protocol;
- sa->reqid = reqid;
- sa->spi = spi;
- sa->src = src ? src->clone(src) : NULL;
- sa->dst = dst ? dst->clone(dst) : NULL;
- sa->encap = encap;
- sa->inbound = inbound;
- return sa;
-}
-
-/**
- * destroy an sa_entry_t object
- */
-static void sa_entry_destroy(sa_entry_t *this)
-{
- DESTROY_IF(this->src);
- DESTROY_IF(this->dst);
- free(this);
-}
-
-/**
- * match an sa_entry_t for an inbound SA that uses UDP encapsulation by spi and src (remote) address
- */
-static inline bool sa_entry_match_encapbysrc(sa_entry_t *current, u_int32_t *spi,
- host_t *src)
-{
- return current->encap && current->inbound &&
- current->spi == *spi && src->ip_equals(src, current->src);
-}
-
-/**
- * match an sa_entry_t by protocol, spi and dst address (as the kernel does it)
- */
-static inline bool sa_entry_match_bydst(sa_entry_t *current, protocol_id_t *protocol,
- u_int32_t *spi, host_t *dst)
-{
- return current->protocol == *protocol && current->spi == *spi && dst->ip_equals(dst, current->dst);
-}
-
-/**
- * match an sa_entry_t by protocol, reqid and spi
- */
-static inline bool sa_entry_match_byid(sa_entry_t *current, protocol_id_t *protocol,
- u_int32_t *spi, u_int32_t *reqid)
-{
- return current->protocol == *protocol && current->spi == *spi && current->reqid == *reqid;
-}
-
-typedef struct pfkey_msg_t pfkey_msg_t;
-
-struct pfkey_msg_t
-{
- /**
- * PF_KEY message base
- */
- struct sadb_msg *msg;
-
-
- /**
- * PF_KEY message extensions
- */
- union {
- struct sadb_ext *ext[SADB_EXT_MAX + 1];
- struct {
- struct sadb_ext *reserved; /* SADB_EXT_RESERVED */
- struct sadb_sa *sa; /* SADB_EXT_SA */
- struct sadb_lifetime *lft_current; /* SADB_EXT_LIFETIME_CURRENT */
- struct sadb_lifetime *lft_hard; /* SADB_EXT_LIFETIME_HARD */
- struct sadb_lifetime *lft_soft; /* SADB_EXT_LIFETIME_SOFT */
- struct sadb_address *src; /* SADB_EXT_ADDRESS_SRC */
- struct sadb_address *dst; /* SADB_EXT_ADDRESS_DST */
- struct sadb_address *proxy; /* SADB_EXT_ADDRESS_PROXY */
- struct sadb_key *key_auth; /* SADB_EXT_KEY_AUTH */
- struct sadb_key *key_encr; /* SADB_EXT_KEY_ENCRYPT */
- struct sadb_ident *id_src; /* SADB_EXT_IDENTITY_SRC */
- struct sadb_ident *id_dst; /* SADB_EXT_IDENTITY_DST */
- struct sadb_sens *sensitivity; /* SADB_EXT_SENSITIVITY */
- struct sadb_prop *proposal; /* SADB_EXT_PROPOSAL */
- struct sadb_supported *supported_auth; /* SADB_EXT_SUPPORTED_AUTH */
- struct sadb_supported *supported_encr; /* SADB_EXT_SUPPORTED_ENCRYPT */
- struct sadb_spirange *spirange; /* SADB_EXT_SPIRANGE */
- struct sadb_x_kmprivate *x_kmprivate; /* SADB_X_EXT_KMPRIVATE */
- struct sadb_ext *x_policy; /* SADB_X_EXT_SATYPE2 */
- struct sadb_ext *x_sa2; /* SADB_X_EXT_SA2 */
- struct sadb_address *x_dst2; /* SADB_X_EXT_ADDRESS_DST2 */
- struct sadb_address *x_src_flow; /* SADB_X_EXT_ADDRESS_SRC_FLOW */
- struct sadb_address *x_dst_flow; /* SADB_X_EXT_ADDRESS_DST_FLOW */
- struct sadb_address *x_src_mask; /* SADB_X_EXT_ADDRESS_SRC_MASK */
- struct sadb_address *x_dst_mask; /* SADB_X_EXT_ADDRESS_DST_MASK */
- struct sadb_x_debug *x_debug; /* SADB_X_EXT_DEBUG */
- struct sadb_protocol *x_protocol; /* SADB_X_EXT_PROTOCOL */
- struct sadb_x_nat_t_type *x_natt_type; /* SADB_X_EXT_NAT_T_TYPE */
- struct sadb_x_nat_t_port *x_natt_sport; /* SADB_X_EXT_NAT_T_SPORT */
- struct sadb_x_nat_t_port *x_natt_dport; /* SADB_X_EXT_NAT_T_DPORT */
- struct sadb_address *x_natt_oa; /* SADB_X_EXT_NAT_T_OA */
- } __attribute__((__packed__));
- };
-};
-
-/**
- * convert a IKEv2 specific protocol identifier to the PF_KEY sa type
- */
-static u_int8_t proto_ike2satype(protocol_id_t proto)
-{
- switch (proto)
- {
- case PROTO_ESP:
- return SADB_SATYPE_ESP;
- case PROTO_AH:
- return SADB_SATYPE_AH;
- case IPPROTO_COMP:
- return SADB_X_SATYPE_COMP;
- default:
- return proto;
- }
-}
-
-/**
- * convert a PF_KEY sa type to a IKEv2 specific protocol identifier
- */
-static protocol_id_t proto_satype2ike(u_int8_t proto)
-{
- switch (proto)
- {
- case SADB_SATYPE_ESP:
- return PROTO_ESP;
- case SADB_SATYPE_AH:
- return PROTO_AH;
- case SADB_X_SATYPE_COMP:
- return IPPROTO_COMP;
- default:
- return proto;
- }
-}
-
-typedef struct kernel_algorithm_t kernel_algorithm_t;
-
-/**
- * Mapping of IKEv2 algorithms to PF_KEY algorithms
- */
-struct kernel_algorithm_t {
- /**
- * Identifier specified in IKEv2
- */
- int ikev2;
-
- /**
- * Identifier as defined in pfkeyv2.h
- */
- int kernel;
-};
-
-#define END_OF_LIST -1
-
-/**
- * Algorithms for encryption
- */
-static kernel_algorithm_t encryption_algs[] = {
-/* {ENCR_DES_IV64, 0 }, */
- {ENCR_DES, SADB_EALG_DESCBC },
- {ENCR_3DES, SADB_EALG_3DESCBC },
-/* {ENCR_RC5, 0 }, */
-/* {ENCR_IDEA, 0 }, */
-/* {ENCR_CAST, 0 }, */
- {ENCR_BLOWFISH, SADB_EALG_BFCBC },
-/* {ENCR_3IDEA, 0 }, */
-/* {ENCR_DES_IV32, 0 }, */
- {ENCR_NULL, SADB_EALG_NULL },
- {ENCR_AES_CBC, SADB_EALG_AESCBC },
-/* {ENCR_AES_CTR, 0 }, */
-/* {ENCR_AES_CCM_ICV8, 0 }, */
-/* {ENCR_AES_CCM_ICV12, 0 }, */
-/* {ENCR_AES_CCM_ICV16, 0 }, */
-/* {ENCR_AES_GCM_ICV8, 0 }, */
-/* {ENCR_AES_GCM_ICV12, 0 }, */
-/* {ENCR_AES_GCM_ICV16, 0 }, */
- {END_OF_LIST, 0 },
-};
-
-/**
- * Algorithms for integrity protection
- */
-static kernel_algorithm_t integrity_algs[] = {
- {AUTH_HMAC_MD5_96, SADB_AALG_MD5HMAC },
- {AUTH_HMAC_SHA1_96, SADB_AALG_SHA1HMAC },
- {AUTH_HMAC_SHA2_256_128, SADB_AALG_SHA256_HMAC },
- {AUTH_HMAC_SHA2_384_192, SADB_AALG_SHA384_HMAC },
- {AUTH_HMAC_SHA2_512_256, SADB_AALG_SHA512_HMAC },
-/* {AUTH_DES_MAC, 0, }, */
-/* {AUTH_KPDK_MD5, 0, }, */
-/* {AUTH_AES_XCBC_96, 0, }, */
- {END_OF_LIST, 0, },
-};
-
-#if 0
-/**
- * Algorithms for IPComp, unused yet
- */
-static kernel_algorithm_t compression_algs[] = {
-/* {IPCOMP_OUI, 0 }, */
- {IPCOMP_DEFLATE, SADB_X_CALG_DEFLATE },
- {IPCOMP_LZS, SADB_X_CALG_LZS },
-/* {IPCOMP_LZJH, 0 }, */
- {END_OF_LIST, 0 },
-};
-#endif
-
-/**
- * Look up a kernel algorithm ID and its key size
- */
-static int lookup_algorithm(kernel_algorithm_t *list, int ikev2)
-{
- while (list->ikev2 != END_OF_LIST)
- {
- if (ikev2 == list->ikev2)
- {
- return list->kernel;
- }
- list++;
- }
- return 0;
-}
-
-/**
- * add a host behind a sadb_address extension
- */
-static void host2ext(host_t *host, struct sadb_address *ext)
-{
- sockaddr_t *host_addr = host->get_sockaddr(host);
- socklen_t *len = host->get_sockaddr_len(host);
- memcpy((char*)(ext + 1), host_addr, *len);
- ext->sadb_address_len = PFKEY_LEN(sizeof(*ext) + *len);
-}
-
-/**
- * add a host to the given sadb_msg
- */
-static void add_addr_ext(struct sadb_msg *msg, host_t *host, u_int16_t type)
-{
- struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg);
- addr->sadb_address_exttype = type;
- host2ext(host, addr);
- PFKEY_EXT_ADD(msg, addr);
-}
-
-/**
- * adds an empty address extension to the given sadb_msg
- */
-static void add_anyaddr_ext(struct sadb_msg *msg, int family, u_int8_t type)
-{
- socklen_t len = (family == AF_INET) ? sizeof(struct sockaddr_in) :
- sizeof(struct sockaddr_in6);
- struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg);
- addr->sadb_address_exttype = type;
- sockaddr_t *saddr = (sockaddr_t*)(addr + 1);
- saddr->sa_family = family;
- addr->sadb_address_len = PFKEY_LEN(sizeof(*addr) + len);
- PFKEY_EXT_ADD(msg, addr);
-}
-
-/**
- * add udp encap extensions to a sadb_msg
- */
-static void add_encap_ext(struct sadb_msg *msg, host_t *src, host_t *dst,
- bool ports_only)
-{
- struct sadb_x_nat_t_type* nat_type;
- struct sadb_x_nat_t_port* nat_port;
-
- if (!ports_only)
- {
- nat_type = (struct sadb_x_nat_t_type*)PFKEY_EXT_ADD_NEXT(msg);
- nat_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
- nat_type->sadb_x_nat_t_type_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_type));
- nat_type->sadb_x_nat_t_type_type = UDP_ENCAP_ESPINUDP;
- PFKEY_EXT_ADD(msg, nat_type);
- }
-
- nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg);
- nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT;
- nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port));
- nat_port->sadb_x_nat_t_port_port = src->get_port(src);
- PFKEY_EXT_ADD(msg, nat_port);
-
- nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg);
- nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT;
- nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port));
- nat_port->sadb_x_nat_t_port_port = dst->get_port(dst);
- PFKEY_EXT_ADD(msg, nat_port);
-}
-
-/**
- * build an SADB_X_ADDFLOW msg
- */
-static void build_addflow(struct sadb_msg *msg, u_int8_t satype, u_int32_t spi,
- host_t *src, host_t *dst, host_t *src_net, u_int8_t src_mask,
- host_t *dst_net, u_int8_t dst_mask, u_int8_t protocol, bool replace)
-{
- struct sadb_sa *sa;
- struct sadb_protocol *proto;
- host_t *host;
-
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_X_ADDFLOW;
- msg->sadb_msg_satype = satype;
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
- sa->sadb_sa_exttype = SADB_EXT_SA;
- sa->sadb_sa_spi = spi;
- sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
- sa->sadb_sa_flags = replace ? SADB_X_SAFLAGS_REPLACEFLOW : 0;
- PFKEY_EXT_ADD(msg, sa);
-
- if (!src)
- {
- add_anyaddr_ext(msg, src_net->get_family(src_net), SADB_EXT_ADDRESS_SRC);
- }
- else
- {
- add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC);
- }
-
- if (!dst)
- {
- add_anyaddr_ext(msg, dst_net->get_family(dst_net), SADB_EXT_ADDRESS_DST);
- }
- else
- {
- add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST);
- }
-
- add_addr_ext(msg, src_net, SADB_X_EXT_ADDRESS_SRC_FLOW);
- add_addr_ext(msg, dst_net, SADB_X_EXT_ADDRESS_DST_FLOW);
-
- host = mask2host(src_net->get_family(src_net), src_mask);
- add_addr_ext(msg, host, SADB_X_EXT_ADDRESS_SRC_MASK);
- host->destroy(host);
-
- host = mask2host(dst_net->get_family(dst_net), dst_mask);
- add_addr_ext(msg, host, SADB_X_EXT_ADDRESS_DST_MASK);
- host->destroy(host);
-
- proto = (struct sadb_protocol*)PFKEY_EXT_ADD_NEXT(msg);
- proto->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
- proto->sadb_protocol_len = PFKEY_LEN(sizeof(struct sadb_protocol));
- proto->sadb_protocol_proto = protocol;
- PFKEY_EXT_ADD(msg, proto);
-}
-
-/**
- * build an SADB_X_DELFLOW msg
- */
-static void build_delflow(struct sadb_msg *msg, u_int8_t satype,
- host_t *src_net, u_int8_t src_mask, host_t *dst_net, u_int8_t dst_mask,
- u_int8_t protocol)
-{
- struct sadb_protocol *proto;
- host_t *host;
-
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_X_DELFLOW;
- msg->sadb_msg_satype = satype;
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- add_addr_ext(msg, src_net, SADB_X_EXT_ADDRESS_SRC_FLOW);
- add_addr_ext(msg, dst_net, SADB_X_EXT_ADDRESS_DST_FLOW);
-
- host = mask2host(src_net->get_family(src_net),
- src_mask);
- add_addr_ext(msg, host, SADB_X_EXT_ADDRESS_SRC_MASK);
- host->destroy(host);
-
- host = mask2host(dst_net->get_family(dst_net),
- dst_mask);
- add_addr_ext(msg, host, SADB_X_EXT_ADDRESS_DST_MASK);
- host->destroy(host);
-
- proto = (struct sadb_protocol*)PFKEY_EXT_ADD_NEXT(msg);
- proto->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
- proto->sadb_protocol_len = PFKEY_LEN(sizeof(struct sadb_protocol));
- proto->sadb_protocol_proto = protocol;
- PFKEY_EXT_ADD(msg, proto);
-}
-
-/**
- * Parses a pfkey message received from the kernel
- */
-static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out)
-{
- struct sadb_ext* ext;
- size_t len;
-
- memset(out, 0, sizeof(pfkey_msg_t));
- out->msg = msg;
-
- len = msg->sadb_msg_len;
- len -= PFKEY_LEN(sizeof(struct sadb_msg));
-
- ext = (struct sadb_ext*)(((char*)msg) + sizeof(struct sadb_msg));
-
- while (len >= PFKEY_LEN(sizeof(struct sadb_ext)))
- {
- if (ext->sadb_ext_len < PFKEY_LEN(sizeof(struct sadb_ext)) ||
- ext->sadb_ext_len > len)
- {
- DBG1(DBG_KNL, "length of PF_KEY extension (%d) is invalid", ext->sadb_ext_type);
- break;
- }
-
- if ((ext->sadb_ext_type > SADB_EXT_MAX) || (!ext->sadb_ext_type))
- {
- DBG1(DBG_KNL, "type of PF_KEY extension (%d) is invalid", ext->sadb_ext_type);
- break;
- }
-
- if (out->ext[ext->sadb_ext_type])
- {
- DBG1(DBG_KNL, "duplicate PF_KEY extension of type (%d)", ext->sadb_ext_type);
- break;
- }
-
- out->ext[ext->sadb_ext_type] = ext;
- ext = PFKEY_EXT_NEXT_LEN(ext, len);
- }
-
- if (len)
- {
- DBG1(DBG_KNL, "PF_KEY message length is invalid");
- return FAILED;
- }
-
- return SUCCESS;
-}
-
-/**
- * Send a message to a specific PF_KEY socket and handle the response.
- */
-static status_t pfkey_send_socket(private_kernel_klips_ipsec_t *this, int socket,
- struct sadb_msg *in, struct sadb_msg **out, size_t *out_len)
-{
- unsigned char buf[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg;
- int in_len, len;
-
- this->mutex_pfkey->lock(this->mutex_pfkey);
-
- in->sadb_msg_seq = ++this->seq;
- in->sadb_msg_pid = getpid();
-
- in_len = PFKEY_USER_LEN(in->sadb_msg_len);
-
- while (TRUE)
- {
- len = send(socket, in, in_len, 0);
-
- if (len != in_len)
- {
- switch (errno)
- {
- case EINTR:
- /* interrupted, try again */
- continue;
- case EINVAL:
- case EEXIST:
- case ESRCH:
- /* we should also get a response for these from KLIPS */
- break;
- default:
- this->mutex_pfkey->unlock(this->mutex_pfkey);
- DBG1(DBG_KNL, "error sending to PF_KEY socket: %s (%d)",
- strerror(errno), errno);
- return FAILED;
- }
- }
- break;
- }
-
- while (TRUE)
- {
- msg = (struct sadb_msg*)buf;
-
- len = recv(socket, buf, sizeof(buf), 0);
-
- if (len < 0)
- {
- if (errno == EINTR)
- {
- DBG1(DBG_KNL, "got interrupted");
- /* interrupted, try again */
- continue;
- }
- this->mutex_pfkey->unlock(this->mutex_pfkey);
- DBG1(DBG_KNL, "error reading from PF_KEY socket: %s", strerror(errno));
- return FAILED;
- }
- if (len < sizeof(struct sadb_msg) ||
- msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg)))
- {
- this->mutex_pfkey->unlock(this->mutex_pfkey);
- DBG1(DBG_KNL, "received corrupted PF_KEY message");
- return FAILED;
- }
- if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT)
- {
- this->mutex_pfkey->unlock(this->mutex_pfkey);
- DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message");
- return FAILED;
- }
- if (msg->sadb_msg_pid != in->sadb_msg_pid)
- {
- DBG2(DBG_KNL, "received PF_KEY message is not intended for us");
- continue;
- }
- if (msg->sadb_msg_seq != this->seq)
- {
- DBG1(DBG_KNL, "received PF_KEY message with invalid sequence number,"
- " was %d expected %d", msg->sadb_msg_seq, this->seq);
- if (msg->sadb_msg_seq < this->seq)
- {
- continue;
- }
- this->mutex_pfkey->unlock(this->mutex_pfkey);
- return FAILED;
- }
- if (msg->sadb_msg_type != in->sadb_msg_type)
- {
- DBG2(DBG_KNL, "received PF_KEY message of wrong type,"
- " was %d expected %d, ignoring",
- msg->sadb_msg_type, in->sadb_msg_type);
- }
- break;
- }
-
- *out_len = len;
- *out = (struct sadb_msg*)malloc(len);
- memcpy(*out, buf, len);
-
- this->mutex_pfkey->unlock(this->mutex_pfkey);
-
- return SUCCESS;
-}
-
-/**
- * Send a message to the default PF_KEY socket.
- */
-static status_t pfkey_send(private_kernel_klips_ipsec_t *this,
- struct sadb_msg *in, struct sadb_msg **out, size_t *out_len)
-{
- return pfkey_send_socket(this, this->socket, in, out, out_len);
-}
-
-/**
- * Send a message to the default PF_KEY socket and handle the response.
- */
-static status_t pfkey_send_ack(private_kernel_klips_ipsec_t *this, struct sadb_msg *in)
-{
- struct sadb_msg *out;
- size_t len;
-
- if (pfkey_send(this, in, &out, &len) != SUCCESS)
- {
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "PF_KEY error: %s (%d)",
- strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- free(out);
- return SUCCESS;
-}
-
-/**
- * Add an eroute to KLIPS
- */
-static status_t add_eroute(private_kernel_klips_ipsec_t *this, u_int8_t satype,
- u_int32_t spi, host_t *src, host_t *dst, host_t *src_net, u_int8_t src_mask,
- host_t *dst_net, u_int8_t dst_mask, u_int8_t protocol, bool replace)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg = (struct sadb_msg*)request;
-
- memset(&request, 0, sizeof(request));
-
- build_addflow(msg, satype, spi, src, dst, src_net, src_mask,
- dst_net, dst_mask, protocol, replace);
-
- return pfkey_send_ack(this, msg);
-}
-
-/**
- * Delete an eroute fom KLIPS
- */
-static status_t del_eroute(private_kernel_klips_ipsec_t *this, u_int8_t satype,
- host_t *src_net, u_int8_t src_mask, host_t *dst_net, u_int8_t dst_mask,
- u_int8_t protocol)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg = (struct sadb_msg*)request;
-
- memset(&request, 0, sizeof(request));
-
- build_delflow(msg, satype, src_net, src_mask, dst_net, dst_mask, protocol);
-
- return pfkey_send_ack(this, msg);
-}
-
-/**
- * Process a SADB_ACQUIRE message from the kernel
- */
-static void process_acquire(private_kernel_klips_ipsec_t *this, struct sadb_msg* msg)
-{
- pfkey_msg_t response;
- host_t *src, *dst;
- u_int32_t reqid;
- u_int8_t proto;
- policy_entry_t *policy;
- job_t *job;
-
- switch (msg->sadb_msg_satype)
- {
- case SADB_SATYPE_UNSPEC:
- case SADB_SATYPE_ESP:
- case SADB_SATYPE_AH:
- break;
- default:
- /* acquire for AH/ESP only */
- return;
- }
-
- if (parse_pfkey_message(msg, &response) != SUCCESS)
- {
- DBG1(DBG_KNL, "parsing SADB_ACQUIRE from kernel failed");
- return;
- }
-
- /* KLIPS provides us only with the source and destination address,
- * and the transport protocol of the packet that triggered the policy.
- * we use this information to find a matching policy in our cache.
- * because KLIPS installs a narrow %hold eroute covering only this information,
- * we replace both the %trap and this %hold eroutes with a broader %hold
- * eroute covering the whole policy */
- src = host_create_from_sockaddr((sockaddr_t*)(response.src + 1));
- dst = host_create_from_sockaddr((sockaddr_t*)(response.dst + 1));
- proto = response.src->sadb_address_proto;
- if (!src || !dst || src->get_family(src) != dst->get_family(dst))
- {
- DBG1(DBG_KNL, "received an SADB_ACQUIRE with invalid hosts");
- return;
- }
-
- DBG2(DBG_KNL, "received an SADB_ACQUIRE for %H == %H : %d", src, dst, proto);
- this->mutex->lock(this->mutex);
- if (this->policies->find_first(this->policies,
- (linked_list_match_t)policy_entry_match_byaddrs,
- (void**)&policy, src, dst) != SUCCESS)
- {
- this->mutex->unlock(this->mutex);
- DBG1(DBG_KNL, "received an SADB_ACQUIRE, but found no matching policy");
- return;
- }
- if ((reqid = policy->reqid) == 0)
- {
- this->mutex->unlock(this->mutex);
- DBG1(DBG_KNL, "received an SADB_ACQUIRE, but policy is not routed anymore");
- return;
- }
-
- /* add a broad %hold eroute that replaces the %trap eroute */
- add_eroute(this, SADB_X_SATYPE_INT, htonl(SPI_HOLD), NULL, NULL,
- policy->src.net, policy->src.mask, policy->dst.net, policy->dst.mask,
- policy->src.proto, TRUE);
-
- /* remove the narrow %hold eroute installed by KLIPS */
- del_eroute(this, SADB_X_SATYPE_INT, src, 32, dst, 32, proto);
-
- this->mutex->unlock(this->mutex);
-
- DBG2(DBG_KNL, "received an SADB_ACQUIRE");
- DBG1(DBG_KNL, "creating acquire job for CHILD_SA with reqid {%d}", reqid);
- job = (job_t*)acquire_job_create(reqid, NULL, NULL);
- charon->processor->queue_job(charon->processor, job);
-}
-
-/**
- * Process a SADB_X_NAT_T_NEW_MAPPING message from the kernel
- */
-static void process_mapping(private_kernel_klips_ipsec_t *this, struct sadb_msg* msg)
-{
- pfkey_msg_t response;
- u_int32_t spi, reqid;
- host_t *old_src, *new_src;
- job_t *job;
-
- DBG2(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING");
-
- if (parse_pfkey_message(msg, &response) != SUCCESS)
- {
- DBG1(DBG_KNL, "parsing SADB_X_NAT_T_NEW_MAPPING from kernel failed");
- return;
- }
-
- spi = response.sa->sadb_sa_spi;
-
- if (proto_satype2ike(msg->sadb_msg_satype) == PROTO_ESP)
- {
- sa_entry_t *sa;
- sockaddr_t *addr = (sockaddr_t*)(response.src + 1);
- old_src = host_create_from_sockaddr(addr);
-
- this->mutex->lock(this->mutex);
- if (!old_src || this->installed_sas->find_first(this->installed_sas,
- (linked_list_match_t)sa_entry_match_encapbysrc,
- (void**)&sa, &spi, old_src) != SUCCESS)
- {
- this->mutex->unlock(this->mutex);
- DBG1(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING, but found no matching SA");
- return;
- }
- reqid = sa->reqid;
- this->mutex->unlock(this->mutex);
-
- addr = (sockaddr_t*)(response.dst + 1);
- switch (addr->sa_family)
- {
- case AF_INET:
- {
- struct sockaddr_in *sin = (struct sockaddr_in*)addr;
- sin->sin_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port);
- }
- case AF_INET6:
- {
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)addr;
- sin6->sin6_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port);
- }
- default:
- break;
- }
- new_src = host_create_from_sockaddr(addr);
- if (new_src)
- {
- DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and"
- " reqid {%d} changed, queuing update job", ntohl(spi), reqid);
- job = (job_t*)update_sa_job_create(reqid, new_src);
- charon->processor->queue_job(charon->processor, job);
- }
- }
-}
-
-/**
- * Receives events from kernel
- */
-static job_requeue_t receive_events(private_kernel_klips_ipsec_t *this)
-{
- unsigned char buf[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg = (struct sadb_msg*)buf;
- int len;
- bool oldstate;
-
- oldstate = thread_cancelability(TRUE);
- len = recv(this->socket_events, buf, sizeof(buf), 0);
- thread_cancelability(oldstate);
-
- if (len < 0)
- {
- switch (errno)
- {
- case EINTR:
- /* interrupted, try again */
- return JOB_REQUEUE_DIRECT;
- case EAGAIN:
- /* no data ready, select again */
- return JOB_REQUEUE_DIRECT;
- default:
- DBG1(DBG_KNL, "unable to receive from PF_KEY event socket");
- sleep(1);
- return JOB_REQUEUE_FAIR;
- }
- }
-
- if (len < sizeof(struct sadb_msg) ||
- msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg)))
- {
- DBG2(DBG_KNL, "received corrupted PF_KEY message");
- return JOB_REQUEUE_DIRECT;
- }
- if (msg->sadb_msg_pid != 0)
- { /* not from kernel. not interested, try another one */
- return JOB_REQUEUE_DIRECT;
- }
- if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT)
- {
- DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message");
- return JOB_REQUEUE_DIRECT;
- }
-
- switch (msg->sadb_msg_type)
- {
- case SADB_ACQUIRE:
- process_acquire(this, msg);
- break;
- case SADB_EXPIRE:
- /* SADB_EXPIRE events in KLIPS are only triggered by traffic (even for
- * the time based limits). So if there is no traffic for a longer
- * period than configured as hard limit, we wouldn't be able to rekey
- * the SA and just receive the hard expire and thus delete the SA.
- * To avoid this behavior and to make charon behave as with the other
- * kernel plugins, we implement the expiration of SAs ourselves. */
- break;
- case SADB_X_NAT_T_NEW_MAPPING:
- process_mapping(this, msg);
- break;
- default:
- break;
- }
-
- return JOB_REQUEUE_DIRECT;
-}
-
-typedef enum {
- /** an SPI has expired */
- EXPIRE_TYPE_SPI,
- /** a CHILD_SA has to be rekeyed */
- EXPIRE_TYPE_SOFT,
- /** a CHILD_SA has to be deleted */
- EXPIRE_TYPE_HARD
-} expire_type_t;
-
-typedef struct sa_expire_t sa_expire_t;
-
-struct sa_expire_t {
- /** kernel interface */
- private_kernel_klips_ipsec_t *this;
- /** the SPI of the expiring SA */
- u_int32_t spi;
- /** the protocol of the expiring SA */
- protocol_id_t protocol;
- /** the reqid of the expiring SA*/
- u_int32_t reqid;
- /** what type of expire this is */
- expire_type_t type;
-};
-
-/**
- * Called when an SA expires
- */
-static job_requeue_t sa_expires(sa_expire_t *expire)
-{
- private_kernel_klips_ipsec_t *this = expire->this;
- protocol_id_t protocol = expire->protocol;
- u_int32_t spi = expire->spi, reqid = expire->reqid;
- bool hard = expire->type != EXPIRE_TYPE_SOFT;
- sa_entry_t *cached_sa;
- linked_list_t *list;
- job_t *job;
-
- /* for an expired SPI we first check whether the CHILD_SA got installed
- * in the meantime, for expired SAs we check whether they are still installed */
- list = expire->type == EXPIRE_TYPE_SPI ? this->allocated_spis : this->installed_sas;
-
- this->mutex->lock(this->mutex);
- if (list->find_first(list, (linked_list_match_t)sa_entry_match_byid,
- (void**)&cached_sa, &protocol, &spi, &reqid) != SUCCESS)
- {
- /* we found no entry:
- * - for SPIs, a CHILD_SA has been installed
- * - for SAs, the CHILD_SA has already been deleted */
- this->mutex->unlock(this->mutex);
- return JOB_REQUEUE_NONE;
- }
- else
- {
- list->remove(list, cached_sa, NULL);
- sa_entry_destroy(cached_sa);
- }
- this->mutex->unlock(this->mutex);
-
- DBG2(DBG_KNL, "%N CHILD_SA with SPI %.8x and reqid {%d} expired",
- protocol_id_names, protocol, ntohl(spi), reqid);
-
- DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%d}",
- hard ? "delete" : "rekey", protocol_id_names,
- protocol, ntohl(spi), reqid);
- if (hard)
- {
- job = (job_t*)delete_child_sa_job_create(reqid, protocol, spi);
- }
- else
- {
- job = (job_t*)rekey_child_sa_job_create(reqid, protocol, spi);
- }
- charon->processor->queue_job(charon->processor, job);
- return JOB_REQUEUE_NONE;
-}
-
-/**
- * Schedule an expire job for an SA. Time is in seconds.
- */
-static void schedule_expire(private_kernel_klips_ipsec_t *this,
- protocol_id_t protocol, u_int32_t spi,
- u_int32_t reqid, expire_type_t type, u_int32_t time)
-{
- callback_job_t *job;
- sa_expire_t *expire = malloc_thing(sa_expire_t);
- expire->this = this;
- expire->protocol = protocol;
- expire->spi = spi;
- expire->reqid = reqid;
- expire->type = type;
- job = callback_job_create((callback_job_cb_t)sa_expires, expire, free, NULL);
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)job, time);
-}
-
-METHOD(kernel_ipsec_t, get_spi, status_t,
- private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
- protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi)
-{
- /* we cannot use SADB_GETSPI because KLIPS does not allow us to set the
- * NAT-T type in an SADB_UPDATE which we would have to use to update the
- * implicitly created SA.
- */
- rng_t *rng;
- u_int32_t spi_gen;
-
- rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- if (!rng)
- {
- DBG1(DBG_KNL, "allocating SPI failed: no RNG");
- return FAILED;
- }
- rng->get_bytes(rng, sizeof(spi_gen), (void*)&spi_gen);
- rng->destroy(rng);
-
- /* charon's SPIs lie within the range from 0xc0000000 to 0xcFFFFFFF */
- spi_gen = 0xc0000000 | (spi_gen & 0x0FFFFFFF);
-
- DBG2(DBG_KNL, "allocated SPI %.8x for %N SA between %#H..%#H",
- spi_gen, protocol_id_names, protocol, src, dst);
-
- *spi = htonl(spi_gen);
-
- this->mutex->lock(this->mutex);
- this->allocated_spis->insert_last(this->allocated_spis,
- create_sa_entry(protocol, *spi, reqid, NULL, NULL, FALSE, TRUE));
- this->mutex->unlock(this->mutex);
- schedule_expire(this, protocol, *spi, reqid, EXPIRE_TYPE_SPI, SPI_TIMEOUT);
-
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, get_cpi, status_t,
- private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
-{
- return FAILED;
-}
-
-/**
- * Add a pseudo IPIP SA for tunnel mode with KLIPS.
- */
-static status_t add_ipip_sa(private_kernel_klips_ipsec_t *this,
- host_t *src, host_t *dst, u_int32_t spi, u_int32_t reqid)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_sa *sa;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- DBG2(DBG_KNL, "adding pseudo IPIP SA with SPI %.8x and reqid {%d}", ntohl(spi), reqid);
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_ADD;
- msg->sadb_msg_satype = SADB_X_SATYPE_IPIP;
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
- sa->sadb_sa_exttype = SADB_EXT_SA;
- sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
- sa->sadb_sa_spi = spi;
- sa->sadb_sa_state = SADB_SASTATE_MATURE;
- PFKEY_EXT_ADD(msg, sa);
-
- add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC);
- add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to add pseudo IPIP SA with SPI %.8x", ntohl(spi));
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to add pseudo IPIP SA with SPI %.8x: %s (%d)",
- ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
-
- free(out);
- return SUCCESS;
-}
-
-/**
- * group the IPIP SA required for tunnel mode with the outer SA
- */
-static status_t group_ipip_sa(private_kernel_klips_ipsec_t *this,
- host_t *src, host_t *dst, u_int32_t spi,
- protocol_id_t protocol, u_int32_t reqid)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_sa *sa;
- struct sadb_x_satype *satype;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- DBG2(DBG_KNL, "grouping SAs with SPI %.8x and reqid {%d}", ntohl(spi), reqid);
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_X_GRPSA;
- msg->sadb_msg_satype = SADB_X_SATYPE_IPIP;
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
- sa->sadb_sa_exttype = SADB_EXT_SA;
- sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
- sa->sadb_sa_spi = spi;
- sa->sadb_sa_state = SADB_SASTATE_MATURE;
- PFKEY_EXT_ADD(msg, sa);
-
- add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST);
-
- satype = (struct sadb_x_satype*)PFKEY_EXT_ADD_NEXT(msg);
- satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
- satype->sadb_x_satype_len = PFKEY_LEN(sizeof(struct sadb_x_satype));
- satype->sadb_x_satype_satype = proto_ike2satype(protocol);
- PFKEY_EXT_ADD(msg, satype);
-
- sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
- sa->sadb_sa_exttype = SADB_X_EXT_SA2;
- sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
- sa->sadb_sa_spi = spi;
- sa->sadb_sa_state = SADB_SASTATE_MATURE;
- PFKEY_EXT_ADD(msg, sa);
-
- add_addr_ext(msg, dst, SADB_X_EXT_ADDRESS_DST2);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to group SAs with SPI %.8x", ntohl(spi));
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to group SAs with SPI %.8x: %s (%d)",
- ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
-
- free(out);
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, add_sa, status_t,
- private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi,
- protocol_id_t protocol, u_int32_t reqid, mark_t mark,
- lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
- u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
- u_int16_t ipcomp, u_int16_t cpi, bool encap, bool inbound,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_sa *sa;
- struct sadb_key *key;
- size_t len;
-
- if (inbound)
- {
- /* for inbound SAs we allocated an SPI via get_spi, so we first check
- * whether that SPI has already expired (race condition) */
- sa_entry_t *alloc_spi;
- this->mutex->lock(this->mutex);
- if (this->allocated_spis->find_first(this->allocated_spis,
- (linked_list_match_t)sa_entry_match_byid, (void**)&alloc_spi,
- &protocol, &spi, &reqid) != SUCCESS)
- {
- this->mutex->unlock(this->mutex);
- DBG1(DBG_KNL, "allocated SPI %.8x has already expired", ntohl(spi));
- return FAILED;
- }
- else
- {
- this->allocated_spis->remove(this->allocated_spis, alloc_spi, NULL);
- sa_entry_destroy(alloc_spi);
- }
- this->mutex->unlock(this->mutex);
- }
-
- memset(&request, 0, sizeof(request));
-
- DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%d}", ntohl(spi), reqid);
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_ADD;
- msg->sadb_msg_satype = proto_ike2satype(protocol);
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
- sa->sadb_sa_exttype = SADB_EXT_SA;
- sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
- sa->sadb_sa_spi = spi;
- sa->sadb_sa_state = SADB_SASTATE_MATURE;
- sa->sadb_sa_replay = (protocol == IPPROTO_COMP) ? 0 : 32;
- sa->sadb_sa_auth = lookup_algorithm(integrity_algs, int_alg);
- sa->sadb_sa_encrypt = lookup_algorithm(encryption_algs, enc_alg);
- PFKEY_EXT_ADD(msg, sa);
-
- add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC);
- add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST);
-
- if (enc_alg != ENCR_UNDEFINED)
- {
- if (!sa->sadb_sa_encrypt)
- {
- DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- encryption_algorithm_names, enc_alg);
- return FAILED;
- }
- DBG2(DBG_KNL, " using encryption algorithm %N with key size %d",
- encryption_algorithm_names, enc_alg, enc_key.len * 8);
-
- key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg);
- key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
- key->sadb_key_bits = enc_key.len * 8;
- key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + enc_key.len);
- memcpy(key + 1, enc_key.ptr, enc_key.len);
-
- PFKEY_EXT_ADD(msg, key);
- }
-
- if (int_alg != AUTH_UNDEFINED)
- {
- if (!sa->sadb_sa_auth)
- {
- DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- integrity_algorithm_names, int_alg);
- return FAILED;
- }
- DBG2(DBG_KNL, " using integrity algorithm %N with key size %d",
- integrity_algorithm_names, int_alg, int_key.len * 8);
-
- key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg);
- key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
- key->sadb_key_bits = int_key.len * 8;
- key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + int_key.len);
- memcpy(key + 1, int_key.ptr, int_key.len);
-
- PFKEY_EXT_ADD(msg, key);
- }
-
- if (ipcomp != IPCOMP_NONE)
- {
- /*TODO*/
- }
-
- if (encap)
- {
- add_encap_ext(msg, src, dst, FALSE);
- }
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi));
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x: %s (%d)",
- ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- free(out);
-
- /* for tunnel mode SAs we have to install an additional IPIP SA and
- * group the two SAs together */
- if (mode == MODE_TUNNEL)
- {
- if (add_ipip_sa(this, src, dst, spi, reqid) != SUCCESS ||
- group_ipip_sa(this, src, dst, spi, protocol, reqid) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi));
- return FAILED;
- }
- }
-
- this->mutex->lock(this->mutex);
- /* we cache this SA for two reasons:
- * - in case an SADB_X_NAT_T_MAPPING_NEW event occurs (we need to find the reqid then)
- * - to decide if an expired SA is still installed */
- this->installed_sas->insert_last(this->installed_sas,
- create_sa_entry(protocol, spi, reqid, src, dst, encap, inbound));
- this->mutex->unlock(this->mutex);
-
- /* Although KLIPS supports SADB_EXT_LIFETIME_SOFT/HARD, we handle the lifetime
- * of SAs manually in the plugin. Refer to the comments in receive_events()
- * for details. */
- if (lifetime->time.rekey)
- {
- schedule_expire(this, protocol, spi, reqid, EXPIRE_TYPE_SOFT, lifetime->time.rekey);
- }
-
- if (lifetime->time.life)
- {
- schedule_expire(this, protocol, spi, reqid, EXPIRE_TYPE_HARD, lifetime->time.life);
- }
-
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, update_sa, status_t,
- private_kernel_klips_ipsec_t *this, u_int32_t spi, protocol_id_t protocol,
- u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
- bool encap, bool new_encap, mark_t mark)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_sa *sa;
- size_t len;
-
- /* we can't update the SA if any of the ip addresses have changed.
- * that's because we can't use SADB_UPDATE and by deleting and readding the
- * SA the sequence numbers would get lost */
- if (!src->ip_equals(src, new_src) ||
- !dst->ip_equals(dst, new_dst))
- {
- DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: address changes"
- " are not supported", ntohl(spi));
- return NOT_SUPPORTED;
- }
-
- /* because KLIPS does not allow us to change the NAT-T type in an SADB_UPDATE,
- * we can't update the SA if the encap flag has changed since installing it */
- if (encap != new_encap)
- {
- DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: change of UDP"
- " encapsulation is not supported", ntohl(spi));
- return NOT_SUPPORTED;
- }
-
- DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H",
- ntohl(spi), src, dst, new_src, new_dst);
-
- memset(&request, 0, sizeof(request));
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_UPDATE;
- msg->sadb_msg_satype = proto_ike2satype(protocol);
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
- sa->sadb_sa_exttype = SADB_EXT_SA;
- sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
- sa->sadb_sa_spi = spi;
- sa->sadb_sa_encrypt = SADB_EALG_AESCBC; /* ignored */
- sa->sadb_sa_auth = SADB_AALG_SHA1HMAC; /* ignored */
- sa->sadb_sa_state = SADB_SASTATE_MATURE;
- PFKEY_EXT_ADD(msg, sa);
-
- add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC);
- add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST);
-
- add_encap_ext(msg, new_src, new_dst, TRUE);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi));
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: %s (%d)",
- ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- free(out);
-
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, query_sa, status_t,
- private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
-{
- return NOT_SUPPORTED; /* TODO */
-}
-
-METHOD(kernel_ipsec_t, del_sa, status_t,
- private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_sa *sa;
- sa_entry_t *cached_sa;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- /* all grouped SAs are automatically deleted by KLIPS as soon as
- * one of them is deleted, therefore we delete only the main one */
- DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi));
-
- this->mutex->lock(this->mutex);
- /* this should not fail, but we don't care if it does, let the kernel decide
- * whether this SA exists or not */
- if (this->installed_sas->find_first(this->installed_sas,
- (linked_list_match_t)sa_entry_match_bydst, (void**)&cached_sa,
- &protocol, &spi, dst) == SUCCESS)
- {
- this->installed_sas->remove(this->installed_sas, cached_sa, NULL);
- sa_entry_destroy(cached_sa);
- }
- this->mutex->unlock(this->mutex);
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_DELETE;
- msg->sadb_msg_satype = proto_ike2satype(protocol);
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
- sa->sadb_sa_exttype = SADB_EXT_SA;
- sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
- sa->sadb_sa_spi = spi;
- PFKEY_EXT_ADD(msg, sa);
-
- /* the kernel wants an SADB_EXT_ADDRESS_SRC to be present even though
- * it is not used for anything. */
- add_anyaddr_ext(msg, dst->get_family(dst), SADB_EXT_ADDRESS_SRC);
- add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi));
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x: %s (%d)",
- ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
-
- DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi));
- free(out);
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, add_policy, status_t,
- private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
- policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
- u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool routed)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- policy_entry_t *policy, *found = NULL;
- u_int8_t satype;
- size_t len;
-
- if (direction == POLICY_FWD)
- {
- /* no forward policies for KLIPS */
- return SUCCESS;
- }
-
- /* tunnel mode policies direct the packets into the pseudo IPIP SA */
- satype = (mode == MODE_TUNNEL) ? SADB_X_SATYPE_IPIP :
- proto_ike2satype(protocol);
-
- /* create a policy */
- policy = create_policy_entry(src_ts, dst_ts, direction);
-
- /* find a matching policy */
- this->mutex->lock(this->mutex);
- if (this->policies->find_first(this->policies,
- (linked_list_match_t)policy_entry_equals, (void**)&found, policy) == SUCCESS)
- {
- /* use existing policy */
- DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing"
- " refcount", src_ts, dst_ts,
- policy_dir_names, direction);
- policy_entry_destroy(policy);
- policy = found;
- }
- else
- {
- /* apply the new one, if we have no such policy */
- this->policies->insert_last(this->policies, policy);
- }
-
- if (routed)
- {
- /* we install this as a %trap eroute in the kernel, later to be
- * triggered by packets matching the policy (-> ACQUIRE). */
- spi = htonl(SPI_TRAP);
- satype = SADB_X_SATYPE_INT;
-
- /* the reqid is always set to the latest child SA that trapped this
- * policy. we will need this reqid upon receiving an acquire. */
- policy->reqid = reqid;
-
- /* increase the trap counter */
- policy->trapcount++;
-
- if (policy->activecount)
- {
- /* we do not replace the current policy in the kernel while a
- * policy is actively used */
- this->mutex->unlock(this->mutex);
- return SUCCESS;
- }
- }
- else
- {
- /* increase the reference counter */
- policy->activecount++;
- }
-
- DBG2(DBG_KNL, "adding policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
-
- memset(&request, 0, sizeof(request));
-
- msg = (struct sadb_msg*)request;
-
- /* FIXME: SADB_X_SAFLAGS_INFLOW may be required, if we add an inbound policy for an IPIP SA */
- build_addflow(msg, satype, spi, routed ? NULL : src, routed ? NULL : dst,
- policy->src.net, policy->src.mask, policy->dst.net, policy->dst.mask,
- policy->src.proto, found != NULL);
-
- this->mutex->unlock(this->mutex);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to add policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to add policy %R === %R %N: %s (%d)", src_ts, dst_ts,
- policy_dir_names, direction,
- strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- free(out);
-
- this->mutex->lock(this->mutex);
-
- /* we try to find the policy again and install the route if needed */
- if (this->policies->find_last(this->policies, NULL, (void**)&policy) != SUCCESS)
- {
- this->mutex->unlock(this->mutex);
- DBG2(DBG_KNL, "the policy %R === %R %N is already gone, ignoring",
- src_ts, dst_ts, policy_dir_names, direction);
- return SUCCESS;
- }
-
- /* KLIPS requires a special route that directs traffic that matches this
- * policy to one of the virtual ipsec interfaces. The virtual interface
- * has to be attached to the physical one the traffic runs over.
- * This is a special case of the source route we install in other kernel
- * interfaces.
- * In the following cases we do NOT install a source route (but just a
- * regular route):
- * - we are not in tunnel mode
- * - we are using IPv6 (does not work correctly yet!)
- * - routing is disabled via strongswan.conf
- */
- if (policy->route == NULL && direction == POLICY_OUT)
- {
- char *iface;
- ipsec_dev_t *dev;
- route_entry_t *route = malloc_thing(route_entry_t);
- route->src_ip = NULL;
-
- if (mode != MODE_TRANSPORT && src->get_family(src) != AF_INET6 &&
- this->install_routes)
- {
- charon->kernel_interface->get_address_by_ts(charon->kernel_interface,
- src_ts, &route->src_ip);
- }
-
- if (!route->src_ip)
- {
- route->src_ip = host_create_any(src->get_family(src));
- }
-
- /* find the virtual interface */
- iface = charon->kernel_interface->get_interface(charon->kernel_interface,
- src);
- if (find_ipsec_dev(this, iface, &dev) == SUCCESS)
- {
- /* above, we got either the name of a virtual or a physical
- * interface. for both cases it means we already have the devices
- * properly attached (assuming that we are exclusively attaching
- * ipsec devices). */
- dev->refcount++;
- }
- else
- {
- /* there is no record of a mapping with the returned interface.
- * thus, we attach the first free virtual interface we find to
- * it. As above we assume we are the only client fiddling with
- * ipsec devices. */
- if (this->ipsec_devices->find_first(this->ipsec_devices,
- (linked_list_match_t)ipsec_dev_match_free,
- (void**)&dev) == SUCCESS)
- {
- if (attach_ipsec_dev(dev->name, iface) == SUCCESS)
- {
- strncpy(dev->phys_name, iface, IFNAMSIZ);
- dev->refcount = 1;
- }
- else
- {
- DBG1(DBG_KNL, "failed to attach virtual interface %s"
- " to %s", dev->name, iface);
- this->mutex->unlock(this->mutex);
- free(iface);
- return FAILED;
- }
- }
- else
- {
- this->mutex->unlock(this->mutex);
- DBG1(DBG_KNL, "failed to attach a virtual interface to %s: no"
- " virtual interfaces left", iface);
- free(iface);
- return FAILED;
- }
- }
- free(iface);
- route->if_name = strdup(dev->name);
-
- /* get the nexthop to dst */
- route->gateway = charon->kernel_interface->get_nexthop(
- charon->kernel_interface, dst);
- route->dst_net = chunk_clone(policy->dst.net->get_address(policy->dst.net));
- route->prefixlen = policy->dst.mask;
-
- switch (charon->kernel_interface->add_route(charon->kernel_interface,
- route->dst_net, route->prefixlen, route->gateway,
- route->src_ip, route->if_name))
- {
- default:
- DBG1(DBG_KNL, "unable to install route for policy %R === %R",
- src_ts, dst_ts);
- /* FALL */
- case ALREADY_DONE:
- /* route exists, do not uninstall */
- route_entry_destroy(route);
- break;
- case SUCCESS:
- /* cache the installed route */
- policy->route = route;
- break;
- }
- }
-
- this->mutex->unlock(this->mutex);
-
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, query_policy, status_t,
- private_kernel_klips_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
- u_int32_t *use_time)
-{
- #define IDLE_PREFIX "idle="
- static const char *path_eroute = "/proc/net/ipsec_eroute";
- static const char *path_spi = "/proc/net/ipsec_spi";
- FILE *file;
- char line[1024], src[INET6_ADDRSTRLEN + 9], dst[INET6_ADDRSTRLEN + 9];
- char *said = NULL, *pos;
- policy_entry_t *policy, *found = NULL;
- status_t status = FAILED;
-
- if (direction == POLICY_FWD)
- {
- /* we do not install forward policies */
- return FAILED;
- }
-
- DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
-
- /* create a policy */
- policy = create_policy_entry(src_ts, dst_ts, direction);
-
- /* find a matching policy */
- this->mutex->lock(this->mutex);
- if (this->policies->find_first(this->policies,
- (linked_list_match_t)policy_entry_equals, (void**)&found, policy) != SUCCESS)
- {
- this->mutex->unlock(this->mutex);
- DBG1(DBG_KNL, "querying policy %R === %R %N failed, not found", src_ts,
- dst_ts, policy_dir_names, direction);
- policy_entry_destroy(policy);
- return NOT_FOUND;
- }
- policy_entry_destroy(policy);
- policy = found;
-
- /* src and dst selectors in KLIPS are of the form NET_ADDR/NETBITS:PROTO */
- snprintf(src, sizeof(src), "%H/%d:%d", policy->src.net, policy->src.mask,
- policy->src.proto);
- src[sizeof(src) - 1] = '\0';
- snprintf(dst, sizeof(dst), "%H/%d:%d", policy->dst.net, policy->dst.mask,
- policy->dst.proto);
- dst[sizeof(dst) - 1] = '\0';
-
- this->mutex->unlock(this->mutex);
-
- /* we try to find the matching eroute first */
- file = fopen(path_eroute, "r");
- if (file == NULL)
- {
- DBG1(DBG_KNL, "unable to query policy %R === %R %N: %s (%d)", src_ts,
- dst_ts, policy_dir_names, direction, strerror(errno), errno);
- return FAILED;
- }
-
- /* read line by line where each line looks like:
- * packets src -> dst => said */
- while (fgets(line, sizeof(line), file))
- {
- enumerator_t *enumerator;
- char *token;
- int i = 0;
-
- enumerator = enumerator_create_token(line, " \t", " \t\n");
- while (enumerator->enumerate(enumerator, &token))
- {
- switch (i++)
- {
- case 0: /* packets */
- continue;
- case 1: /* src */
- if (streq(token, src))
- {
- continue;
- }
- break;
- case 2: /* -> */
- continue;
- case 3: /* dst */
- if (streq(token, dst))
- {
- continue;
- }
- break;
- case 4: /* => */
- continue;
- case 5: /* said */
- said = strdup(token);
- break;
- }
- break;
- }
- enumerator->destroy(enumerator);
-
- if (i == 5)
- {
- /* eroute matched */
- break;
- }
- }
- fclose(file);
-
- if (said == NULL)
- {
- DBG1(DBG_KNL, "unable to query policy %R === %R %N: found no matching"
- " eroute", src_ts, dst_ts, policy_dir_names, direction);
- return FAILED;
- }
-
- /* compared with the one in the spi entry the SA ID from the eroute entry
- * has an additional ":PROTO" appended, which we need to cut off */
- pos = strrchr(said, ':');
- *pos = '\0';
-
- /* now we try to find the matching spi entry */
- file = fopen(path_spi, "r");
- if (file == NULL)
- {
- DBG1(DBG_KNL, "unable to query policy %R === %R %N: %s (%d)", src_ts,
- dst_ts, policy_dir_names, direction, strerror(errno), errno);
- return FAILED;
- }
-
- while (fgets(line, sizeof(line), file))
- {
- if (strneq(line, said, strlen(said)))
- {
- /* fine we found the correct line, now find the idle time */
- u_int32_t idle_time;
- pos = strstr(line, IDLE_PREFIX);
- if (pos == NULL)
- {
- /* no idle time, i.e. this SA has not been used yet */
- break;
- }
- if (sscanf(pos, IDLE_PREFIX"%u", &idle_time) <= 0)
- {
- /* idle time not valid */
- break;
- }
-
- *use_time = time_monotonic(NULL) - idle_time;
- status = SUCCESS;
- break;
- }
- }
- fclose(file);
- free(said);
-
- return status;
-}
-
-METHOD(kernel_ipsec_t, del_policy, status_t,
- private_kernel_klips_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
- bool unrouted)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg = (struct sadb_msg*)request, *out;
- policy_entry_t *policy, *found = NULL;
- route_entry_t *route;
- size_t len;
-
- if (direction == POLICY_FWD)
- {
- /* no forward policies for KLIPS */
- return SUCCESS;
- }
-
- DBG2(DBG_KNL, "deleting policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
-
- /* create a policy */
- policy = create_policy_entry(src_ts, dst_ts, direction);
-
- /* find a matching policy */
- this->mutex->lock(this->mutex);
- if (this->policies->find_first(this->policies,
- (linked_list_match_t)policy_entry_equals, (void**)&found, policy) != SUCCESS)
- {
- this->mutex->unlock(this->mutex);
- DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", src_ts,
- dst_ts, policy_dir_names, direction);
- policy_entry_destroy(policy);
- return NOT_FOUND;
- }
- policy_entry_destroy(policy);
-
- /* decrease appropriate counter */
- unrouted ? found->trapcount-- : found->activecount--;
-
- if (found->trapcount == 0)
- {
- /* if this policy is finally unrouted, we reset the reqid because it
- * may still be actively used and there might be a pending acquire for
- * this policy. */
- found->reqid = 0;
- }
-
- if (found->activecount > 0)
- {
- /* is still used by SAs, keep in kernel */
- this->mutex->unlock(this->mutex);
- DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed");
- return SUCCESS;
- }
- else if (found->activecount == 0 && found->trapcount > 0)
- {
- /* for a policy that is not used actively anymore, but is still trapped
- * by another child SA we replace the current eroute with a %trap eroute */
- DBG2(DBG_KNL, "policy still routed by another CHILD_SA, not removed");
- memset(&request, 0, sizeof(request));
- build_addflow(msg, SADB_X_SATYPE_INT, htonl(SPI_TRAP), NULL, NULL,
- found->src.net, found->src.mask, found->dst.net,
- found->dst.mask, found->src.proto, TRUE);
- this->mutex->unlock(this->mutex);
- return pfkey_send_ack(this, msg);
- }
-
- /* remove if last reference */
- this->policies->remove(this->policies, found, NULL);
- policy = found;
-
- this->mutex->unlock(this->mutex);
-
- memset(&request, 0, sizeof(request));
-
- build_delflow(msg, 0, policy->src.net, policy->src.mask, policy->dst.net,
- policy->dst.mask, policy->src.proto);
-
- route = policy->route;
- policy->route = NULL;
- policy_entry_destroy(policy);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to delete policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to delete policy %R === %R %N: %s (%d)", src_ts,
- dst_ts, policy_dir_names, direction,
- strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- free(out);
-
- if (route)
- {
- ipsec_dev_t *dev;
-
- if (charon->kernel_interface->del_route(charon->kernel_interface,
- route->dst_net, route->prefixlen, route->gateway,
- route->src_ip, route->if_name) != SUCCESS)
- {
- DBG1(DBG_KNL, "error uninstalling route installed with"
- " policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
- }
-
- /* we have to detach the ipsec interface from the physical one over which
- * this SA ran (if it is not used by any other) */
- this->mutex->lock(this->mutex);
-
- if (find_ipsec_dev(this, route->if_name, &dev) == SUCCESS)
- {
- /* fine, we found a matching device object, let's check if we have
- * to detach it. */
- if (--dev->refcount == 0)
- {
- if (detach_ipsec_dev(dev->name, dev->phys_name) != SUCCESS)
- {
- DBG1(DBG_KNL, "failed to detach virtual interface %s"
- " from %s", dev->name, dev->phys_name);
- }
- dev->phys_name[0] = '\0';
- }
- }
-
- this->mutex->unlock(this->mutex);
-
- route_entry_destroy(route);
- }
-
- return SUCCESS;
-}
-
-/**
- * Initialize the list of ipsec devices
- */
-static void init_ipsec_devices(private_kernel_klips_ipsec_t *this)
-{
- int i, count = lib->settings->get_int(lib->settings,
- "charon.plugins.kernel-klips.ipsec_dev_count",
- DEFAULT_IPSEC_DEV_COUNT);
-
- for (i = 0; i < count; ++i)
- {
- ipsec_dev_t *dev = malloc_thing(ipsec_dev_t);
- snprintf(dev->name, IFNAMSIZ, IPSEC_DEV_PREFIX"%d", i);
- dev->name[IFNAMSIZ - 1] = '\0';
- dev->phys_name[0] = '\0';
- dev->refcount = 0;
- this->ipsec_devices->insert_last(this->ipsec_devices, dev);
-
- /* detach any previously attached ipsec device */
- detach_ipsec_dev(dev->name, dev->phys_name);
- }
-}
-
-/**
- * Register a socket for AQUIRE/EXPIRE messages
- */
-static status_t register_pfkey_socket(private_kernel_klips_ipsec_t *this, u_int8_t satype)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_REGISTER;
- msg->sadb_msg_satype = satype;
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- if (pfkey_send_socket(this, this->socket_events, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to register PF_KEY socket");
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to register PF_KEY socket: %s (%d)",
- strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- free(out);
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, bypass_socket, bool,
- private_kernel_klips_ipsec_t *this, int fd, int family)
-{
- /* KLIPS does not need a bypass policy for IKE */
- return TRUE;
-}
-
-METHOD(kernel_ipsec_t, destroy, void,
- private_kernel_klips_ipsec_t *this)
-{
- if (this->job)
- {
- this->job->cancel(this->job);
- }
- if (this->socket > 0)
- {
- close(this->socket);
- }
- if (this->socket_events > 0)
- {
- close(this->socket_events);
- }
- this->mutex_pfkey->destroy(this->mutex_pfkey);
- this->mutex->destroy(this->mutex);
- this->ipsec_devices->destroy_function(this->ipsec_devices, (void*)ipsec_dev_destroy);
- this->installed_sas->destroy_function(this->installed_sas, (void*)sa_entry_destroy);
- this->allocated_spis->destroy_function(this->allocated_spis, (void*)sa_entry_destroy);
- this->policies->destroy_function(this->policies, (void*)policy_entry_destroy);
- free(this);
-}
-
-/*
- * Described in header.
- */
-kernel_klips_ipsec_t *kernel_klips_ipsec_create()
-{
- private_kernel_klips_ipsec_t *this;
-
- INIT(this,
- .public.interface = {
- .get_spi = _get_spi,
- .get_cpi = _get_cpi,
- .add_sa = _add_sa,
- .update_sa = _update_sa,
- .query_sa = _query_sa,
- .del_sa = _del_sa,
- .add_policy = _add_policy,
- .query_policy = _query_policy,
- .del_policy = _del_policy,
- .bypass_socket = _bypass_socket,
- .destroy = _destroy,
- },
- .policies = linked_list_create(),
- .allocated_spis = linked_list_create(),
- .installed_sas = linked_list_create(),
- .ipsec_devices = linked_list_create(),
- .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
- .mutex_pfkey = mutex_create(MUTEX_TYPE_DEFAULT),
- .install_routes = lib->settings->get_bool(lib->settings,
- "charon.install_routes", TRUE),
- );
-
- /* initialize ipsec devices */
- init_ipsec_devices(this);
-
- /* create a PF_KEY socket to communicate with the kernel */
- this->socket = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
- if (this->socket <= 0)
- {
- DBG1(DBG_KNL, "unable to create PF_KEY socket");
- destroy(this);
- return NULL;
- }
-
- /* create a PF_KEY socket for ACQUIRE & EXPIRE */
- this->socket_events = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
- if (this->socket_events <= 0)
- {
- DBG1(DBG_KNL, "unable to create PF_KEY event socket");
- destroy(this);
- return NULL;
- }
-
- /* register the event socket */
- if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS ||
- register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to register PF_KEY event socket");
- destroy(this);
- return NULL;
- }
-
- this->job = callback_job_create((callback_job_cb_t)receive_events,
- this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
-
- return &this->public;
-}
-
diff --git a/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.h b/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.h
deleted file mode 100644
index 306ec0ada..000000000
--- a/src/libcharon/plugins/kernel_klips/kernel_klips_ipsec.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup kernel_klips_ipsec_i kernel_klips_ipsec
- * @{ @ingroup kernel_klips
- */
-
-#ifndef KERNEL_KLIPS_IPSEC_H_
-#define KERNEL_KLIPS_IPSEC_H_
-
-#include <kernel/kernel_ipsec.h>
-
-typedef struct kernel_klips_ipsec_t kernel_klips_ipsec_t;
-
-/**
- * Implementation of the kernel ipsec interface using PF_KEY.
- */
-struct kernel_klips_ipsec_t {
-
- /**
- * Implements kernel_ipsec_t interface
- */
- kernel_ipsec_t interface;
-};
-
-/**
- * Create a PF_KEY kernel ipsec interface instance.
- *
- * @return kernel_klips_ipsec_t instance
- */
-kernel_klips_ipsec_t *kernel_klips_ipsec_create();
-
-#endif /** KERNEL_KLIPS_IPSEC_H_ @}*/
diff --git a/src/libcharon/plugins/kernel_klips/kernel_klips_plugin.c b/src/libcharon/plugins/kernel_klips/kernel_klips_plugin.c
deleted file mode 100644
index fa5e9eb29..000000000
--- a/src/libcharon/plugins/kernel_klips/kernel_klips_plugin.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-
-#include "kernel_klips_plugin.h"
-
-#include "kernel_klips_ipsec.h"
-
-#include <daemon.h>
-
-typedef struct private_kernel_klips_plugin_t private_kernel_klips_plugin_t;
-
-/**
- * private data of kernel PF_KEY plugin
- */
-struct private_kernel_klips_plugin_t {
- /**
- * implements plugin interface
- */
- kernel_klips_plugin_t public;
-};
-
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(private_kernel_klips_plugin_t *this)
-{
- charon->kernel_interface->remove_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_klips_ipsec_create);
- free(this);
-}
-
-/*
- * see header file
- */
-plugin_t *kernel_klips_plugin_create()
-{
- private_kernel_klips_plugin_t *this = malloc_thing(private_kernel_klips_plugin_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
-
- charon->kernel_interface->add_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_klips_ipsec_create);
-
- return &this->public.plugin;
-}
diff --git a/src/libcharon/plugins/kernel_klips/pfkeyv2.h b/src/libcharon/plugins/kernel_klips/pfkeyv2.h
deleted file mode 100644
index 20d1c298d..000000000
--- a/src/libcharon/plugins/kernel_klips/pfkeyv2.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
-RFC 2367 PF_KEY Key Management API July 1998
-
-
-Appendix D: Sample Header File
-
-This file defines structures and symbols for the PF_KEY Version 2
-key management interface. It was written at the U.S. Naval Research
-Laboratory. This file is in the public domain. The authors ask that
-you leave this credit intact on any copies of this file.
-*/
-#ifndef __PFKEY_V2_H
-#define __PFKEY_V2_H 1
-
-#define PF_KEY_V2 2
-#define PFKEYV2_REVISION 199806L
-
-#define SADB_RESERVED 0
-#define SADB_GETSPI 1
-#define SADB_UPDATE 2
-#define SADB_ADD 3
-#define SADB_DELETE 4
-#define SADB_GET 5
-#define SADB_ACQUIRE 6
-#define SADB_REGISTER 7
-#define SADB_EXPIRE 8
-#define SADB_FLUSH 9
-#define SADB_DUMP 10
-#define SADB_X_PROMISC 11
-#define SADB_X_PCHANGE 12
-#define SADB_X_GRPSA 13
-#define SADB_X_ADDFLOW 14
-#define SADB_X_DELFLOW 15
-#define SADB_X_DEBUG 16
-#define SADB_X_NAT_T_NEW_MAPPING 17
-#define SADB_MAX 17
-
-struct sadb_msg {
- uint8_t sadb_msg_version;
- uint8_t sadb_msg_type;
- uint8_t sadb_msg_errno;
- uint8_t sadb_msg_satype;
- uint16_t sadb_msg_len;
- uint16_t sadb_msg_reserved;
- uint32_t sadb_msg_seq;
- uint32_t sadb_msg_pid;
-};
-
-struct sadb_ext {
- uint16_t sadb_ext_len;
- uint16_t sadb_ext_type;
-};
-
-struct sadb_sa {
- uint16_t sadb_sa_len;
- uint16_t sadb_sa_exttype;
- uint32_t sadb_sa_spi;
- uint8_t sadb_sa_replay;
- uint8_t sadb_sa_state;
- uint8_t sadb_sa_auth;
- uint8_t sadb_sa_encrypt;
- uint32_t sadb_sa_flags;
-};
-
-struct sadb_lifetime {
- uint16_t sadb_lifetime_len;
- uint16_t sadb_lifetime_exttype;
- uint32_t sadb_lifetime_allocations;
- uint64_t sadb_lifetime_bytes;
- uint64_t sadb_lifetime_addtime;
- uint64_t sadb_lifetime_usetime;
- uint32_t sadb_x_lifetime_packets;
- uint32_t sadb_x_lifetime_reserved;
-};
-
-struct sadb_address {
- uint16_t sadb_address_len;
- uint16_t sadb_address_exttype;
- uint8_t sadb_address_proto;
- uint8_t sadb_address_prefixlen;
- uint16_t sadb_address_reserved;
-};
-
-struct sadb_key {
- uint16_t sadb_key_len;
- uint16_t sadb_key_exttype;
- uint16_t sadb_key_bits;
- uint16_t sadb_key_reserved;
-};
-
-struct sadb_ident {
- uint16_t sadb_ident_len;
- uint16_t sadb_ident_exttype;
- uint16_t sadb_ident_type;
- uint16_t sadb_ident_reserved;
- uint64_t sadb_ident_id;
-};
-
-struct sadb_sens {
- uint16_t sadb_sens_len;
- uint16_t sadb_sens_exttype;
- uint32_t sadb_sens_dpd;
- uint8_t sadb_sens_sens_level;
- uint8_t sadb_sens_sens_len;
- uint8_t sadb_sens_integ_level;
- uint8_t sadb_sens_integ_len;
- uint32_t sadb_sens_reserved;
-};
-
-struct sadb_prop {
- uint16_t sadb_prop_len;
- uint16_t sadb_prop_exttype;
- uint8_t sadb_prop_replay;
- uint8_t sadb_prop_reserved[3];
-};
-
-struct sadb_comb {
- uint8_t sadb_comb_auth;
- uint8_t sadb_comb_encrypt;
- uint16_t sadb_comb_flags;
- uint16_t sadb_comb_auth_minbits;
- uint16_t sadb_comb_auth_maxbits;
- uint16_t sadb_comb_encrypt_minbits;
- uint16_t sadb_comb_encrypt_maxbits;
- uint32_t sadb_comb_reserved;
- uint32_t sadb_comb_soft_allocations;
- uint32_t sadb_comb_hard_allocations;
- uint64_t sadb_comb_soft_bytes;
- uint64_t sadb_comb_hard_bytes;
- uint64_t sadb_comb_soft_addtime;
- uint64_t sadb_comb_hard_addtime;
- uint64_t sadb_comb_soft_usetime;
- uint64_t sadb_comb_hard_usetime;
- uint32_t sadb_x_comb_soft_packets;
- uint32_t sadb_x_comb_hard_packets;
-};
-
-struct sadb_supported {
- uint16_t sadb_supported_len;
- uint16_t sadb_supported_exttype;
- uint32_t sadb_supported_reserved;
-};
-
-struct sadb_alg {
- uint8_t sadb_alg_id;
- uint8_t sadb_alg_ivlen;
- uint16_t sadb_alg_minbits;
- uint16_t sadb_alg_maxbits;
- uint16_t sadb_alg_reserved;
-};
-
-struct sadb_spirange {
- uint16_t sadb_spirange_len;
- uint16_t sadb_spirange_exttype;
- uint32_t sadb_spirange_min;
- uint32_t sadb_spirange_max;
- uint32_t sadb_spirange_reserved;
-};
-
-struct sadb_x_kmprivate {
- uint16_t sadb_x_kmprivate_len;
- uint16_t sadb_x_kmprivate_exttype;
- uint32_t sadb_x_kmprivate_reserved;
-};
-
-struct sadb_x_satype {
- uint16_t sadb_x_satype_len;
- uint16_t sadb_x_satype_exttype;
- uint8_t sadb_x_satype_satype;
- uint8_t sadb_x_satype_reserved[3];
-};
-
-struct sadb_x_debug {
- uint16_t sadb_x_debug_len;
- uint16_t sadb_x_debug_exttype;
- uint32_t sadb_x_debug_tunnel;
- uint32_t sadb_x_debug_netlink;
- uint32_t sadb_x_debug_xform;
- uint32_t sadb_x_debug_eroute;
- uint32_t sadb_x_debug_spi;
- uint32_t sadb_x_debug_radij;
- uint32_t sadb_x_debug_esp;
- uint32_t sadb_x_debug_ah;
- uint32_t sadb_x_debug_rcv;
- uint32_t sadb_x_debug_pfkey;
- uint32_t sadb_x_debug_ipcomp;
- uint32_t sadb_x_debug_verbose;
- uint8_t sadb_x_debug_reserved[4];
-};
-
-struct sadb_x_nat_t_type {
- uint16_t sadb_x_nat_t_type_len;
- uint16_t sadb_x_nat_t_type_exttype;
- uint8_t sadb_x_nat_t_type_type;
- uint8_t sadb_x_nat_t_type_reserved[3];
-};
-struct sadb_x_nat_t_port {
- uint16_t sadb_x_nat_t_port_len;
- uint16_t sadb_x_nat_t_port_exttype;
- uint16_t sadb_x_nat_t_port_port;
- uint16_t sadb_x_nat_t_port_reserved;
-};
-
-/*
- * A protocol structure for passing through the transport level
- * protocol. It contains more fields than are actually used/needed
- * but it is this way to be compatible with the structure used in
- * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
- */
-struct sadb_protocol {
- uint16_t sadb_protocol_len;
- uint16_t sadb_protocol_exttype;
- uint8_t sadb_protocol_proto;
- uint8_t sadb_protocol_direction;
- uint8_t sadb_protocol_flags;
- uint8_t sadb_protocol_reserved2;
-};
-
-#define SADB_EXT_RESERVED 0
-#define SADB_EXT_SA 1
-#define SADB_EXT_LIFETIME_CURRENT 2
-#define SADB_EXT_LIFETIME_HARD 3
-#define SADB_EXT_LIFETIME_SOFT 4
-#define SADB_EXT_ADDRESS_SRC 5
-#define SADB_EXT_ADDRESS_DST 6
-#define SADB_EXT_ADDRESS_PROXY 7
-#define SADB_EXT_KEY_AUTH 8
-#define SADB_EXT_KEY_ENCRYPT 9
-#define SADB_EXT_IDENTITY_SRC 10
-#define SADB_EXT_IDENTITY_DST 11
-#define SADB_EXT_SENSITIVITY 12
-#define SADB_EXT_PROPOSAL 13
-#define SADB_EXT_SUPPORTED_AUTH 14
-#define SADB_EXT_SUPPORTED_ENCRYPT 15
-#define SADB_EXT_SPIRANGE 16
-#define SADB_X_EXT_KMPRIVATE 17
-#define SADB_X_EXT_SATYPE2 18
-#define SADB_X_EXT_SA2 19
-#define SADB_X_EXT_ADDRESS_DST2 20
-#define SADB_X_EXT_ADDRESS_SRC_FLOW 21
-#define SADB_X_EXT_ADDRESS_DST_FLOW 22
-#define SADB_X_EXT_ADDRESS_SRC_MASK 23
-#define SADB_X_EXT_ADDRESS_DST_MASK 24
-#define SADB_X_EXT_DEBUG 25
-#define SADB_X_EXT_PROTOCOL 26
-#define SADB_X_EXT_NAT_T_TYPE 27
-#define SADB_X_EXT_NAT_T_SPORT 28
-#define SADB_X_EXT_NAT_T_DPORT 29
-#define SADB_X_EXT_NAT_T_OA 30
-#define SADB_EXT_MAX 30
-
-/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
-#define SADB_X_EXT_ADDRESS_DELFLOW \
- ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
- | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
- | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
- | (1<<SADB_X_EXT_ADDRESS_DST_MASK))
-
-#define SADB_SATYPE_UNSPEC 0
-#define SADB_SATYPE_AH 2
-#define SADB_SATYPE_ESP 3
-#define SADB_SATYPE_RSVP 5
-#define SADB_SATYPE_OSPFV2 6
-#define SADB_SATYPE_RIPV2 7
-#define SADB_SATYPE_MIP 8
-#define SADB_X_SATYPE_IPIP 9
-#define SADB_X_SATYPE_COMP 10
-#define SADB_X_SATYPE_INT 11
-#define SADB_SATYPE_MAX 11
-
-#define SADB_SASTATE_LARVAL 0
-#define SADB_SASTATE_MATURE 1
-#define SADB_SASTATE_DYING 2
-#define SADB_SASTATE_DEAD 3
-#define SADB_SASTATE_MAX 3
-
-#define SADB_SAFLAGS_PFS 1
-#define SADB_X_SAFLAGS_REPLACEFLOW 2
-#define SADB_X_SAFLAGS_CLEARFLOW 4
-#define SADB_X_SAFLAGS_INFLOW 8
-
-#define SADB_AALG_NONE 0
-#define SADB_AALG_MD5HMAC 2
-#define SADB_AALG_SHA1HMAC 3
-#define SADB_AALG_SHA256_HMAC 5
-#define SADB_AALG_SHA384_HMAC 6
-#define SADB_AALG_SHA512_HMAC 7
-#define SADB_AALG_RIPEMD160HMAC 8
-#define SADB_AALG_MAX 15
-
-#define SADB_EALG_NONE 0
-#define SADB_EALG_DESCBC 2
-#define SADB_EALG_3DESCBC 3
-#define SADB_EALG_BFCBC 7
-#define SADB_EALG_NULL 11
-#define SADB_EALG_AESCBC 12
-#define SADB_EALG_MAX 255
-
-#define SADB_X_CALG_NONE 0
-#define SADB_X_CALG_OUI 1
-#define SADB_X_CALG_DEFLATE 2
-#define SADB_X_CALG_LZS 3
-#define SADB_X_CALG_V42BIS 4
-#define SADB_X_CALG_MAX 4
-
-#define SADB_X_TALG_NONE 0
-#define SADB_X_TALG_IPv4_in_IPv4 1
-#define SADB_X_TALG_IPv6_in_IPv4 2
-#define SADB_X_TALG_IPv4_in_IPv6 3
-#define SADB_X_TALG_IPv6_in_IPv6 4
-#define SADB_X_TALG_MAX 4
-
-
-#define SADB_IDENTTYPE_RESERVED 0
-#define SADB_IDENTTYPE_PREFIX 1
-#define SADB_IDENTTYPE_FQDN 2
-#define SADB_IDENTTYPE_USERFQDN 3
-#define SADB_X_IDENTTYPE_CONNECTION 4
-#define SADB_IDENTTYPE_MAX 4
-
-#define SADB_KEY_FLAGS_MAX 0
-#endif /* __PFKEY_V2_H */
diff --git a/src/libcharon/plugins/kernel_netlink/Makefile.am b/src/libcharon/plugins/kernel_netlink/Makefile.am
deleted file mode 100644
index 2bb00ec0d..000000000
--- a/src/libcharon/plugins/kernel_netlink/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-
-INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \
- -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon
-
-AM_CFLAGS = -rdynamic \
--DROUTING_TABLE=${routing_table} \
--DROUTING_TABLE_PRIO=${routing_table_prio}
-
-if MONOLITHIC
-noinst_LTLIBRARIES = libstrongswan-kernel-netlink.la
-else
-plugin_LTLIBRARIES = libstrongswan-kernel-netlink.la
-endif
-
-libstrongswan_kernel_netlink_la_SOURCES = \
- kernel_netlink_plugin.h kernel_netlink_plugin.c \
- kernel_netlink_ipsec.h kernel_netlink_ipsec.c kernel_netlink_net.h kernel_netlink_net.c \
- kernel_netlink_shared.h kernel_netlink_shared.c
-
-libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
deleted file mode 100644
index 019ec93f8..000000000
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ /dev/null
@@ -1,2265 +0,0 @@
-/*
- * Copyright (C) 2006-2009 Tobias Brunner
- * Copyright (C) 2005-2009 Martin Willi
- * Copyright (C) 2008 Andreas Steffen
- * Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
- * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <stdint.h>
-#include <linux/ipsec.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <linux/xfrm.h>
-#include <linux/udp.h>
-#include <unistd.h>
-#include <time.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-
-#include "kernel_netlink_ipsec.h"
-#include "kernel_netlink_shared.h"
-
-#include <daemon.h>
-#include <threading/thread.h>
-#include <threading/mutex.h>
-#include <utils/hashtable.h>
-#include <processing/jobs/callback_job.h>
-#include <processing/jobs/acquire_job.h>
-#include <processing/jobs/migrate_job.h>
-#include <processing/jobs/rekey_child_sa_job.h>
-#include <processing/jobs/delete_child_sa_job.h>
-#include <processing/jobs/update_sa_job.h>
-
-/** required for Linux 2.6.26 kernel and later */
-#ifndef XFRM_STATE_AF_UNSPEC
-#define XFRM_STATE_AF_UNSPEC 32
-#endif
-
-/** from linux/in.h */
-#ifndef IP_XFRM_POLICY
-#define IP_XFRM_POLICY 17
-#endif
-
-/* missing on uclibc */
-#ifndef IPV6_XFRM_POLICY
-#define IPV6_XFRM_POLICY 34
-#endif /*IPV6_XFRM_POLICY*/
-
-/** default priority of installed policies */
-#define PRIO_LOW 3000
-#define PRIO_HIGH 2000
-
-/**
- * map the limit for bytes and packets to XFRM_INF per default
- */
-#define XFRM_LIMIT(x) ((x) == 0 ? XFRM_INF : (x))
-
-/**
- * Create ORable bitfield of XFRM NL groups
- */
-#define XFRMNLGRP(x) (1<<(XFRMNLGRP_##x-1))
-
-/**
- * returns a pointer to the first rtattr following the nlmsghdr *nlh and the
- * 'usual' netlink data x like 'struct xfrm_usersa_info'
- */
-#define XFRM_RTA(nlh, x) ((struct rtattr*)(NLMSG_DATA(nlh) + NLMSG_ALIGN(sizeof(x))))
-/**
- * returns a pointer to the next rtattr following rta.
- * !!! do not use this to parse messages. use RTA_NEXT and RTA_OK instead !!!
- */
-#define XFRM_RTA_NEXT(rta) ((struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len)))
-/**
- * returns the total size of attached rta data
- * (after 'usual' netlink data x like 'struct xfrm_usersa_info')
- */
-#define XFRM_PAYLOAD(nlh, x) NLMSG_PAYLOAD(nlh, sizeof(x))
-
-typedef struct kernel_algorithm_t kernel_algorithm_t;
-
-/**
- * Mapping of IKEv2 kernel identifier to linux crypto API names
- */
-struct kernel_algorithm_t {
- /**
- * Identifier specified in IKEv2
- */
- int ikev2;
-
- /**
- * Name of the algorithm in linux crypto API
- */
- char *name;
-};
-
-ENUM(xfrm_msg_names, XFRM_MSG_NEWSA, XFRM_MSG_MAPPING,
- "XFRM_MSG_NEWSA",
- "XFRM_MSG_DELSA",
- "XFRM_MSG_GETSA",
- "XFRM_MSG_NEWPOLICY",
- "XFRM_MSG_DELPOLICY",
- "XFRM_MSG_GETPOLICY",
- "XFRM_MSG_ALLOCSPI",
- "XFRM_MSG_ACQUIRE",
- "XFRM_MSG_EXPIRE",
- "XFRM_MSG_UPDPOLICY",
- "XFRM_MSG_UPDSA",
- "XFRM_MSG_POLEXPIRE",
- "XFRM_MSG_FLUSHSA",
- "XFRM_MSG_FLUSHPOLICY",
- "XFRM_MSG_NEWAE",
- "XFRM_MSG_GETAE",
- "XFRM_MSG_REPORT",
- "XFRM_MSG_MIGRATE",
- "XFRM_MSG_NEWSADINFO",
- "XFRM_MSG_GETSADINFO",
- "XFRM_MSG_NEWSPDINFO",
- "XFRM_MSG_GETSPDINFO",
- "XFRM_MSG_MAPPING"
-);
-
-ENUM(xfrm_attr_type_names, XFRMA_UNSPEC, XFRMA_KMADDRESS,
- "XFRMA_UNSPEC",
- "XFRMA_ALG_AUTH",
- "XFRMA_ALG_CRYPT",
- "XFRMA_ALG_COMP",
- "XFRMA_ENCAP",
- "XFRMA_TMPL",
- "XFRMA_SA",
- "XFRMA_POLICY",
- "XFRMA_SEC_CTX",
- "XFRMA_LTIME_VAL",
- "XFRMA_REPLAY_VAL",
- "XFRMA_REPLAY_THRESH",
- "XFRMA_ETIMER_THRESH",
- "XFRMA_SRCADDR",
- "XFRMA_COADDR",
- "XFRMA_LASTUSED",
- "XFRMA_POLICY_TYPE",
- "XFRMA_MIGRATE",
- "XFRMA_ALG_AEAD",
- "XFRMA_KMADDRESS"
-);
-
-#define END_OF_LIST -1
-
-/**
- * Algorithms for encryption
- */
-static kernel_algorithm_t encryption_algs[] = {
-/* {ENCR_DES_IV64, "***" }, */
- {ENCR_DES, "des" },
- {ENCR_3DES, "des3_ede" },
-/* {ENCR_RC5, "***" }, */
-/* {ENCR_IDEA, "***" }, */
- {ENCR_CAST, "cast128" },
- {ENCR_BLOWFISH, "blowfish" },
-/* {ENCR_3IDEA, "***" }, */
-/* {ENCR_DES_IV32, "***" }, */
- {ENCR_NULL, "cipher_null" },
- {ENCR_AES_CBC, "aes" },
- {ENCR_AES_CTR, "rfc3686(ctr(aes))" },
- {ENCR_AES_CCM_ICV8, "rfc4309(ccm(aes))" },
- {ENCR_AES_CCM_ICV12, "rfc4309(ccm(aes))" },
- {ENCR_AES_CCM_ICV16, "rfc4309(ccm(aes))" },
- {ENCR_AES_GCM_ICV8, "rfc4106(gcm(aes))" },
- {ENCR_AES_GCM_ICV12, "rfc4106(gcm(aes))" },
- {ENCR_AES_GCM_ICV16, "rfc4106(gcm(aes))" },
- {ENCR_NULL_AUTH_AES_GMAC, "rfc4543(gcm(aes))" },
- {ENCR_CAMELLIA_CBC, "cbc(camellia)" },
-/* {ENCR_CAMELLIA_CTR, "***" }, */
-/* {ENCR_CAMELLIA_CCM_ICV8, "***" }, */
-/* {ENCR_CAMELLIA_CCM_ICV12, "***" }, */
-/* {ENCR_CAMELLIA_CCM_ICV16, "***" }, */
- {END_OF_LIST, NULL }
-};
-
-/**
- * Algorithms for integrity protection
- */
-static kernel_algorithm_t integrity_algs[] = {
- {AUTH_HMAC_MD5_96, "md5" },
- {AUTH_HMAC_SHA1_96, "sha1" },
- {AUTH_HMAC_SHA2_256_96, "sha256" },
- {AUTH_HMAC_SHA2_256_128, "hmac(sha256)" },
- {AUTH_HMAC_SHA2_384_192, "hmac(sha384)" },
- {AUTH_HMAC_SHA2_512_256, "hmac(sha512)" },
-/* {AUTH_DES_MAC, "***" }, */
-/* {AUTH_KPDK_MD5, "***" }, */
- {AUTH_AES_XCBC_96, "xcbc(aes)" },
- {END_OF_LIST, NULL }
-};
-
-/**
- * Algorithms for IPComp
- */
-static kernel_algorithm_t compression_algs[] = {
-/* {IPCOMP_OUI, "***" }, */
- {IPCOMP_DEFLATE, "deflate" },
- {IPCOMP_LZS, "lzs" },
- {IPCOMP_LZJH, "lzjh" },
- {END_OF_LIST, NULL }
-};
-
-/**
- * Look up a kernel algorithm name and its key size
- */
-static char* lookup_algorithm(kernel_algorithm_t *list, int ikev2)
-{
- while (list->ikev2 != END_OF_LIST)
- {
- if (list->ikev2 == ikev2)
- {
- return list->name;
- }
- list++;
- }
- return NULL;
-}
-
-typedef struct route_entry_t route_entry_t;
-
-/**
- * installed routing entry
- */
-struct route_entry_t {
- /** Name of the interface the route is bound to */
- char *if_name;
-
- /** Source ip of the route */
- host_t *src_ip;
-
- /** gateway for this route */
- host_t *gateway;
-
- /** Destination net */
- chunk_t dst_net;
-
- /** Destination net prefixlen */
- u_int8_t prefixlen;
-};
-
-/**
- * destroy an route_entry_t object
- */
-static void route_entry_destroy(route_entry_t *this)
-{
- free(this->if_name);
- this->src_ip->destroy(this->src_ip);
- DESTROY_IF(this->gateway);
- chunk_free(&this->dst_net);
- free(this);
-}
-
-typedef struct policy_entry_t policy_entry_t;
-
-/**
- * installed kernel policy.
- */
-struct policy_entry_t {
-
- /** direction of this policy: in, out, forward */
- u_int8_t direction;
-
- /** parameters of installed policy */
- struct xfrm_selector sel;
-
- /** optional mark */
- u_int32_t mark;
-
- /** associated route installed for this policy */
- route_entry_t *route;
-
- /** by how many CHILD_SA's this policy is used */
- u_int refcount;
-};
-
-/**
- * Hash function for policy_entry_t objects
- */
-static u_int policy_hash(policy_entry_t *key)
-{
- chunk_t chunk = chunk_create((void*)&key->sel,
- sizeof(struct xfrm_selector) + sizeof(u_int32_t));
- return chunk_hash(chunk);
-}
-
-/**
- * Equality function for policy_entry_t objects
- */
-static bool policy_equals(policy_entry_t *key, policy_entry_t *other_key)
-{
- return memeq(&key->sel, &other_key->sel,
- sizeof(struct xfrm_selector) + sizeof(u_int32_t)) &&
- key->direction == other_key->direction;
-}
-
-typedef struct private_kernel_netlink_ipsec_t private_kernel_netlink_ipsec_t;
-
-/**
- * Private variables and functions of kernel_netlink class.
- */
-struct private_kernel_netlink_ipsec_t {
- /**
- * Public part of the kernel_netlink_t object.
- */
- kernel_netlink_ipsec_t public;
-
- /**
- * mutex to lock access to various lists
- */
- mutex_t *mutex;
-
- /**
- * Hash table of installed policies (policy_entry_t)
- */
- hashtable_t *policies;
-
- /**
- * job receiving netlink events
- */
- callback_job_t *job;
-
- /**
- * Netlink xfrm socket (IPsec)
- */
- netlink_socket_t *socket_xfrm;
-
- /**
- * netlink xfrm socket to receive acquire and expire events
- */
- int socket_xfrm_events;
-
- /**
- * whether to install routes along policies
- */
- bool install_routes;
-};
-
-/**
- * convert a IKEv2 specific protocol identifier to the kernel one
- */
-static u_int8_t proto_ike2kernel(protocol_id_t proto)
-{
- switch (proto)
- {
- case PROTO_ESP:
- return IPPROTO_ESP;
- case PROTO_AH:
- return IPPROTO_AH;
- default:
- return proto;
- }
-}
-
-/**
- * reverse of ike2kernel
- */
-static protocol_id_t proto_kernel2ike(u_int8_t proto)
-{
- switch (proto)
- {
- case IPPROTO_ESP:
- return PROTO_ESP;
- case IPPROTO_AH:
- return PROTO_AH;
- default:
- return proto;
- }
-}
-
-/**
- * convert the general ipsec mode to the one defined in xfrm.h
- */
-static u_int8_t mode2kernel(ipsec_mode_t mode)
-{
- switch (mode)
- {
- case MODE_TRANSPORT:
- return XFRM_MODE_TRANSPORT;
- case MODE_TUNNEL:
- return XFRM_MODE_TUNNEL;
- case MODE_BEET:
- return XFRM_MODE_BEET;
- default:
- return mode;
- }
-}
-
-/**
- * convert a host_t to a struct xfrm_address
- */
-static void host2xfrm(host_t *host, xfrm_address_t *xfrm)
-{
- chunk_t chunk = host->get_address(host);
- memcpy(xfrm, chunk.ptr, min(chunk.len, sizeof(xfrm_address_t)));
-}
-
-/**
- * convert a struct xfrm_address to a host_t
- */
-static host_t* xfrm2host(int family, xfrm_address_t *xfrm, u_int16_t port)
-{
- chunk_t chunk;
-
- switch (family)
- {
- case AF_INET:
- chunk = chunk_create((u_char*)&xfrm->a4, sizeof(xfrm->a4));
- break;
- case AF_INET6:
- chunk = chunk_create((u_char*)&xfrm->a6, sizeof(xfrm->a6));
- break;
- default:
- return NULL;
- }
- return host_create_from_chunk(family, chunk, ntohs(port));
-}
-
-/**
- * convert a traffic selector address range to subnet and its mask.
- */
-static void ts2subnet(traffic_selector_t* ts,
- xfrm_address_t *net, u_int8_t *mask)
-{
- host_t *net_host;
- chunk_t net_chunk;
-
- ts->to_subnet(ts, &net_host, mask);
- net_chunk = net_host->get_address(net_host);
- memcpy(net, net_chunk.ptr, net_chunk.len);
- net_host->destroy(net_host);
-}
-
-/**
- * convert a traffic selector port range to port/portmask
- */
-static void ts2ports(traffic_selector_t* ts,
- u_int16_t *port, u_int16_t *mask)
-{
- /* linux does not seem to accept complex portmasks. Only
- * any or a specific port is allowed. We set to any, if we have
- * a port range, or to a specific, if we have one port only.
- */
- u_int16_t from, to;
-
- from = ts->get_from_port(ts);
- to = ts->get_to_port(ts);
-
- if (from == to)
- {
- *port = htons(from);
- *mask = ~0;
- }
- else
- {
- *port = 0;
- *mask = 0;
- }
-}
-
-/**
- * convert a pair of traffic_selectors to a xfrm_selector
- */
-static struct xfrm_selector ts2selector(traffic_selector_t *src,
- traffic_selector_t *dst)
-{
- struct xfrm_selector sel;
-
- memset(&sel, 0, sizeof(sel));
- sel.family = (src->get_type(src) == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6;
- /* src or dest proto may be "any" (0), use more restrictive one */
- sel.proto = max(src->get_protocol(src), dst->get_protocol(dst));
- ts2subnet(dst, &sel.daddr, &sel.prefixlen_d);
- ts2subnet(src, &sel.saddr, &sel.prefixlen_s);
- ts2ports(dst, &sel.dport, &sel.dport_mask);
- ts2ports(src, &sel.sport, &sel.sport_mask);
- sel.ifindex = 0;
- sel.user = 0;
-
- return sel;
-}
-
-/**
- * convert a xfrm_selector to a src|dst traffic_selector
- */
-static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src)
-{
- u_char *addr;
- u_int8_t prefixlen;
- u_int16_t port = 0;
- host_t *host = NULL;
-
- if (src)
- {
- addr = (u_char*)&sel->saddr;
- prefixlen = sel->prefixlen_s;
- if (sel->sport_mask)
- {
- port = htons(sel->sport);
- }
- }
- else
- {
- addr = (u_char*)&sel->daddr;
- prefixlen = sel->prefixlen_d;
- if (sel->dport_mask)
- {
- port = htons(sel->dport);
- }
- }
-
- /* The Linux 2.6 kernel does not set the selector's family field,
- * so as a kludge we additionally test the prefix length.
- */
- if (sel->family == AF_INET || sel->prefixlen_s == 32)
- {
- host = host_create_from_chunk(AF_INET, chunk_create(addr, 4), 0);
- }
- else if (sel->family == AF_INET6 || sel->prefixlen_s == 128)
- {
- host = host_create_from_chunk(AF_INET6, chunk_create(addr, 16), 0);
- }
-
- if (host)
- {
- return traffic_selector_create_from_subnet(host, prefixlen,
- sel->proto, port);
- }
- return NULL;
-}
-
-/**
- * process a XFRM_MSG_ACQUIRE from kernel
- */
-static void process_acquire(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr)
-{
- u_int32_t reqid = 0;
- int proto = 0;
- traffic_selector_t *src_ts, *dst_ts;
- struct xfrm_user_acquire *acquire;
- struct rtattr *rta;
- size_t rtasize;
- job_t *job;
-
- acquire = (struct xfrm_user_acquire*)NLMSG_DATA(hdr);
- rta = XFRM_RTA(hdr, struct xfrm_user_acquire);
- rtasize = XFRM_PAYLOAD(hdr, struct xfrm_user_acquire);
-
- DBG2(DBG_KNL, "received a XFRM_MSG_ACQUIRE");
-
- while (RTA_OK(rta, rtasize))
- {
- DBG2(DBG_KNL, " %N", xfrm_attr_type_names, rta->rta_type);
-
- if (rta->rta_type == XFRMA_TMPL)
- {
- struct xfrm_user_tmpl* tmpl;
-
- tmpl = (struct xfrm_user_tmpl*)RTA_DATA(rta);
- reqid = tmpl->reqid;
- proto = tmpl->id.proto;
- }
- rta = RTA_NEXT(rta, rtasize);
- }
- switch (proto)
- {
- case 0:
- case IPPROTO_ESP:
- case IPPROTO_AH:
- break;
- default:
- /* acquire for AH/ESP only, not for IPCOMP */
- return;
- }
- src_ts = selector2ts(&acquire->sel, TRUE);
- dst_ts = selector2ts(&acquire->sel, FALSE);
- DBG1(DBG_KNL, "creating acquire job for policy %R === %R with reqid {%u}",
- src_ts, dst_ts, reqid);
- job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts);
- charon->processor->queue_job(charon->processor, job);
-}
-
-/**
- * process a XFRM_MSG_EXPIRE from kernel
- */
-static void process_expire(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr)
-{
- job_t *job;
- protocol_id_t protocol;
- u_int32_t spi, reqid;
- struct xfrm_user_expire *expire;
-
- expire = (struct xfrm_user_expire*)NLMSG_DATA(hdr);
- protocol = proto_kernel2ike(expire->state.id.proto);
- spi = expire->state.id.spi;
- reqid = expire->state.reqid;
-
- DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE");
-
- if (protocol != PROTO_ESP && protocol != PROTO_AH)
- {
- DBG2(DBG_KNL, "ignoring XFRM_MSG_EXPIRE for SA with SPI %.8x and reqid {%u} "
- "which is not a CHILD_SA", ntohl(spi), reqid);
- return;
- }
-
- DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%d}",
- expire->hard ? "delete" : "rekey", protocol_id_names,
- protocol, ntohl(spi), reqid);
- if (expire->hard)
- {
- job = (job_t*)delete_child_sa_job_create(reqid, protocol, spi);
- }
- else
- {
- job = (job_t*)rekey_child_sa_job_create(reqid, protocol, spi);
- }
- charon->processor->queue_job(charon->processor, job);
-}
-
-/**
- * process a XFRM_MSG_MIGRATE from kernel
- */
-static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr)
-{
- traffic_selector_t *src_ts, *dst_ts;
- host_t *local = NULL, *remote = NULL;
- host_t *old_src = NULL, *old_dst = NULL;
- host_t *new_src = NULL, *new_dst = NULL;
- struct xfrm_userpolicy_id *policy_id;
- struct rtattr *rta;
- size_t rtasize;
- u_int32_t reqid = 0;
- policy_dir_t dir;
- job_t *job;
-
- policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr);
- rta = XFRM_RTA(hdr, struct xfrm_userpolicy_id);
- rtasize = XFRM_PAYLOAD(hdr, struct xfrm_userpolicy_id);
-
- DBG2(DBG_KNL, "received a XFRM_MSG_MIGRATE");
-
- src_ts = selector2ts(&policy_id->sel, TRUE);
- dst_ts = selector2ts(&policy_id->sel, FALSE);
- dir = (policy_dir_t)policy_id->dir;
-
- DBG2(DBG_KNL, " policy: %R === %R %N", src_ts, dst_ts, policy_dir_names);
-
- while (RTA_OK(rta, rtasize))
- {
- DBG2(DBG_KNL, " %N", xfrm_attr_type_names, rta->rta_type);
- if (rta->rta_type == XFRMA_KMADDRESS)
- {
- struct xfrm_user_kmaddress *kmaddress;
-
- kmaddress = (struct xfrm_user_kmaddress*)RTA_DATA(rta);
- local = xfrm2host(kmaddress->family, &kmaddress->local, 0);
- remote = xfrm2host(kmaddress->family, &kmaddress->remote, 0);
- DBG2(DBG_KNL, " kmaddress: %H...%H", local, remote);
- }
- else if (rta->rta_type == XFRMA_MIGRATE)
- {
- struct xfrm_user_migrate *migrate;
- protocol_id_t proto;
-
- migrate = (struct xfrm_user_migrate*)RTA_DATA(rta);
- old_src = xfrm2host(migrate->old_family, &migrate->old_saddr, 0);
- old_dst = xfrm2host(migrate->old_family, &migrate->old_daddr, 0);
- new_src = xfrm2host(migrate->new_family, &migrate->new_saddr, 0);
- new_dst = xfrm2host(migrate->new_family, &migrate->new_daddr, 0);
- proto = proto_kernel2ike(migrate->proto);
- reqid = migrate->reqid;
- DBG2(DBG_KNL, " migrate %N %H...%H to %H...%H, reqid {%u}",
- protocol_id_names, proto, old_src, old_dst,
- new_src, new_dst, reqid);
- DESTROY_IF(old_src);
- DESTROY_IF(old_dst);
- DESTROY_IF(new_src);
- DESTROY_IF(new_dst);
- }
- rta = RTA_NEXT(rta, rtasize);
- }
-
- if (src_ts && dst_ts && local && remote)
- {
- DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}",
- src_ts, dst_ts, policy_dir_names, dir, reqid, local);
- job = (job_t*)migrate_job_create(reqid, src_ts, dst_ts, dir,
- local, remote);
- charon->processor->queue_job(charon->processor, job);
- }
- else
- {
- DESTROY_IF(src_ts);
- DESTROY_IF(dst_ts);
- DESTROY_IF(local);
- DESTROY_IF(remote);
- }
-}
-
-/**
- * process a XFRM_MSG_MAPPING from kernel
- */
-static void process_mapping(private_kernel_netlink_ipsec_t *this,
- struct nlmsghdr *hdr)
-{
- job_t *job;
- u_int32_t spi, reqid;
- struct xfrm_user_mapping *mapping;
- host_t *host;
-
- mapping = (struct xfrm_user_mapping*)NLMSG_DATA(hdr);
- spi = mapping->id.spi;
- reqid = mapping->reqid;
-
- DBG2(DBG_KNL, "received a XFRM_MSG_MAPPING");
-
- if (proto_kernel2ike(mapping->id.proto) == PROTO_ESP)
- {
- host = xfrm2host(mapping->id.family, &mapping->new_saddr,
- mapping->new_sport);
- if (host)
- {
- DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and "
- "reqid {%u} changed, queuing update job", ntohl(spi), reqid);
- job = (job_t*)update_sa_job_create(reqid, host);
- charon->processor->queue_job(charon->processor, job);
- }
- }
-}
-
-/**
- * Receives events from kernel
- */
-static job_requeue_t receive_events(private_kernel_netlink_ipsec_t *this)
-{
- char response[1024];
- struct nlmsghdr *hdr = (struct nlmsghdr*)response;
- struct sockaddr_nl addr;
- socklen_t addr_len = sizeof(addr);
- int len;
- bool oldstate;
-
- oldstate = thread_cancelability(TRUE);
- len = recvfrom(this->socket_xfrm_events, response, sizeof(response), 0,
- (struct sockaddr*)&addr, &addr_len);
- thread_cancelability(oldstate);
-
- if (len < 0)
- {
- switch (errno)
- {
- case EINTR:
- /* interrupted, try again */
- return JOB_REQUEUE_DIRECT;
- case EAGAIN:
- /* no data ready, select again */
- return JOB_REQUEUE_DIRECT;
- default:
- DBG1(DBG_KNL, "unable to receive from xfrm event socket");
- sleep(1);
- return JOB_REQUEUE_FAIR;
- }
- }
-
- if (addr.nl_pid != 0)
- { /* not from kernel. not interested, try another one */
- return JOB_REQUEUE_DIRECT;
- }
-
- while (NLMSG_OK(hdr, len))
- {
- switch (hdr->nlmsg_type)
- {
- case XFRM_MSG_ACQUIRE:
- process_acquire(this, hdr);
- break;
- case XFRM_MSG_EXPIRE:
- process_expire(this, hdr);
- break;
- case XFRM_MSG_MIGRATE:
- process_migrate(this, hdr);
- break;
- case XFRM_MSG_MAPPING:
- process_mapping(this, hdr);
- break;
- default:
- DBG1(DBG_KNL, "received unknown event from xfrm event socket: %d", hdr->nlmsg_type);
- break;
- }
- hdr = NLMSG_NEXT(hdr, len);
- }
- return JOB_REQUEUE_DIRECT;
-}
-
-/**
- * Get an SPI for a specific protocol from the kernel.
- */
-static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this,
- host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max,
- u_int32_t reqid, u_int32_t *spi)
-{
- netlink_buf_t request;
- struct nlmsghdr *hdr, *out;
- struct xfrm_userspi_info *userspi;
- u_int32_t received_spi = 0;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST;
- hdr->nlmsg_type = XFRM_MSG_ALLOCSPI;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userspi_info));
-
- userspi = (struct xfrm_userspi_info*)NLMSG_DATA(hdr);
- host2xfrm(src, &userspi->info.saddr);
- host2xfrm(dst, &userspi->info.id.daddr);
- userspi->info.id.proto = proto;
- userspi->info.mode = XFRM_MODE_TUNNEL;
- userspi->info.reqid = reqid;
- userspi->info.family = src->get_family(src);
- userspi->min = min;
- userspi->max = max;
-
- if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
- {
- hdr = out;
- while (NLMSG_OK(hdr, len))
- {
- switch (hdr->nlmsg_type)
- {
- case XFRM_MSG_NEWSA:
- {
- struct xfrm_usersa_info* usersa = NLMSG_DATA(hdr);
- received_spi = usersa->id.spi;
- break;
- }
- case NLMSG_ERROR:
- {
- struct nlmsgerr *err = NLMSG_DATA(hdr);
-
- DBG1(DBG_KNL, "allocating SPI failed: %s (%d)",
- strerror(-err->error), -err->error);
- break;
- }
- default:
- hdr = NLMSG_NEXT(hdr, len);
- continue;
- case NLMSG_DONE:
- break;
- }
- break;
- }
- free(out);
- }
-
- if (received_spi == 0)
- {
- return FAILED;
- }
-
- *spi = received_spi;
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, get_spi, status_t,
- private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi)
-{
- DBG2(DBG_KNL, "getting SPI for reqid {%u}", reqid);
-
- if (get_spi_internal(this, src, dst, proto_ike2kernel(protocol),
- 0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to get SPI for reqid {%u}", reqid);
- return FAILED;
- }
-
- DBG2(DBG_KNL, "got SPI %.8x for reqid {%u}", ntohl(*spi), reqid);
-
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, get_cpi, status_t,
- private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
-{
- u_int32_t received_spi = 0;
-
- DBG2(DBG_KNL, "getting CPI for reqid {%u}", reqid);
-
- if (get_spi_internal(this, src, dst,
- IPPROTO_COMP, 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to get CPI for reqid {%u}", reqid);
- return FAILED;
- }
-
- *cpi = htons((u_int16_t)ntohl(received_spi));
-
- DBG2(DBG_KNL, "got CPI %.4x for reqid {%u}", ntohs(*cpi), reqid);
-
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, add_sa, status_t,
- private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int32_t reqid, mark_t mark,
- lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
- u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool encap, bool inbound,
- traffic_selector_t* src_ts, traffic_selector_t* dst_ts)
-{
- netlink_buf_t request;
- char *alg_name;
- struct nlmsghdr *hdr;
- struct xfrm_usersa_info *sa;
- u_int16_t icv_size = 64;
-
- /* if IPComp is used, we install an additional IPComp SA. if the cpi is 0
- * we are in the recursive call below */
- if (ipcomp != IPCOMP_NONE && cpi != 0)
- {
- lifetime_cfg_t lft = {{0,0,0},{0,0,0},{0,0,0}};
- add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
- &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, chunk_empty,
- mode, ipcomp, 0, FALSE, inbound, NULL, NULL);
- ipcomp = IPCOMP_NONE;
- /* use transport mode ESP SA, IPComp uses tunnel mode */
- mode = MODE_TRANSPORT;
- }
-
- memset(&request, 0, sizeof(request));
-
- if (mark.value)
- {
- DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u} "
- "(mark %u/0x%8x)", ntohl(spi), reqid, mark.value, mark.mask);
- }
- else
- {
- DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}",
- ntohl(spi), reqid);
- }
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- hdr->nlmsg_type = inbound ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
-
- sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr);
- host2xfrm(src, &sa->saddr);
- host2xfrm(dst, &sa->id.daddr);
- sa->id.spi = spi;
- sa->id.proto = proto_ike2kernel(protocol);
- sa->family = src->get_family(src);
- sa->mode = mode2kernel(mode);
- switch (mode)
- {
- case MODE_TUNNEL:
- sa->flags |= XFRM_STATE_AF_UNSPEC;
- break;
- case MODE_BEET:
- if(src_ts && dst_ts)
- {
- sa->sel = ts2selector(src_ts, dst_ts);
- }
- break;
- default:
- break;
- }
-
- sa->replay_window = (protocol == IPPROTO_COMP) ? 0 : 32;
- sa->reqid = reqid;
- sa->lft.soft_byte_limit = XFRM_LIMIT(lifetime->bytes.rekey);
- sa->lft.hard_byte_limit = XFRM_LIMIT(lifetime->bytes.life);
- sa->lft.soft_packet_limit = XFRM_LIMIT(lifetime->packets.rekey);
- sa->lft.hard_packet_limit = XFRM_LIMIT(lifetime->packets.life);
- /* we use lifetimes since added, not since used */
- sa->lft.soft_add_expires_seconds = lifetime->time.rekey;
- sa->lft.hard_add_expires_seconds = lifetime->time.life;
- sa->lft.soft_use_expires_seconds = 0;
- sa->lft.hard_use_expires_seconds = 0;
-
- struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_usersa_info);
-
- switch (enc_alg)
- {
- case ENCR_UNDEFINED:
- /* no encryption */
- break;
- case ENCR_AES_CCM_ICV16:
- case ENCR_AES_GCM_ICV16:
- case ENCR_NULL_AUTH_AES_GMAC:
- case ENCR_CAMELLIA_CCM_ICV16:
- icv_size += 32;
- /* FALL */
- case ENCR_AES_CCM_ICV12:
- case ENCR_AES_GCM_ICV12:
- case ENCR_CAMELLIA_CCM_ICV12:
- icv_size += 32;
- /* FALL */
- case ENCR_AES_CCM_ICV8:
- case ENCR_AES_GCM_ICV8:
- case ENCR_CAMELLIA_CCM_ICV8:
- {
- struct xfrm_algo_aead *algo;
-
- alg_name = lookup_algorithm(encryption_algs, enc_alg);
- if (alg_name == NULL)
- {
- DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- encryption_algorithm_names, enc_alg);
- return FAILED;
- }
- DBG2(DBG_KNL, " using encryption algorithm %N with key size %d",
- encryption_algorithm_names, enc_alg, enc_key.len * 8);
-
- rthdr->rta_type = XFRMA_ALG_AEAD;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo_aead) + enc_key.len);
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- algo = (struct xfrm_algo_aead*)RTA_DATA(rthdr);
- algo->alg_key_len = enc_key.len * 8;
- algo->alg_icv_len = icv_size;
- strcpy(algo->alg_name, alg_name);
- memcpy(algo->alg_key, enc_key.ptr, enc_key.len);
-
- rthdr = XFRM_RTA_NEXT(rthdr);
- break;
- }
- default:
- {
- struct xfrm_algo *algo;
-
- alg_name = lookup_algorithm(encryption_algs, enc_alg);
- if (alg_name == NULL)
- {
- DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- encryption_algorithm_names, enc_alg);
- return FAILED;
- }
- DBG2(DBG_KNL, " using encryption algorithm %N with key size %d",
- encryption_algorithm_names, enc_alg, enc_key.len * 8);
-
- rthdr->rta_type = XFRMA_ALG_CRYPT;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + enc_key.len);
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- algo = (struct xfrm_algo*)RTA_DATA(rthdr);
- algo->alg_key_len = enc_key.len * 8;
- strcpy(algo->alg_name, alg_name);
- memcpy(algo->alg_key, enc_key.ptr, enc_key.len);
-
- rthdr = XFRM_RTA_NEXT(rthdr);
- }
- }
-
- if (int_alg != AUTH_UNDEFINED)
- {
- alg_name = lookup_algorithm(integrity_algs, int_alg);
- if (alg_name == NULL)
- {
- DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- integrity_algorithm_names, int_alg);
- return FAILED;
- }
- DBG2(DBG_KNL, " using integrity algorithm %N with key size %d",
- integrity_algorithm_names, int_alg, int_key.len * 8);
-
- if (int_alg == AUTH_HMAC_SHA2_256_128)
- {
- struct xfrm_algo_auth* algo;
-
- /* the kernel uses SHA256 with 96 bit truncation by default,
- * use specified truncation size supported by newer kernels */
- rthdr->rta_type = XFRMA_ALG_AUTH_TRUNC;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo_auth) + int_key.len);
-
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- algo = (struct xfrm_algo_auth*)RTA_DATA(rthdr);
- algo->alg_key_len = int_key.len * 8;
- algo->alg_trunc_len = 128;
- strcpy(algo->alg_name, alg_name);
- memcpy(algo->alg_key, int_key.ptr, int_key.len);
- }
- else
- {
- struct xfrm_algo* algo;
-
- rthdr->rta_type = XFRMA_ALG_AUTH;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo) + int_key.len);
-
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- algo = (struct xfrm_algo*)RTA_DATA(rthdr);
- algo->alg_key_len = int_key.len * 8;
- strcpy(algo->alg_name, alg_name);
- memcpy(algo->alg_key, int_key.ptr, int_key.len);
- }
- rthdr = XFRM_RTA_NEXT(rthdr);
- }
-
- if (ipcomp != IPCOMP_NONE)
- {
- rthdr->rta_type = XFRMA_ALG_COMP;
- alg_name = lookup_algorithm(compression_algs, ipcomp);
- if (alg_name == NULL)
- {
- DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- ipcomp_transform_names, ipcomp);
- return FAILED;
- }
- DBG2(DBG_KNL, " using compression algorithm %N",
- ipcomp_transform_names, ipcomp);
-
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo));
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- struct xfrm_algo* algo = (struct xfrm_algo*)RTA_DATA(rthdr);
- algo->alg_key_len = 0;
- strcpy(algo->alg_name, alg_name);
-
- rthdr = XFRM_RTA_NEXT(rthdr);
- }
-
- if (encap)
- {
- struct xfrm_encap_tmpl *tmpl;
-
- rthdr->rta_type = XFRMA_ENCAP;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_encap_tmpl));
-
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rthdr);
- tmpl->encap_type = UDP_ENCAP_ESPINUDP;
- tmpl->encap_sport = htons(src->get_port(src));
- tmpl->encap_dport = htons(dst->get_port(dst));
- memset(&tmpl->encap_oa, 0, sizeof (xfrm_address_t));
- /* encap_oa could probably be derived from the
- * traffic selectors [rfc4306, p39]. In the netlink kernel implementation
- * pluto does the same as we do here but it uses encap_oa in the
- * pfkey implementation. BUT as /usr/src/linux/net/key/af_key.c indicates
- * the kernel ignores it anyway
- * -> does that mean that NAT-T encap doesn't work in transport mode?
- * No. The reason the kernel ignores NAT-OA is that it recomputes
- * (or, rather, just ignores) the checksum. If packets pass
- * the IPsec checks it marks them "checksum ok" so OA isn't needed. */
- rthdr = XFRM_RTA_NEXT(rthdr);
- }
-
- if (mark.value)
- {
- struct xfrm_mark *mrk;
-
- rthdr->rta_type = XFRMA_MARK;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
-
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
- mrk->v = mark.value;
- mrk->m = mark.mask;
- rthdr = XFRM_RTA_NEXT(rthdr);
- }
-
- if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
- {
- if (mark.value)
- {
- DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x "
- "(mark %u/0x%8x)", ntohl(spi), mark.value, mark.mask);
- }
- else
- {
- DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi));
- }
- return FAILED;
- }
- return SUCCESS;
-}
-
-/**
- * Get the replay state (i.e. sequence numbers) of an SA.
- */
-static status_t get_replay_state(private_kernel_netlink_ipsec_t *this,
- u_int32_t spi, protocol_id_t protocol, host_t *dst,
- struct xfrm_replay_state *replay)
-{
- netlink_buf_t request;
- struct nlmsghdr *hdr, *out = NULL;
- struct xfrm_aevent_id *out_aevent = NULL, *aevent_id;
- size_t len;
- struct rtattr *rta;
- size_t rtasize;
-
- memset(&request, 0, sizeof(request));
-
- DBG2(DBG_KNL, "querying replay state from SAD entry with SPI %.8x", ntohl(spi));
-
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST;
- hdr->nlmsg_type = XFRM_MSG_GETAE;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_aevent_id));
-
- aevent_id = (struct xfrm_aevent_id*)NLMSG_DATA(hdr);
- aevent_id->flags = XFRM_AE_RVAL;
-
- host2xfrm(dst, &aevent_id->sa_id.daddr);
- aevent_id->sa_id.spi = spi;
- aevent_id->sa_id.proto = proto_ike2kernel(protocol);
- aevent_id->sa_id.family = dst->get_family(dst);
-
- if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
- {
- hdr = out;
- while (NLMSG_OK(hdr, len))
- {
- switch (hdr->nlmsg_type)
- {
- case XFRM_MSG_NEWAE:
- {
- out_aevent = NLMSG_DATA(hdr);
- break;
- }
- case NLMSG_ERROR:
- {
- struct nlmsgerr *err = NLMSG_DATA(hdr);
- DBG1(DBG_KNL, "querying replay state from SAD entry failed: %s (%d)",
- strerror(-err->error), -err->error);
- break;
- }
- default:
- hdr = NLMSG_NEXT(hdr, len);
- continue;
- case NLMSG_DONE:
- break;
- }
- break;
- }
- }
-
- if (out_aevent == NULL)
- {
- DBG1(DBG_KNL, "unable to query replay state from SAD entry with SPI %.8x",
- ntohl(spi));
- free(out);
- return FAILED;
- }
-
- rta = XFRM_RTA(out, struct xfrm_aevent_id);
- rtasize = XFRM_PAYLOAD(out, struct xfrm_aevent_id);
- while(RTA_OK(rta, rtasize))
- {
- if (rta->rta_type == XFRMA_REPLAY_VAL &&
- RTA_PAYLOAD(rta) == sizeof(struct xfrm_replay_state))
- {
- memcpy(replay, RTA_DATA(rta), RTA_PAYLOAD(rta));
- free(out);
- return SUCCESS;
- }
- rta = RTA_NEXT(rta, rtasize);
- }
-
- DBG1(DBG_KNL, "unable to query replay state from SAD entry with SPI %.8x",
- ntohl(spi));
- free(out);
- return FAILED;
-}
-
-METHOD(kernel_ipsec_t, query_sa, status_t,
- private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
-{
- netlink_buf_t request;
- struct nlmsghdr *out = NULL, *hdr;
- struct xfrm_usersa_id *sa_id;
- struct xfrm_usersa_info *sa = NULL;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- if (mark.value)
- {
- DBG2(DBG_KNL, "querying SAD entry with SPI %.8x (mark %u/0x%8x)",
- ntohl(spi), mark.value, mark.mask);
- }
- else
- {
- DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi));
- }
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST;
- hdr->nlmsg_type = XFRM_MSG_GETSA;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
-
- sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
- host2xfrm(dst, &sa_id->daddr);
- sa_id->spi = spi;
- sa_id->proto = proto_ike2kernel(protocol);
- sa_id->family = dst->get_family(dst);
-
- if (mark.value)
- {
- struct xfrm_mark *mrk;
- struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_usersa_id);
-
- rthdr->rta_type = XFRMA_MARK;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
- mrk->v = mark.value;
- mrk->m = mark.mask;
- }
-
- if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
- {
- hdr = out;
- while (NLMSG_OK(hdr, len))
- {
- switch (hdr->nlmsg_type)
- {
- case XFRM_MSG_NEWSA:
- {
- sa = (struct xfrm_usersa_info*)NLMSG_DATA(hdr);
- break;
- }
- case NLMSG_ERROR:
- {
- struct nlmsgerr *err = NLMSG_DATA(hdr);
-
- if (mark.value)
- {
- DBG1(DBG_KNL, "querying SAD entry with SPI %.8x "
- "(mark %u/0x%8x) failed: %s (%d)",
- ntohl(spi), mark.value, mark.mask,
- strerror(-err->error), -err->error);
- }
- else
- {
- DBG1(DBG_KNL, "querying SAD entry with SPI %.8x "
- "failed: %s (%d)", ntohl(spi),
- strerror(-err->error), -err->error);
- }
- break;
- }
- default:
- hdr = NLMSG_NEXT(hdr, len);
- continue;
- case NLMSG_DONE:
- break;
- }
- break;
- }
- }
-
- if (sa == NULL)
- {
- DBG2(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi));
- free(out);
- return FAILED;
- }
- *bytes = sa->curlft.bytes;
-
- free(out);
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, del_sa, status_t,
- private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark)
-{
- netlink_buf_t request;
- struct nlmsghdr *hdr;
- struct xfrm_usersa_id *sa_id;
-
- /* if IPComp was used, we first delete the additional IPComp SA */
- if (cpi)
- {
- del_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, 0, mark);
- }
-
- memset(&request, 0, sizeof(request));
-
- if (mark.value)
- {
- DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x (mark %u/0x%8x)",
- ntohl(spi), mark.value, mark.mask);
- }
- else
- {
- DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi));
- }
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- hdr->nlmsg_type = XFRM_MSG_DELSA;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
-
- sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
- host2xfrm(dst, &sa_id->daddr);
- sa_id->spi = spi;
- sa_id->proto = proto_ike2kernel(protocol);
- sa_id->family = dst->get_family(dst);
-
- if (mark.value)
- {
- struct xfrm_mark *mrk;
- struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_usersa_id);
-
- rthdr->rta_type = XFRMA_MARK;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
- mrk->v = mark.value;
- mrk->m = mark.mask;
- }
-
- if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
- {
- if (mark.value)
- {
- DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x "
- "(mark %u/0x%8x)", ntohl(spi), mark.value, mark.mask);
- }
- else
- {
- DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi));
- }
- return FAILED;
- }
- if (mark.value)
- {
- DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x (mark %u/0x%8x)",
- ntohl(spi), mark.value, mark.mask);
- }
- else
- {
- DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi));
- }
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, update_sa, status_t,
- private_kernel_netlink_ipsec_t *this, u_int32_t spi, protocol_id_t protocol,
- u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
- bool old_encap, bool new_encap, mark_t mark)
-{
- netlink_buf_t request;
- u_char *pos;
- struct nlmsghdr *hdr, *out = NULL;
- struct xfrm_usersa_id *sa_id;
- struct xfrm_usersa_info *out_sa = NULL, *sa;
- size_t len;
- struct rtattr *rta;
- size_t rtasize;
- struct xfrm_encap_tmpl* tmpl = NULL;
- bool got_replay_state = FALSE;
- struct xfrm_replay_state replay;
-
- /* if IPComp is used, we first update the IPComp SA */
- if (cpi)
- {
- update_sa(this, htonl(ntohs(cpi)), IPPROTO_COMP, 0,
- src, dst, new_src, new_dst, FALSE, FALSE, mark);
- }
-
- memset(&request, 0, sizeof(request));
-
- DBG2(DBG_KNL, "querying SAD entry with SPI %.8x for update", ntohl(spi));
-
- /* query the existing SA first */
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST;
- hdr->nlmsg_type = XFRM_MSG_GETSA;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
-
- sa_id = (struct xfrm_usersa_id*)NLMSG_DATA(hdr);
- host2xfrm(dst, &sa_id->daddr);
- sa_id->spi = spi;
- sa_id->proto = proto_ike2kernel(protocol);
- sa_id->family = dst->get_family(dst);
-
- if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
- {
- hdr = out;
- while (NLMSG_OK(hdr, len))
- {
- switch (hdr->nlmsg_type)
- {
- case XFRM_MSG_NEWSA:
- {
- out_sa = NLMSG_DATA(hdr);
- break;
- }
- case NLMSG_ERROR:
- {
- struct nlmsgerr *err = NLMSG_DATA(hdr);
- DBG1(DBG_KNL, "querying SAD entry failed: %s (%d)",
- strerror(-err->error), -err->error);
- break;
- }
- default:
- hdr = NLMSG_NEXT(hdr, len);
- continue;
- case NLMSG_DONE:
- break;
- }
- break;
- }
- }
- if (out_sa == NULL)
- {
- DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi));
- free(out);
- return FAILED;
- }
-
- /* try to get the replay state */
- if (get_replay_state(this, spi, protocol, dst, &replay) == SUCCESS)
- {
- got_replay_state = TRUE;
- }
-
- /* delete the old SA (without affecting the IPComp SA) */
- if (del_sa(this, src, dst, spi, protocol, 0, mark) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to delete old SAD entry with SPI %.8x", ntohl(spi));
- free(out);
- return FAILED;
- }
-
- DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H",
- ntohl(spi), src, dst, new_src, new_dst);
- /* copy over the SA from out to request */
- hdr = (struct nlmsghdr*)request;
- memcpy(hdr, out, min(out->nlmsg_len, sizeof(request)));
- hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- hdr->nlmsg_type = XFRM_MSG_NEWSA;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info));
- sa = NLMSG_DATA(hdr);
- sa->family = new_dst->get_family(new_dst);
-
- if (!src->ip_equals(src, new_src))
- {
- host2xfrm(new_src, &sa->saddr);
- }
- if (!dst->ip_equals(dst, new_dst))
- {
- host2xfrm(new_dst, &sa->id.daddr);
- }
-
- rta = XFRM_RTA(out, struct xfrm_usersa_info);
- rtasize = XFRM_PAYLOAD(out, struct xfrm_usersa_info);
- pos = (u_char*)XFRM_RTA(hdr, struct xfrm_usersa_info);
- while(RTA_OK(rta, rtasize))
- {
- /* copy all attributes, but not XFRMA_ENCAP if we are disabling it */
- if (rta->rta_type != XFRMA_ENCAP || new_encap)
- {
- if (rta->rta_type == XFRMA_ENCAP)
- { /* update encap tmpl */
- tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rta);
- tmpl->encap_sport = ntohs(new_src->get_port(new_src));
- tmpl->encap_dport = ntohs(new_dst->get_port(new_dst));
- }
- memcpy(pos, rta, rta->rta_len);
- pos += RTA_ALIGN(rta->rta_len);
- hdr->nlmsg_len += RTA_ALIGN(rta->rta_len);
- }
- rta = RTA_NEXT(rta, rtasize);
- }
-
- rta = (struct rtattr*)pos;
- if (tmpl == NULL && new_encap)
- { /* add tmpl if we are enabling it */
- rta->rta_type = XFRMA_ENCAP;
- rta->rta_len = RTA_LENGTH(sizeof(struct xfrm_encap_tmpl));
-
- hdr->nlmsg_len += rta->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rta);
- tmpl->encap_type = UDP_ENCAP_ESPINUDP;
- tmpl->encap_sport = ntohs(new_src->get_port(new_src));
- tmpl->encap_dport = ntohs(new_dst->get_port(new_dst));
- memset(&tmpl->encap_oa, 0, sizeof (xfrm_address_t));
-
- rta = XFRM_RTA_NEXT(rta);
- }
-
- if (got_replay_state)
- { /* copy the replay data if available */
- rta->rta_type = XFRMA_REPLAY_VAL;
- rta->rta_len = RTA_LENGTH(sizeof(struct xfrm_replay_state));
-
- hdr->nlmsg_len += rta->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
- memcpy(RTA_DATA(rta), &replay, sizeof(replay));
-
- rta = XFRM_RTA_NEXT(rta);
- }
-
- if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi));
- free(out);
- return FAILED;
- }
- free(out);
-
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, add_policy, status_t,
- private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
- policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
- u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool routed)
-{
- policy_entry_t *current, *policy;
- bool found = FALSE;
- netlink_buf_t request;
- struct xfrm_userpolicy_info *policy_info;
- struct nlmsghdr *hdr;
-
- /* create a policy */
- policy = malloc_thing(policy_entry_t);
- memset(policy, 0, sizeof(policy_entry_t));
- policy->sel = ts2selector(src_ts, dst_ts);
- policy->mark = mark.value & mark.mask;
- policy->direction = direction;
-
- /* find the policy, which matches EXACTLY */
- this->mutex->lock(this->mutex);
- current = this->policies->get(this->policies, policy);
- if (current)
- {
- /* use existing policy */
- current->refcount++;
- if (mark.value)
- {
- DBG2(DBG_KNL, "policy %R === %R %N (mark %u/0x%8x) "
- "already exists, increasing refcount",
- src_ts, dst_ts, policy_dir_names, direction,
- mark.value, mark.mask);
- }
- else
- {
- DBG2(DBG_KNL, "policy %R === %R %N "
- "already exists, increasing refcount",
- src_ts, dst_ts, policy_dir_names, direction);
- }
- free(policy);
- policy = current;
- found = TRUE;
- }
- else
- { /* apply the new one, if we have no such policy */
- this->policies->put(this->policies, policy, policy);
- policy->refcount = 1;
- }
-
- if (mark.value)
- {
- DBG2(DBG_KNL, "adding policy %R === %R %N (mark %u/0x%8x)",
- src_ts, dst_ts, policy_dir_names, direction,
- mark.value, mark.mask);
- }
- else
- {
- DBG2(DBG_KNL, "adding policy %R === %R %N",
- src_ts, dst_ts, policy_dir_names, direction);
- }
-
- memset(&request, 0, sizeof(request));
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- hdr->nlmsg_type = found ? XFRM_MSG_UPDPOLICY : XFRM_MSG_NEWPOLICY;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info));
-
- policy_info = (struct xfrm_userpolicy_info*)NLMSG_DATA(hdr);
- policy_info->sel = policy->sel;
- policy_info->dir = policy->direction;
- /* calculate priority based on source selector size, small size = high prio */
- policy_info->priority = routed ? PRIO_LOW : PRIO_HIGH;
- policy_info->priority -= policy->sel.prefixlen_s * 10;
- policy_info->priority -= policy->sel.proto ? 2 : 0;
- policy_info->priority -= policy->sel.sport_mask ? 1 : 0;
- policy_info->action = XFRM_POLICY_ALLOW;
- policy_info->share = XFRM_SHARE_ANY;
- this->mutex->unlock(this->mutex);
-
- /* policies don't expire */
- policy_info->lft.soft_byte_limit = XFRM_INF;
- policy_info->lft.soft_packet_limit = XFRM_INF;
- policy_info->lft.hard_byte_limit = XFRM_INF;
- policy_info->lft.hard_packet_limit = XFRM_INF;
- policy_info->lft.soft_add_expires_seconds = 0;
- policy_info->lft.hard_add_expires_seconds = 0;
- policy_info->lft.soft_use_expires_seconds = 0;
- policy_info->lft.hard_use_expires_seconds = 0;
-
- struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_info);
- rthdr->rta_type = XFRMA_TMPL;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_user_tmpl));
-
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- struct xfrm_user_tmpl *tmpl = (struct xfrm_user_tmpl*)RTA_DATA(rthdr);
-
- if (ipcomp != IPCOMP_NONE)
- {
- tmpl->reqid = reqid;
- tmpl->id.proto = IPPROTO_COMP;
- tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
- tmpl->mode = mode2kernel(mode);
- tmpl->optional = direction != POLICY_OUT;
- tmpl->family = src->get_family(src);
-
- host2xfrm(src, &tmpl->saddr);
- host2xfrm(dst, &tmpl->id.daddr);
-
- /* add an additional xfrm_user_tmpl */
- rthdr->rta_len += RTA_LENGTH(sizeof(struct xfrm_user_tmpl));
- hdr->nlmsg_len += RTA_LENGTH(sizeof(struct xfrm_user_tmpl));
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- tmpl++;
-
- /* use transport mode for ESP if we have a tunnel mode IPcomp SA */
- mode = MODE_TRANSPORT;
- }
- else
- {
- /* when using IPcomp, only the IPcomp SA uses tmp src/dst addresses */
- host2xfrm(src, &tmpl->saddr);
- host2xfrm(dst, &tmpl->id.daddr);
- }
-
- tmpl->reqid = reqid;
- tmpl->id.proto = proto_ike2kernel(protocol);
- tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
- tmpl->mode = mode2kernel(mode);
- tmpl->family = src->get_family(src);
- rthdr = XFRM_RTA_NEXT(rthdr);
-
- if (mark.value)
- {
- struct xfrm_mark *mrk;
-
- rthdr->rta_type = XFRMA_MARK;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
-
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
- mrk->v = mark.value;
- mrk->m = mark.mask;
- }
-
- if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to add policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
- return FAILED;
- }
-
- /* install a route, if:
- * - we are NOT updating a policy
- * - this is a forward policy (to just get one for each child)
- * - we are in tunnel/BEET mode
- * - routing is not disabled via strongswan.conf
- */
- if (policy->route == NULL && direction == POLICY_FWD &&
- mode != MODE_TRANSPORT && this->install_routes)
- {
- route_entry_t *route = malloc_thing(route_entry_t);
-
- if (charon->kernel_interface->get_address_by_ts(charon->kernel_interface,
- dst_ts, &route->src_ip) == SUCCESS)
- {
- /* get the nexthop to src (src as we are in POLICY_FWD).*/
- route->gateway = charon->kernel_interface->get_nexthop(
- charon->kernel_interface, src);
- /* install route via outgoing interface */
- route->if_name = charon->kernel_interface->get_interface(
- charon->kernel_interface, dst);
- route->dst_net = chunk_alloc(policy->sel.family == AF_INET ? 4 : 16);
- memcpy(route->dst_net.ptr, &policy->sel.saddr, route->dst_net.len);
- route->prefixlen = policy->sel.prefixlen_s;
-
- if (route->if_name)
- {
- switch (charon->kernel_interface->add_route(
- charon->kernel_interface, route->dst_net,
- route->prefixlen, route->gateway,
- route->src_ip, route->if_name))
- {
- default:
- DBG1(DBG_KNL, "unable to install source route for %H",
- route->src_ip);
- /* FALL */
- case ALREADY_DONE:
- /* route exists, do not uninstall */
- route_entry_destroy(route);
- break;
- case SUCCESS:
- /* cache the installed route */
- policy->route = route;
- break;
- }
- }
- else
- {
- route_entry_destroy(route);
- }
- }
- else
- {
- free(route);
- }
- }
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, query_policy, status_t,
- private_kernel_netlink_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
- u_int32_t *use_time)
-{
- netlink_buf_t request;
- struct nlmsghdr *out = NULL, *hdr;
- struct xfrm_userpolicy_id *policy_id;
- struct xfrm_userpolicy_info *policy = NULL;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- if (mark.value)
- {
- DBG2(DBG_KNL, "querying policy %R === %R %N (mark %u/0x%8x)",
- src_ts, dst_ts, policy_dir_names, direction,
- mark.value, mark.mask);
- }
- else
- {
- DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
- }
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST;
- hdr->nlmsg_type = XFRM_MSG_GETPOLICY;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id));
-
- policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr);
- policy_id->sel = ts2selector(src_ts, dst_ts);
- policy_id->dir = direction;
-
- if (mark.value)
- {
- struct xfrm_mark *mrk;
- struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_id);
-
- rthdr->rta_type = XFRMA_MARK;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
-
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
- mrk->v = mark.value;
- mrk->m = mark.mask;
- }
-
- if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
- {
- hdr = out;
- while (NLMSG_OK(hdr, len))
- {
- switch (hdr->nlmsg_type)
- {
- case XFRM_MSG_NEWPOLICY:
- {
- policy = (struct xfrm_userpolicy_info*)NLMSG_DATA(hdr);
- break;
- }
- case NLMSG_ERROR:
- {
- struct nlmsgerr *err = NLMSG_DATA(hdr);
- DBG1(DBG_KNL, "querying policy failed: %s (%d)",
- strerror(-err->error), -err->error);
- break;
- }
- default:
- hdr = NLMSG_NEXT(hdr, len);
- continue;
- case NLMSG_DONE:
- break;
- }
- break;
- }
- }
-
- if (policy == NULL)
- {
- DBG2(DBG_KNL, "unable to query policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
- free(out);
- return FAILED;
- }
-
- if (policy->curlft.use_time)
- {
- /* we need the monotonic time, but the kernel returns system time. */
- *use_time = time_monotonic(NULL) - (time(NULL) - policy->curlft.use_time);
- }
- else
- {
- *use_time = 0;
- }
-
- free(out);
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, del_policy, status_t,
- private_kernel_netlink_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
- bool unrouted)
-{
- policy_entry_t *current, policy, *to_delete = NULL;
- route_entry_t *route;
- netlink_buf_t request;
- struct nlmsghdr *hdr;
- struct xfrm_userpolicy_id *policy_id;
-
- if (mark.value)
- {
- DBG2(DBG_KNL, "deleting policy %R === %R %N (mark %u/0x%8x)",
- src_ts, dst_ts, policy_dir_names, direction,
- mark.value, mark.mask);
- }
- else
- {
- DBG2(DBG_KNL, "deleting policy %R === %R %N",
- src_ts, dst_ts, policy_dir_names, direction);
- }
-
- /* create a policy */
- memset(&policy, 0, sizeof(policy_entry_t));
- policy.sel = ts2selector(src_ts, dst_ts);
- policy.mark = mark.value & mark.mask;
- policy.direction = direction;
-
- /* find the policy */
- this->mutex->lock(this->mutex);
- current = this->policies->get(this->policies, &policy);
- if (current)
- {
- to_delete = current;
- if (--to_delete->refcount > 0)
- {
- /* is used by more SAs, keep in kernel */
- DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed");
- this->mutex->unlock(this->mutex);
- return SUCCESS;
- }
- /* remove if last reference */
- this->policies->remove(this->policies, to_delete);
- }
- this->mutex->unlock(this->mutex);
- if (!to_delete)
- {
- if (mark.value)
- {
- DBG1(DBG_KNL, "deleting policy %R === %R %N (mark %u/0x%8x) "
- "failed, not found", src_ts, dst_ts, policy_dir_names,
- direction, mark.value, mark.mask);
- }
- else
- {
- DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found",
- src_ts, dst_ts, policy_dir_names, direction);
- }
- return NOT_FOUND;
- }
-
- memset(&request, 0, sizeof(request));
-
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- hdr->nlmsg_type = XFRM_MSG_DELPOLICY;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id));
-
- policy_id = (struct xfrm_userpolicy_id*)NLMSG_DATA(hdr);
- policy_id->sel = to_delete->sel;
- policy_id->dir = direction;
-
- if (mark.value)
- {
- struct xfrm_mark *mrk;
- struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_id);
-
- rthdr->rta_type = XFRMA_MARK;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
- hdr->nlmsg_len += rthdr->rta_len;
- if (hdr->nlmsg_len > sizeof(request))
- {
- return FAILED;
- }
-
- mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
- mrk->v = mark.value;
- mrk->m = mark.mask;
- }
-
- route = to_delete->route;
- free(to_delete);
-
- if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
- {
- if (mark.value)
- {
- DBG1(DBG_KNL, "unable to delete policy %R === %R %N "
- "(mark %u/0x%8x)", src_ts, dst_ts, policy_dir_names,
- direction, mark.value, mark.mask);
- }
- else
- {
- DBG1(DBG_KNL, "unable to delete policy %R === %R %N",
- src_ts, dst_ts, policy_dir_names, direction);
- }
- return FAILED;
- }
-
- if (route)
- {
- if (charon->kernel_interface->del_route(charon->kernel_interface,
- route->dst_net, route->prefixlen, route->gateway,
- route->src_ip, route->if_name) != SUCCESS)
- {
- DBG1(DBG_KNL, "error uninstalling route installed with "
- "policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
- }
- route_entry_destroy(route);
- }
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, bypass_socket, bool,
- private_kernel_netlink_ipsec_t *this, int fd, int family)
-{
- struct xfrm_userpolicy_info policy;
- u_int sol, ipsec_policy;
-
- switch (family)
- {
- case AF_INET:
- sol = SOL_IP;
- ipsec_policy = IP_XFRM_POLICY;
- break;
- case AF_INET6:
- sol = SOL_IPV6;
- ipsec_policy = IPV6_XFRM_POLICY;
- break;
- default:
- return FALSE;
- }
-
- memset(&policy, 0, sizeof(policy));
- policy.action = XFRM_POLICY_ALLOW;
- policy.sel.family = family;
-
- policy.dir = XFRM_POLICY_OUT;
- if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
- {
- DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
- strerror(errno));
- return FALSE;
- }
- policy.dir = XFRM_POLICY_IN;
- if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
- {
- DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
- strerror(errno));
- return FALSE;
- }
- return TRUE;
-}
-
-METHOD(kernel_ipsec_t, destroy, void,
- private_kernel_netlink_ipsec_t *this)
-{
- enumerator_t *enumerator;
- policy_entry_t *policy;
-
- if (this->job)
- {
- this->job->cancel(this->job);
- }
- if (this->socket_xfrm_events > 0)
- {
- close(this->socket_xfrm_events);
- }
- DESTROY_IF(this->socket_xfrm);
- enumerator = this->policies->create_enumerator(this->policies);
- while (enumerator->enumerate(enumerator, &policy, &policy))
- {
- free(policy);
- }
- enumerator->destroy(enumerator);
- this->policies->destroy(this->policies);
- this->mutex->destroy(this->mutex);
- free(this);
-}
-
-/*
- * Described in header.
- */
-kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
-{
- private_kernel_netlink_ipsec_t *this;
- struct sockaddr_nl addr;
- int fd;
-
- INIT(this,
- .public.interface = {
- .get_spi = _get_spi,
- .get_cpi = _get_cpi,
- .add_sa = _add_sa,
- .update_sa = _update_sa,
- .query_sa = _query_sa,
- .del_sa = _del_sa,
- .add_policy = _add_policy,
- .query_policy = _query_policy,
- .del_policy = _del_policy,
- .bypass_socket = _bypass_socket,
- .destroy = _destroy,
- },
- .policies = hashtable_create((hashtable_hash_t)policy_hash,
- (hashtable_equals_t)policy_equals, 32),
- .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
- .install_routes = lib->settings->get_bool(lib->settings,
- "charon.install_routes", TRUE),
- );
-
- /* disable lifetimes for allocated SPIs in kernel */
- fd = open("/proc/sys/net/core/xfrm_acq_expires", O_WRONLY);
- if (fd)
- {
- ignore_result(write(fd, "165", 3));
- close(fd);
- }
-
- this->socket_xfrm = netlink_socket_create(NETLINK_XFRM);
- if (!this->socket_xfrm)
- {
- destroy(this);
- return NULL;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.nl_family = AF_NETLINK;
-
- /* create and bind XFRM socket for ACQUIRE, EXPIRE, MIGRATE & MAPPING */
- this->socket_xfrm_events = socket(AF_NETLINK, SOCK_RAW, NETLINK_XFRM);
- if (this->socket_xfrm_events <= 0)
- {
- DBG1(DBG_KNL, "unable to create XFRM event socket");
- destroy(this);
- return NULL;
- }
- addr.nl_groups = XFRMNLGRP(ACQUIRE) | XFRMNLGRP(EXPIRE) |
- XFRMNLGRP(MIGRATE) | XFRMNLGRP(MAPPING);
- if (bind(this->socket_xfrm_events, (struct sockaddr*)&addr, sizeof(addr)))
- {
- DBG1(DBG_KNL, "unable to bind XFRM event socket");
- destroy(this);
- return NULL;
- }
- this->job = callback_job_create((callback_job_cb_t)receive_events,
- this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
-
- return &this->public;
-}
-
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h
deleted file mode 100644
index 3a45cce06..000000000
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup kernel_netlink_ipsec_i kernel_netlink_ipsec
- * @{ @ingroup kernel_netlink
- */
-
-#ifndef KERNEL_NETLINK_IPSEC_H_
-#define KERNEL_NETLINK_IPSEC_H_
-
-#include <kernel/kernel_ipsec.h>
-
-typedef struct kernel_netlink_ipsec_t kernel_netlink_ipsec_t;
-
-/**
- * Implementation of the kernel ipsec interface using Netlink.
- */
-struct kernel_netlink_ipsec_t {
-
- /**
- * Implements kernel_ipsec_t interface
- */
- kernel_ipsec_t interface;
-};
-
-/**
- * Create a netlink kernel ipsec interface instance.
- *
- * @return kernel_netlink_ipsec_t instance
- */
-kernel_netlink_ipsec_t *kernel_netlink_ipsec_create();
-
-#endif /** KERNEL_NETLINK_IPSEC_H_ @}*/
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c
deleted file mode 100644
index 6750458cf..000000000
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c
+++ /dev/null
@@ -1,1506 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2005-2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/*
- * Copyright (C) 2010 secunet Security Networks AG
- * Copyright (C) 2010 Thomas Egerer
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <unistd.h>
-#include <errno.h>
-#include <net/if.h>
-
-#include "kernel_netlink_net.h"
-#include "kernel_netlink_shared.h"
-
-#include <daemon.h>
-#include <threading/thread.h>
-#include <threading/condvar.h>
-#include <threading/mutex.h>
-#include <utils/linked_list.h>
-#include <processing/jobs/callback_job.h>
-#include <processing/jobs/roam_job.h>
-
-/** delay before firing roam jobs (ms) */
-#define ROAM_DELAY 100
-
-typedef struct addr_entry_t addr_entry_t;
-
-/**
- * IP address in an inface_entry_t
- */
-struct addr_entry_t {
-
- /** The ip address */
- host_t *ip;
-
- /** virtual IP managed by us */
- bool virtual;
-
- /** scope of the address */
- u_char scope;
-
- /** Number of times this IP is used, if virtual */
- u_int refcount;
-};
-
-/**
- * destroy a addr_entry_t object
- */
-static void addr_entry_destroy(addr_entry_t *this)
-{
- this->ip->destroy(this->ip);
- free(this);
-}
-
-typedef struct iface_entry_t iface_entry_t;
-
-/**
- * A network interface on this system, containing addr_entry_t's
- */
-struct iface_entry_t {
-
- /** interface index */
- int ifindex;
-
- /** name of the interface */
- char ifname[IFNAMSIZ];
-
- /** interface flags, as in netdevice(7) SIOCGIFFLAGS */
- u_int flags;
-
- /** list of addresses as host_t */
- linked_list_t *addrs;
-};
-
-/**
- * destroy an interface entry
- */
-static void iface_entry_destroy(iface_entry_t *this)
-{
- this->addrs->destroy_function(this->addrs, (void*)addr_entry_destroy);
- free(this);
-}
-
-typedef struct private_kernel_netlink_net_t private_kernel_netlink_net_t;
-
-/**
- * Private variables and functions of kernel_netlink_net class.
- */
-struct private_kernel_netlink_net_t {
- /**
- * Public part of the kernel_netlink_net_t object.
- */
- kernel_netlink_net_t public;
-
- /**
- * mutex to lock access to various lists
- */
- mutex_t *mutex;
-
- /**
- * condition variable to signal virtual IP add/removal
- */
- condvar_t *condvar;
-
- /**
- * Cached list of interfaces and its addresses (iface_entry_t)
- */
- linked_list_t *ifaces;
-
- /**
- * job receiving netlink events
- */
- callback_job_t *job;
-
- /**
- * netlink rt socket (routing)
- */
- netlink_socket_t *socket;
-
- /**
- * Netlink rt socket to receive address change events
- */
- int socket_events;
-
- /**
- * time of the last roam_job
- */
- timeval_t last_roam;
-
- /**
- * routing table to install routes
- */
- int routing_table;
-
- /**
- * priority of used routing table
- */
- int routing_table_prio;
-
- /**
- * whether to react to RTM_NEWROUTE or RTM_DELROUTE events
- */
- bool process_route;
-
- /**
- * whether to actually install virtual IPs
- */
- bool install_virtual_ip;
-
- /**
- * list with routing tables to be excluded from route lookup
- */
- linked_list_t *rt_exclude;
-};
-
-/**
- * get the refcount of a virtual ip
- */
-static int get_vip_refcount(private_kernel_netlink_net_t *this, host_t* ip)
-{
- iterator_t *ifaces, *addrs;
- iface_entry_t *iface;
- addr_entry_t *addr;
- int refcount = 0;
-
- ifaces = this->ifaces->create_iterator(this->ifaces, TRUE);
- while (ifaces->iterate(ifaces, (void**)&iface))
- {
- addrs = iface->addrs->create_iterator(iface->addrs, TRUE);
- while (addrs->iterate(addrs, (void**)&addr))
- {
- if (addr->virtual && (iface->flags & IFF_UP) &&
- ip->ip_equals(ip, addr->ip))
- {
- refcount = addr->refcount;
- break;
- }
- }
- addrs->destroy(addrs);
- if (refcount)
- {
- break;
- }
- }
- ifaces->destroy(ifaces);
-
- return refcount;
-}
-
-/**
- * start a roaming job. We delay it for a second and fire only one job
- * for multiple events. Otherwise we would create two many jobs.
- */
-static void fire_roam_job(private_kernel_netlink_net_t *this, bool address)
-{
- timeval_t now;
-
- time_monotonic(&now);
- if (timercmp(&now, &this->last_roam, >))
- {
- now.tv_usec += ROAM_DELAY * 1000;
- while (now.tv_usec > 1000000)
- {
- now.tv_sec++;
- now.tv_usec -= 1000000;
- }
- this->last_roam = now;
- charon->scheduler->schedule_job_ms(charon->scheduler,
- (job_t*)roam_job_create(address), ROAM_DELAY);
- }
-}
-
-/**
- * process RTM_NEWLINK/RTM_DELLINK from kernel
- */
-static void process_link(private_kernel_netlink_net_t *this,
- struct nlmsghdr *hdr, bool event)
-{
- struct ifinfomsg* msg = (struct ifinfomsg*)(NLMSG_DATA(hdr));
- struct rtattr *rta = IFLA_RTA(msg);
- size_t rtasize = IFLA_PAYLOAD (hdr);
- enumerator_t *enumerator;
- iface_entry_t *current, *entry = NULL;
- char *name = NULL;
- bool update = FALSE;
-
- while(RTA_OK(rta, rtasize))
- {
- switch (rta->rta_type)
- {
- case IFLA_IFNAME:
- name = RTA_DATA(rta);
- break;
- }
- rta = RTA_NEXT(rta, rtasize);
- }
- if (!name)
- {
- name = "(unknown)";
- }
-
- this->mutex->lock(this->mutex);
- switch (hdr->nlmsg_type)
- {
- case RTM_NEWLINK:
- {
- if (msg->ifi_flags & IFF_LOOPBACK)
- { /* ignore loopback interfaces */
- break;
- }
- enumerator = this->ifaces->create_enumerator(this->ifaces);
- while (enumerator->enumerate(enumerator, &current))
- {
- if (current->ifindex == msg->ifi_index)
- {
- entry = current;
- break;
- }
- }
- enumerator->destroy(enumerator);
- if (!entry)
- {
- entry = malloc_thing(iface_entry_t);
- entry->ifindex = msg->ifi_index;
- entry->flags = 0;
- entry->addrs = linked_list_create();
- this->ifaces->insert_last(this->ifaces, entry);
- }
- memcpy(entry->ifname, name, IFNAMSIZ);
- entry->ifname[IFNAMSIZ-1] = '\0';
- if (event)
- {
- if (!(entry->flags & IFF_UP) && (msg->ifi_flags & IFF_UP))
- {
- update = TRUE;
- DBG1(DBG_KNL, "interface %s activated", name);
- }
- if ((entry->flags & IFF_UP) && !(msg->ifi_flags & IFF_UP))
- {
- update = TRUE;
- DBG1(DBG_KNL, "interface %s deactivated", name);
- }
- }
- entry->flags = msg->ifi_flags;
- break;
- }
- case RTM_DELLINK:
- {
- enumerator = this->ifaces->create_enumerator(this->ifaces);
- while (enumerator->enumerate(enumerator, &current))
- {
- if (current->ifindex == msg->ifi_index)
- {
- /* we do not remove it, as an address may be added to a
- * "down" interface and we wan't to know that. */
- current->flags = msg->ifi_flags;
- break;
- }
- }
- enumerator->destroy(enumerator);
- break;
- }
- }
- this->mutex->unlock(this->mutex);
-
- /* send an update to all IKE_SAs */
- if (update && event)
- {
- fire_roam_job(this, TRUE);
- }
-}
-
-/**
- * process RTM_NEWADDR/RTM_DELADDR from kernel
- */
-static void process_addr(private_kernel_netlink_net_t *this,
- struct nlmsghdr *hdr, bool event)
-{
- struct ifaddrmsg* msg = (struct ifaddrmsg*)(NLMSG_DATA(hdr));
- struct rtattr *rta = IFA_RTA(msg);
- size_t rtasize = IFA_PAYLOAD (hdr);
- host_t *host = NULL;
- enumerator_t *ifaces, *addrs;
- iface_entry_t *iface;
- addr_entry_t *addr;
- chunk_t local = chunk_empty, address = chunk_empty;
- bool update = FALSE, found = FALSE, changed = FALSE;
-
- while(RTA_OK(rta, rtasize))
- {
- switch (rta->rta_type)
- {
- case IFA_LOCAL:
- local.ptr = RTA_DATA(rta);
- local.len = RTA_PAYLOAD(rta);
- break;
- case IFA_ADDRESS:
- address.ptr = RTA_DATA(rta);
- address.len = RTA_PAYLOAD(rta);
- break;
- }
- rta = RTA_NEXT(rta, rtasize);
- }
-
- /* For PPP interfaces, we need the IFA_LOCAL address,
- * IFA_ADDRESS is the peers address. But IFA_LOCAL is
- * not included in all cases (IPv6?), so fallback to IFA_ADDRESS. */
- if (local.ptr)
- {
- host = host_create_from_chunk(msg->ifa_family, local, 0);
- }
- else if (address.ptr)
- {
- host = host_create_from_chunk(msg->ifa_family, address, 0);
- }
-
- if (host == NULL)
- { /* bad family? */
- return;
- }
-
- this->mutex->lock(this->mutex);
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &iface))
- {
- if (iface->ifindex == msg->ifa_index)
- {
- addrs = iface->addrs->create_enumerator(iface->addrs);
- while (addrs->enumerate(addrs, &addr))
- {
- if (host->ip_equals(host, addr->ip))
- {
- found = TRUE;
- if (hdr->nlmsg_type == RTM_DELADDR)
- {
- iface->addrs->remove_at(iface->addrs, addrs);
- if (!addr->virtual)
- {
- changed = TRUE;
- DBG1(DBG_KNL, "%H disappeared from %s",
- host, iface->ifname);
- }
- addr_entry_destroy(addr);
- }
- else if (hdr->nlmsg_type == RTM_NEWADDR && addr->virtual)
- {
- addr->refcount = 1;
- }
- }
- }
- addrs->destroy(addrs);
-
- if (hdr->nlmsg_type == RTM_NEWADDR)
- {
- if (!found)
- {
- found = TRUE;
- changed = TRUE;
- addr = malloc_thing(addr_entry_t);
- addr->ip = host->clone(host);
- addr->virtual = FALSE;
- addr->refcount = 1;
- addr->scope = msg->ifa_scope;
-
- iface->addrs->insert_last(iface->addrs, addr);
- if (event)
- {
- DBG1(DBG_KNL, "%H appeared on %s", host, iface->ifname);
- }
- }
- }
- if (found && (iface->flags & IFF_UP))
- {
- update = TRUE;
- }
- break;
- }
- }
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
- host->destroy(host);
-
- /* send an update to all IKE_SAs */
- if (update && event && changed)
- {
- fire_roam_job(this, TRUE);
- }
-}
-
-/**
- * process RTM_NEWROUTE and RTM_DELROUTE from kernel
- */
-static void process_route(private_kernel_netlink_net_t *this, struct nlmsghdr *hdr)
-{
- struct rtmsg* msg = (struct rtmsg*)(NLMSG_DATA(hdr));
- struct rtattr *rta = RTM_RTA(msg);
- size_t rtasize = RTM_PAYLOAD(hdr);
- host_t *host = NULL;
-
- /* ignore routes added by us */
- if (msg->rtm_table && msg->rtm_table == this->routing_table)
- {
- return;
- }
-
- while (RTA_OK(rta, rtasize))
- {
- switch (rta->rta_type)
- {
- case RTA_PREFSRC:
- host = host_create_from_chunk(msg->rtm_family,
- chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)), 0);
- break;
- }
- rta = RTA_NEXT(rta, rtasize);
- }
- if (host)
- {
- this->mutex->lock(this->mutex);
- if (!get_vip_refcount(this, host))
- { /* ignore routes added for virtual IPs */
- fire_roam_job(this, FALSE);
- }
- this->mutex->unlock(this->mutex);
- host->destroy(host);
- }
-}
-
-/**
- * Receives events from kernel
- */
-static job_requeue_t receive_events(private_kernel_netlink_net_t *this)
-{
- char response[1024];
- struct nlmsghdr *hdr = (struct nlmsghdr*)response;
- struct sockaddr_nl addr;
- socklen_t addr_len = sizeof(addr);
- int len;
- bool oldstate;
-
- oldstate = thread_cancelability(TRUE);
- len = recvfrom(this->socket_events, response, sizeof(response), 0,
- (struct sockaddr*)&addr, &addr_len);
- thread_cancelability(oldstate);
-
- if (len < 0)
- {
- switch (errno)
- {
- case EINTR:
- /* interrupted, try again */
- return JOB_REQUEUE_DIRECT;
- case EAGAIN:
- /* no data ready, select again */
- return JOB_REQUEUE_DIRECT;
- default:
- DBG1(DBG_KNL, "unable to receive from rt event socket");
- sleep(1);
- return JOB_REQUEUE_FAIR;
- }
- }
-
- if (addr.nl_pid != 0)
- { /* not from kernel. not interested, try another one */
- return JOB_REQUEUE_DIRECT;
- }
-
- while (NLMSG_OK(hdr, len))
- {
- /* looks good so far, dispatch netlink message */
- switch (hdr->nlmsg_type)
- {
- case RTM_NEWADDR:
- case RTM_DELADDR:
- process_addr(this, hdr, TRUE);
- this->condvar->broadcast(this->condvar);
- break;
- case RTM_NEWLINK:
- case RTM_DELLINK:
- process_link(this, hdr, TRUE);
- this->condvar->broadcast(this->condvar);
- break;
- case RTM_NEWROUTE:
- case RTM_DELROUTE:
- if (this->process_route)
- {
- process_route(this, hdr);
- }
- break;
- default:
- break;
- }
- hdr = NLMSG_NEXT(hdr, len);
- }
- return JOB_REQUEUE_DIRECT;
-}
-
-/** enumerator over addresses */
-typedef struct {
- private_kernel_netlink_net_t* this;
- /** whether to enumerate down interfaces */
- bool include_down_ifaces;
- /** whether to enumerate virtual ip addresses */
- bool include_virtual_ips;
-} address_enumerator_t;
-
-/**
- * cleanup function for address enumerator
- */
-static void address_enumerator_destroy(address_enumerator_t *data)
-{
- data->this->mutex->unlock(data->this->mutex);
- free(data);
-}
-
-/**
- * filter for addresses
- */
-static bool filter_addresses(address_enumerator_t *data, addr_entry_t** in, host_t** out)
-{
- if (!data->include_virtual_ips && (*in)->virtual)
- { /* skip virtual interfaces added by us */
- return FALSE;
- }
- if ((*in)->scope >= RT_SCOPE_LINK)
- { /* skip addresses with a unusable scope */
- return FALSE;
- }
- *out = (*in)->ip;
- return TRUE;
-}
-
-/**
- * enumerator constructor for interfaces
- */
-static enumerator_t *create_iface_enumerator(iface_entry_t *iface, address_enumerator_t *data)
-{
- return enumerator_create_filter(iface->addrs->create_enumerator(iface->addrs),
- (void*)filter_addresses, data, NULL);
-}
-
-/**
- * filter for interfaces
- */
-static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in, iface_entry_t** out)
-{
- if (!data->include_down_ifaces && !((*in)->flags & IFF_UP))
- { /* skip interfaces not up */
- return FALSE;
- }
- *out = *in;
- return TRUE;
-}
-
-/**
- * implementation of kernel_net_t.create_address_enumerator
- */
-static enumerator_t *create_address_enumerator(private_kernel_netlink_net_t *this,
- bool include_down_ifaces, bool include_virtual_ips)
-{
- address_enumerator_t *data = malloc_thing(address_enumerator_t);
- data->this = this;
- data->include_down_ifaces = include_down_ifaces;
- data->include_virtual_ips = include_virtual_ips;
-
- this->mutex->lock(this->mutex);
- return enumerator_create_nested(
- enumerator_create_filter(this->ifaces->create_enumerator(this->ifaces),
- (void*)filter_interfaces, data, NULL),
- (void*)create_iface_enumerator, data, (void*)address_enumerator_destroy);
-}
-
-/**
- * implementation of kernel_net_t.get_interface_name
- */
-static char *get_interface_name(private_kernel_netlink_net_t *this, host_t* ip)
-{
- enumerator_t *ifaces, *addrs;
- iface_entry_t *iface;
- addr_entry_t *addr;
- char *name = NULL;
-
- DBG2(DBG_KNL, "getting interface name for %H", ip);
-
- this->mutex->lock(this->mutex);
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &iface))
- {
- addrs = iface->addrs->create_enumerator(iface->addrs);
- while (addrs->enumerate(addrs, &addr))
- {
- if (ip->ip_equals(ip, addr->ip))
- {
- name = strdup(iface->ifname);
- break;
- }
- }
- addrs->destroy(addrs);
- if (name)
- {
- break;
- }
- }
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
-
- if (name)
- {
- DBG2(DBG_KNL, "%H is on interface %s", ip, name);
- }
- else
- {
- DBG2(DBG_KNL, "%H is not a local address", ip);
- }
- return name;
-}
-
-/**
- * get the index of an interface by name
- */
-static int get_interface_index(private_kernel_netlink_net_t *this, char* name)
-{
- enumerator_t *ifaces;
- iface_entry_t *iface;
- int ifindex = 0;
-
- DBG2(DBG_KNL, "getting iface index for %s", name);
-
- this->mutex->lock(this->mutex);
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &iface))
- {
- if (streq(name, iface->ifname))
- {
- ifindex = iface->ifindex;
- break;
- }
- }
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
-
- if (ifindex == 0)
- {
- DBG1(DBG_KNL, "unable to get interface index for %s", name);
- }
- return ifindex;
-}
-
-/**
- * Check if an interface with a given index is up
- */
-static bool is_interface_up(private_kernel_netlink_net_t *this, int index)
-{
- enumerator_t *ifaces;
- iface_entry_t *iface;
- /* default to TRUE for interface we do not monitor (e.g. lo) */
- bool up = TRUE;
-
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &iface))
- {
- if (iface->ifindex == index)
- {
- up = iface->flags & IFF_UP;
- break;
- }
- }
- ifaces->destroy(ifaces);
- return up;
-}
-
-/**
- * check if an address (chunk) addr is in subnet (net with net_len net bits)
- */
-static bool addr_in_subnet(chunk_t addr, chunk_t net, int net_len)
-{
- static const u_char mask[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
- int byte = 0;
-
- if (net_len == 0)
- { /* any address matches a /0 network */
- return TRUE;
- }
- if (addr.len != net.len || net_len > 8 * net.len )
- {
- return FALSE;
- }
- /* scan through all bytes in network order */
- while (net_len > 0)
- {
- if (net_len < 8)
- {
- return (mask[net_len] & addr.ptr[byte]) == (mask[net_len] & net.ptr[byte]);
- }
- else
- {
- if (addr.ptr[byte] != net.ptr[byte])
- {
- return FALSE;
- }
- byte++;
- net_len -= 8;
- }
- }
- return TRUE;
-}
-
-/**
- * Get a route: If "nexthop", the nexthop is returned. source addr otherwise.
- */
-static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
- bool nexthop, host_t *candidate)
-{
- netlink_buf_t request;
- struct nlmsghdr *hdr, *out, *current;
- struct rtmsg *msg;
- chunk_t chunk;
- size_t len;
- int best = -1;
- enumerator_t *enumerator;
- host_t *src = NULL, *gtw = NULL;
-
- DBG2(DBG_KNL, "getting address to reach %H", dest);
-
- memset(&request, 0, sizeof(request));
-
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST;
- if (dest->get_family(dest) == AF_INET)
- {
- /* We dump all addresses for IPv4, as we want to ignore IPsec specific
- * routes installed by us. But the kernel does not return source
- * addresses in a IPv6 dump, so fall back to get() for v6 routes. */
- hdr->nlmsg_flags |= NLM_F_ROOT | NLM_F_DUMP;
- }
- hdr->nlmsg_type = RTM_GETROUTE;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
-
- msg = (struct rtmsg*)NLMSG_DATA(hdr);
- msg->rtm_family = dest->get_family(dest);
- if (candidate)
- {
- chunk = candidate->get_address(candidate);
- netlink_add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request));
- }
- chunk = dest->get_address(dest);
- netlink_add_attribute(hdr, RTA_DST, chunk, sizeof(request));
-
- if (this->socket->send(this->socket, hdr, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "getting address to %H failed", dest);
- return NULL;
- }
- this->mutex->lock(this->mutex);
-
- for (current = out; NLMSG_OK(current, len);
- current = NLMSG_NEXT(current, len))
- {
- switch (current->nlmsg_type)
- {
- case NLMSG_DONE:
- break;
- case RTM_NEWROUTE:
- {
- struct rtattr *rta;
- size_t rtasize;
- chunk_t rta_gtw, rta_src, rta_dst;
- u_int32_t rta_oif = 0;
- host_t *new_src, *new_gtw;
- bool cont = FALSE;
- uintptr_t table;
-
- rta_gtw = rta_src = rta_dst = chunk_empty;
- msg = (struct rtmsg*)(NLMSG_DATA(current));
- rta = RTM_RTA(msg);
- rtasize = RTM_PAYLOAD(current);
- while (RTA_OK(rta, rtasize))
- {
- switch (rta->rta_type)
- {
- case RTA_PREFSRC:
- rta_src = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta));
- break;
- case RTA_GATEWAY:
- rta_gtw = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta));
- break;
- case RTA_DST:
- rta_dst = chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta));
- break;
- case RTA_OIF:
- if (RTA_PAYLOAD(rta) == sizeof(rta_oif))
- {
- rta_oif = *(u_int32_t*)RTA_DATA(rta);
- }
- break;
- }
- rta = RTA_NEXT(rta, rtasize);
- }
- if (msg->rtm_dst_len <= best)
- { /* not better than a previous one */
- continue;
- }
- enumerator = this->rt_exclude->create_enumerator(this->rt_exclude);
- while (enumerator->enumerate(enumerator, &table))
- {
- if (table == msg->rtm_table)
- {
- cont = TRUE;
- break;
- }
- }
- enumerator->destroy(enumerator);
- if (cont)
- {
- continue;
- }
- if (this->routing_table != 0 &&
- msg->rtm_table == this->routing_table)
- { /* route is from our own ipsec routing table */
- continue;
- }
- if (rta_oif && !is_interface_up(this, rta_oif))
- { /* interface is down */
- continue;
- }
- if (!addr_in_subnet(chunk, rta_dst, msg->rtm_dst_len))
- { /* route destination does not contain dest */
- continue;
- }
-
- if (nexthop)
- {
- /* nexthop lookup, return gateway if any */
- DESTROY_IF(gtw);
- gtw = host_create_from_chunk(msg->rtm_family, rta_gtw, 0);
- best = msg->rtm_dst_len;
- continue;
- }
- if (rta_src.ptr)
- {
- /* got a source address */
- new_src = host_create_from_chunk(msg->rtm_family, rta_src, 0);
- if (new_src)
- {
- if (get_vip_refcount(this, new_src))
- { /* skip source address if it is installed by us */
- new_src->destroy(new_src);
- }
- else
- {
- DESTROY_IF(src);
- src = new_src;
- best = msg->rtm_dst_len;
- }
- }
- continue;
- }
- if (rta_gtw.ptr)
- { /* no source, but a gateway. Lookup source to reach gtw. */
- new_gtw = host_create_from_chunk(msg->rtm_family, rta_gtw, 0);
- new_src = get_route(this, new_gtw, FALSE, candidate);
- new_gtw->destroy(new_gtw);
- if (new_src)
- {
- DESTROY_IF(src);
- src = new_src;
- best = msg->rtm_dst_len;
- }
- continue;
- }
- continue;
- }
- default:
- continue;
- }
- break;
- }
- free(out);
- this->mutex->unlock(this->mutex);
-
- if (nexthop)
- {
- if (gtw)
- {
- return gtw;
- }
- return dest->clone(dest);
- }
- return src;
-}
-
-/**
- * Implementation of kernel_net_t.get_source_addr.
- */
-static host_t* get_source_addr(private_kernel_netlink_net_t *this,
- host_t *dest, host_t *src)
-{
- return get_route(this, dest, FALSE, src);
-}
-
-/**
- * Implementation of kernel_net_t.get_nexthop.
- */
-static host_t* get_nexthop(private_kernel_netlink_net_t *this, host_t *dest)
-{
- return get_route(this, dest, TRUE, NULL);
-}
-
-/**
- * Manages the creation and deletion of ip addresses on an interface.
- * By setting the appropriate nlmsg_type, the ip will be set or unset.
- */
-static status_t manage_ipaddr(private_kernel_netlink_net_t *this, int nlmsg_type,
- int flags, int if_index, host_t *ip)
-{
- netlink_buf_t request;
- struct nlmsghdr *hdr;
- struct ifaddrmsg *msg;
- chunk_t chunk;
-
- memset(&request, 0, sizeof(request));
-
- chunk = ip->get_address(ip);
-
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
- hdr->nlmsg_type = nlmsg_type;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
-
- msg = (struct ifaddrmsg*)NLMSG_DATA(hdr);
- msg->ifa_family = ip->get_family(ip);
- msg->ifa_flags = 0;
- msg->ifa_prefixlen = 8 * chunk.len;
- msg->ifa_scope = RT_SCOPE_UNIVERSE;
- msg->ifa_index = if_index;
-
- netlink_add_attribute(hdr, IFA_LOCAL, chunk, sizeof(request));
-
- return this->socket->send_ack(this->socket, hdr);
-}
-
-/**
- * Implementation of kernel_net_t.add_ip.
- */
-static status_t add_ip(private_kernel_netlink_net_t *this,
- host_t *virtual_ip, host_t *iface_ip)
-{
- iface_entry_t *iface;
- addr_entry_t *addr;
- enumerator_t *addrs, *ifaces;
- int ifindex;
-
- if (!this->install_virtual_ip)
- { /* disabled by config */
- return SUCCESS;
- }
-
- DBG2(DBG_KNL, "adding virtual IP %H", virtual_ip);
-
- this->mutex->lock(this->mutex);
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &iface))
- {
- bool iface_found = FALSE;
-
- addrs = iface->addrs->create_enumerator(iface->addrs);
- while (addrs->enumerate(addrs, &addr))
- {
- if (iface_ip->ip_equals(iface_ip, addr->ip))
- {
- iface_found = TRUE;
- }
- else if (virtual_ip->ip_equals(virtual_ip, addr->ip))
- {
- addr->refcount++;
- DBG2(DBG_KNL, "virtual IP %H already installed on %s",
- virtual_ip, iface->ifname);
- addrs->destroy(addrs);
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
- return SUCCESS;
- }
- }
- addrs->destroy(addrs);
-
- if (iface_found)
- {
- ifindex = iface->ifindex;
- addr = malloc_thing(addr_entry_t);
- addr->ip = virtual_ip->clone(virtual_ip);
- addr->refcount = 0;
- addr->virtual = TRUE;
- addr->scope = RT_SCOPE_UNIVERSE;
- iface->addrs->insert_last(iface->addrs, addr);
-
- if (manage_ipaddr(this, RTM_NEWADDR, NLM_F_CREATE | NLM_F_EXCL,
- ifindex, virtual_ip) == SUCCESS)
- {
- while (get_vip_refcount(this, virtual_ip) == 0)
- { /* wait until address appears */
- this->condvar->wait(this->condvar, this->mutex);
- }
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
- return SUCCESS;
- }
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
- DBG1(DBG_KNL, "adding virtual IP %H failed", virtual_ip);
- return FAILED;
- }
- }
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
-
- DBG1(DBG_KNL, "interface address %H not found, unable to install"
- "virtual IP %H", iface_ip, virtual_ip);
- return FAILED;
-}
-
-/**
- * Implementation of kernel_net_t.del_ip.
- */
-static status_t del_ip(private_kernel_netlink_net_t *this, host_t *virtual_ip)
-{
- iface_entry_t *iface;
- addr_entry_t *addr;
- enumerator_t *addrs, *ifaces;
- status_t status;
- int ifindex;
-
- if (!this->install_virtual_ip)
- { /* disabled by config */
- return SUCCESS;
- }
-
- DBG2(DBG_KNL, "deleting virtual IP %H", virtual_ip);
-
- this->mutex->lock(this->mutex);
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &iface))
- {
- addrs = iface->addrs->create_enumerator(iface->addrs);
- while (addrs->enumerate(addrs, &addr))
- {
- if (virtual_ip->ip_equals(virtual_ip, addr->ip))
- {
- ifindex = iface->ifindex;
- if (addr->refcount == 1)
- {
- status = manage_ipaddr(this, RTM_DELADDR, 0,
- ifindex, virtual_ip);
- if (status == SUCCESS)
- { /* wait until the address is really gone */
- while (get_vip_refcount(this, virtual_ip) > 0)
- {
- this->condvar->wait(this->condvar, this->mutex);
- }
- }
- addrs->destroy(addrs);
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
- return status;
- }
- else
- {
- addr->refcount--;
- }
- DBG2(DBG_KNL, "virtual IP %H used by other SAs, not deleting",
- virtual_ip);
- addrs->destroy(addrs);
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
- return SUCCESS;
- }
- }
- addrs->destroy(addrs);
- }
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
-
- DBG2(DBG_KNL, "virtual IP %H not cached, unable to delete", virtual_ip);
- return FAILED;
-}
-
-/**
- * Manages source routes in the routing table.
- * By setting the appropriate nlmsg_type, the route gets added or removed.
- */
-static status_t manage_srcroute(private_kernel_netlink_net_t *this, int nlmsg_type,
- int flags, chunk_t dst_net, u_int8_t prefixlen,
- host_t *gateway, host_t *src_ip, char *if_name)
-{
- netlink_buf_t request;
- struct nlmsghdr *hdr;
- struct rtmsg *msg;
- int ifindex;
- chunk_t chunk;
-
- /* if route is 0.0.0.0/0, we can't install it, as it would
- * overwrite the default route. Instead, we add two routes:
- * 0.0.0.0/1 and 128.0.0.0/1 */
- if (this->routing_table == 0 && prefixlen == 0)
- {
- chunk_t half_net;
- u_int8_t half_prefixlen;
- status_t status;
-
- half_net = chunk_alloca(dst_net.len);
- memset(half_net.ptr, 0, half_net.len);
- half_prefixlen = 1;
-
- status = manage_srcroute(this, nlmsg_type, flags, half_net, half_prefixlen,
- gateway, src_ip, if_name);
- half_net.ptr[0] |= 0x80;
- status = manage_srcroute(this, nlmsg_type, flags, half_net, half_prefixlen,
- gateway, src_ip, if_name);
- return status;
- }
-
- memset(&request, 0, sizeof(request));
-
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
- hdr->nlmsg_type = nlmsg_type;
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
-
- msg = (struct rtmsg*)NLMSG_DATA(hdr);
- msg->rtm_family = src_ip->get_family(src_ip);
- msg->rtm_dst_len = prefixlen;
- msg->rtm_table = this->routing_table;
- msg->rtm_protocol = RTPROT_STATIC;
- msg->rtm_type = RTN_UNICAST;
- msg->rtm_scope = RT_SCOPE_UNIVERSE;
-
- netlink_add_attribute(hdr, RTA_DST, dst_net, sizeof(request));
- chunk = src_ip->get_address(src_ip);
- netlink_add_attribute(hdr, RTA_PREFSRC, chunk, sizeof(request));
- if (gateway && gateway->get_family(gateway) == src_ip->get_family(src_ip))
- {
- chunk = gateway->get_address(gateway);
- netlink_add_attribute(hdr, RTA_GATEWAY, chunk, sizeof(request));
- }
- ifindex = get_interface_index(this, if_name);
- chunk.ptr = (char*)&ifindex;
- chunk.len = sizeof(ifindex);
- netlink_add_attribute(hdr, RTA_OIF, chunk, sizeof(request));
-
- return this->socket->send_ack(this->socket, hdr);
-}
-
-/**
- * Implementation of kernel_net_t.add_route.
- */
-static status_t add_route(private_kernel_netlink_net_t *this, chunk_t dst_net,
- u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
-{
- return manage_srcroute(this, RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL,
- dst_net, prefixlen, gateway, src_ip, if_name);
-}
-
-/**
- * Implementation of kernel_net_t.del_route.
- */
-static status_t del_route(private_kernel_netlink_net_t *this, chunk_t dst_net,
- u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
-{
- return manage_srcroute(this, RTM_DELROUTE, 0, dst_net, prefixlen,
- gateway, src_ip, if_name);
-}
-
-/**
- * Initialize a list of local addresses.
- */
-static status_t init_address_list(private_kernel_netlink_net_t *this)
-{
- netlink_buf_t request;
- struct nlmsghdr *out, *current, *in;
- struct rtgenmsg *msg;
- size_t len;
- enumerator_t *ifaces, *addrs;
- iface_entry_t *iface;
- addr_entry_t *addr;
-
- DBG1(DBG_KNL, "listening on interfaces:");
-
- memset(&request, 0, sizeof(request));
-
- in = (struct nlmsghdr*)&request;
- in->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
- in->nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT;
- msg = (struct rtgenmsg*)NLMSG_DATA(in);
- msg->rtgen_family = AF_UNSPEC;
-
- /* get all links */
- in->nlmsg_type = RTM_GETLINK;
- if (this->socket->send(this->socket, in, &out, &len) != SUCCESS)
- {
- return FAILED;
- }
- current = out;
- while (NLMSG_OK(current, len))
- {
- switch (current->nlmsg_type)
- {
- case NLMSG_DONE:
- break;
- case RTM_NEWLINK:
- process_link(this, current, FALSE);
- /* fall through */
- default:
- current = NLMSG_NEXT(current, len);
- continue;
- }
- break;
- }
- free(out);
-
- /* get all interface addresses */
- in->nlmsg_type = RTM_GETADDR;
- if (this->socket->send(this->socket, in, &out, &len) != SUCCESS)
- {
- return FAILED;
- }
- current = out;
- while (NLMSG_OK(current, len))
- {
- switch (current->nlmsg_type)
- {
- case NLMSG_DONE:
- break;
- case RTM_NEWADDR:
- process_addr(this, current, FALSE);
- /* fall through */
- default:
- current = NLMSG_NEXT(current, len);
- continue;
- }
- break;
- }
- free(out);
-
- this->mutex->lock(this->mutex);
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &iface))
- {
- if (iface->flags & IFF_UP)
- {
- DBG1(DBG_KNL, " %s", iface->ifname);
- addrs = iface->addrs->create_enumerator(iface->addrs);
- while (addrs->enumerate(addrs, (void**)&addr))
- {
- DBG1(DBG_KNL, " %H", addr->ip);
- }
- addrs->destroy(addrs);
- }
- }
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
- return SUCCESS;
-}
-
-/**
- * create or delete a rule to use our routing table
- */
-static status_t manage_rule(private_kernel_netlink_net_t *this, int nlmsg_type,
- int family, u_int32_t table, u_int32_t prio)
-{
- netlink_buf_t request;
- struct nlmsghdr *hdr;
- struct rtmsg *msg;
- chunk_t chunk;
-
- memset(&request, 0, sizeof(request));
- hdr = (struct nlmsghdr*)request;
- hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- hdr->nlmsg_type = nlmsg_type;
- if (nlmsg_type == RTM_NEWRULE)
- {
- hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
- }
- hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
-
- msg = (struct rtmsg*)NLMSG_DATA(hdr);
- msg->rtm_table = table;
- msg->rtm_family = family;
- msg->rtm_protocol = RTPROT_BOOT;
- msg->rtm_scope = RT_SCOPE_UNIVERSE;
- msg->rtm_type = RTN_UNICAST;
-
- chunk = chunk_from_thing(prio);
- netlink_add_attribute(hdr, RTA_PRIORITY, chunk, sizeof(request));
-
- return this->socket->send_ack(this->socket, hdr);
-}
-
-/**
- * Implementation of kernel_netlink_net_t.destroy.
- */
-static void destroy(private_kernel_netlink_net_t *this)
-{
- if (this->routing_table)
- {
- manage_rule(this, RTM_DELRULE, AF_INET, this->routing_table,
- this->routing_table_prio);
- manage_rule(this, RTM_DELRULE, AF_INET6, this->routing_table,
- this->routing_table_prio);
- }
- if (this->job)
- {
- this->job->cancel(this->job);
- }
- if (this->socket_events > 0)
- {
- close(this->socket_events);
- }
- DESTROY_IF(this->socket);
- this->ifaces->destroy_function(this->ifaces, (void*)iface_entry_destroy);
- this->rt_exclude->destroy(this->rt_exclude);
- this->condvar->destroy(this->condvar);
- this->mutex->destroy(this->mutex);
- free(this);
-}
-
-/*
- * Described in header.
- */
-kernel_netlink_net_t *kernel_netlink_net_create()
-{
- private_kernel_netlink_net_t *this = malloc_thing(private_kernel_netlink_net_t);
- struct sockaddr_nl addr;
- enumerator_t *enumerator;
- char *exclude;
-
- /* public functions */
- this->public.interface.get_interface = (char*(*)(kernel_net_t*,host_t*))get_interface_name;
- this->public.interface.create_address_enumerator = (enumerator_t*(*)(kernel_net_t*,bool,bool))create_address_enumerator;
- this->public.interface.get_source_addr = (host_t*(*)(kernel_net_t*, host_t *dest, host_t *src))get_source_addr;
- this->public.interface.get_nexthop = (host_t*(*)(kernel_net_t*, host_t *dest))get_nexthop;
- this->public.interface.add_ip = (status_t(*)(kernel_net_t*,host_t*,host_t*)) add_ip;
- this->public.interface.del_ip = (status_t(*)(kernel_net_t*,host_t*)) del_ip;
- this->public.interface.add_route = (status_t(*)(kernel_net_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) add_route;
- this->public.interface.del_route = (status_t(*)(kernel_net_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) del_route;
- this->public.interface.destroy = (void(*)(kernel_net_t*)) destroy;
-
- /* private members */
- this->ifaces = linked_list_create();
- this->mutex = mutex_create(MUTEX_TYPE_RECURSIVE);
- this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT);
- timerclear(&this->last_roam);
- this->routing_table = lib->settings->get_int(lib->settings,
- "charon.routing_table", ROUTING_TABLE);
- this->routing_table_prio = lib->settings->get_int(lib->settings,
- "charon.routing_table_prio", ROUTING_TABLE_PRIO);
- this->process_route = lib->settings->get_bool(lib->settings,
- "charon.process_route", TRUE);
- this->install_virtual_ip = lib->settings->get_bool(lib->settings,
- "charon.install_virtual_ip", TRUE);
-
- this->rt_exclude = linked_list_create();
- exclude = lib->settings->get_str(lib->settings,
- "charon.ignore_routing_tables", NULL);
- if (exclude)
- {
- char *token;
- uintptr_t table;
-
- enumerator = enumerator_create_token(exclude, " ", " ");
- while (enumerator->enumerate(enumerator, &token))
- {
- errno = 0;
- table = strtoul(token, NULL, 10);
-
- if (errno == 0)
- {
- this->rt_exclude->insert_last(this->rt_exclude, (void*)table);
- }
- }
- enumerator->destroy(enumerator);
- }
-
- this->socket = netlink_socket_create(NETLINK_ROUTE);
- this->job = NULL;
-
- memset(&addr, 0, sizeof(addr));
- addr.nl_family = AF_NETLINK;
-
- /* create and bind RT socket for events (address/interface/route changes) */
- this->socket_events = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (this->socket_events < 0)
- {
- DBG1(DBG_KNL, "unable to create RT event socket");
- destroy(this);
- return NULL;
- }
- addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR |
- RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_ROUTE | RTMGRP_LINK;
- if (bind(this->socket_events, (struct sockaddr*)&addr, sizeof(addr)))
- {
- DBG1(DBG_KNL, "unable to bind RT event socket");
- destroy(this);
- return NULL;
- }
-
- this->job = callback_job_create((callback_job_cb_t)receive_events,
- this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
-
- if (init_address_list(this) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to get interface list");
- destroy(this);
- return NULL;
- }
-
- if (this->routing_table)
- {
- if (manage_rule(this, RTM_NEWRULE, AF_INET, this->routing_table,
- this->routing_table_prio) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to create IPv4 routing table rule");
- }
- if (manage_rule(this, RTM_NEWRULE, AF_INET6, this->routing_table,
- this->routing_table_prio) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to create IPv6 routing table rule");
- }
- }
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h
deleted file mode 100644
index ff9831d3c..000000000
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup kernel_netlink_net_i kernel_netlink_net
- * @{ @ingroup kernel_netlink
- */
-
-#ifndef KERNEL_NETLINK_NET_H_
-#define KERNEL_NETLINK_NET_H_
-
-#include <kernel/kernel_net.h>
-
-typedef struct kernel_netlink_net_t kernel_netlink_net_t;
-
-/**
- * Implementation of the kernel network interface using Netlink.
- */
-struct kernel_netlink_net_t {
-
- /**
- * Implements kernel_net_t interface
- */
- kernel_net_t interface;
-};
-
-/**
- * Create a netlink kernel network interface instance.
- *
- * @return kernel_netlink_net_t instance
- */
-kernel_netlink_net_t *kernel_netlink_net_create();
-
-#endif /** KERNEL_NETLINK_NET_H_ @}*/
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c
deleted file mode 100644
index 4c61265aa..000000000
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-
-#include "kernel_netlink_plugin.h"
-
-#include "kernel_netlink_ipsec.h"
-#include "kernel_netlink_net.h"
-
-#include <daemon.h>
-
-typedef struct private_kernel_netlink_plugin_t private_kernel_netlink_plugin_t;
-
-/**
- * private data of kernel netlink plugin
- */
-struct private_kernel_netlink_plugin_t {
- /**
- * implements plugin interface
- */
- kernel_netlink_plugin_t public;
-};
-
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(private_kernel_netlink_plugin_t *this)
-{
- charon->kernel_interface->remove_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_netlink_ipsec_create);
- charon->kernel_interface->remove_net_interface(charon->kernel_interface, (kernel_net_constructor_t)kernel_netlink_net_create);
- free(this);
-}
-
-/*
- * see header file
- */
-plugin_t *kernel_netlink_plugin_create()
-{
- private_kernel_netlink_plugin_t *this = malloc_thing(private_kernel_netlink_plugin_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
-
- charon->kernel_interface->add_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_netlink_ipsec_create);
- charon->kernel_interface->add_net_interface(charon->kernel_interface, (kernel_net_constructor_t)kernel_netlink_net_create);
-
- return &this->public.plugin;
-}
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
deleted file mode 100644
index 5ed568150..000000000
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "kernel_netlink_shared.h"
-
-#include <daemon.h>
-#include <threading/mutex.h>
-
-typedef struct private_netlink_socket_t private_netlink_socket_t;
-
-/**
- * Private variables and functions of netlink_socket_t class.
- */
-struct private_netlink_socket_t {
- /**
- * public part of the netlink_socket_t object.
- */
- netlink_socket_t public;
-
- /**
- * mutex to lock access to netlink socket
- */
- mutex_t *mutex;
-
- /**
- * current sequence number for netlink request
- */
- int seq;
-
- /**
- * netlink socket protocol
- */
- int protocol;
-
- /**
- * netlink socket
- */
- int socket;
-};
-
-/**
- * Imported from kernel_netlink_ipsec.c
- */
-extern enum_name_t *xfrm_msg_names;
-
-/**
- * Implementation of netlink_socket_t.send
- */
-static status_t netlink_send(private_netlink_socket_t *this, struct nlmsghdr *in,
- struct nlmsghdr **out, size_t *out_len)
-{
- int len, addr_len;
- struct sockaddr_nl addr;
- chunk_t result = chunk_empty, tmp;
- struct nlmsghdr *msg, peek;
-
- this->mutex->lock(this->mutex);
-
- in->nlmsg_seq = ++this->seq;
- in->nlmsg_pid = getpid();
-
- memset(&addr, 0, sizeof(addr));
- addr.nl_family = AF_NETLINK;
- addr.nl_pid = 0;
- addr.nl_groups = 0;
-
- if (this->protocol == NETLINK_XFRM)
- {
- chunk_t in_chunk = { (u_char*)in, in->nlmsg_len };
-
- DBG3(DBG_KNL, "sending %N: %B", xfrm_msg_names, in->nlmsg_type, &in_chunk);
- }
-
- while (TRUE)
- {
- len = sendto(this->socket, in, in->nlmsg_len, 0,
- (struct sockaddr*)&addr, sizeof(addr));
-
- if (len != in->nlmsg_len)
- {
- if (errno == EINTR)
- {
- /* interrupted, try again */
- continue;
- }
- this->mutex->unlock(this->mutex);
- DBG1(DBG_KNL, "error sending to netlink socket: %s", strerror(errno));
- return FAILED;
- }
- break;
- }
-
- while (TRUE)
- {
- char buf[4096];
- tmp.len = sizeof(buf);
- tmp.ptr = buf;
- msg = (struct nlmsghdr*)tmp.ptr;
-
- memset(&addr, 0, sizeof(addr));
- addr.nl_family = AF_NETLINK;
- addr.nl_pid = getpid();
- addr.nl_groups = 0;
- addr_len = sizeof(addr);
-
- len = recvfrom(this->socket, tmp.ptr, tmp.len, 0,
- (struct sockaddr*)&addr, &addr_len);
-
- if (len < 0)
- {
- if (errno == EINTR)
- {
- DBG1(DBG_KNL, "got interrupted");
- /* interrupted, try again */
- continue;
- }
- DBG1(DBG_KNL, "error reading from netlink socket: %s", strerror(errno));
- this->mutex->unlock(this->mutex);
- free(result.ptr);
- return FAILED;
- }
- if (!NLMSG_OK(msg, len))
- {
- DBG1(DBG_KNL, "received corrupted netlink message");
- this->mutex->unlock(this->mutex);
- free(result.ptr);
- return FAILED;
- }
- if (msg->nlmsg_seq != this->seq)
- {
- DBG1(DBG_KNL, "received invalid netlink sequence number");
- if (msg->nlmsg_seq < this->seq)
- {
- continue;
- }
- this->mutex->unlock(this->mutex);
- free(result.ptr);
- return FAILED;
- }
-
- tmp.len = len;
- result.ptr = realloc(result.ptr, result.len + tmp.len);
- memcpy(result.ptr + result.len, tmp.ptr, tmp.len);
- result.len += tmp.len;
-
- /* NLM_F_MULTI flag does not seem to be set correctly, we use sequence
- * numbers to detect multi header messages */
- len = recvfrom(this->socket, &peek, sizeof(peek), MSG_PEEK | MSG_DONTWAIT,
- (struct sockaddr*)&addr, &addr_len);
-
- if (len == sizeof(peek) && peek.nlmsg_seq == this->seq)
- {
- /* seems to be multipart */
- continue;
- }
- break;
- }
-
- *out_len = result.len;
- *out = (struct nlmsghdr*)result.ptr;
-
- this->mutex->unlock(this->mutex);
-
- return SUCCESS;
-}
-
-/**
- * Implementation of netlink_socket_t.send_ack.
- */
-static status_t netlink_send_ack(private_netlink_socket_t *this, struct nlmsghdr *in)
-{
- struct nlmsghdr *out, *hdr;
- size_t len;
-
- if (netlink_send(this, in, &out, &len) != SUCCESS)
- {
- return FAILED;
- }
- hdr = out;
- while (NLMSG_OK(hdr, len))
- {
- switch (hdr->nlmsg_type)
- {
- case NLMSG_ERROR:
- {
- struct nlmsgerr* err = (struct nlmsgerr*)NLMSG_DATA(hdr);
-
- if (err->error)
- {
- if (-err->error == EEXIST)
- { /* do not report existing routes */
- free(out);
- return ALREADY_DONE;
- }
- DBG1(DBG_KNL, "received netlink error: %s (%d)",
- strerror(-err->error), -err->error);
- free(out);
- return FAILED;
- }
- free(out);
- return SUCCESS;
- }
- default:
- hdr = NLMSG_NEXT(hdr, len);
- continue;
- case NLMSG_DONE:
- break;
- }
- break;
- }
- DBG1(DBG_KNL, "netlink request not acknowledged");
- free(out);
- return FAILED;
-}
-
-/**
- * Implementation of netlink_socket_t.destroy.
- */
-static void destroy(private_netlink_socket_t *this)
-{
- if (this->socket > 0)
- {
- close(this->socket);
- }
- this->mutex->destroy(this->mutex);
- free(this);
-}
-
-/**
- * Described in header.
- */
-netlink_socket_t *netlink_socket_create(int protocol)
-{
- private_netlink_socket_t *this = malloc_thing(private_netlink_socket_t);
- struct sockaddr_nl addr;
-
- /* public functions */
- this->public.send = (status_t(*)(netlink_socket_t*,struct nlmsghdr*, struct nlmsghdr**, size_t*))netlink_send;
- this->public.send_ack = (status_t(*)(netlink_socket_t*,struct nlmsghdr*))netlink_send_ack;
- this->public.destroy = (void(*)(netlink_socket_t*))destroy;
-
- /* private members */
- this->seq = 200;
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
-
- memset(&addr, 0, sizeof(addr));
- addr.nl_family = AF_NETLINK;
-
- this->protocol = protocol;
- this->socket = socket(AF_NETLINK, SOCK_RAW, protocol);
- if (this->socket < 0)
- {
- DBG1(DBG_KNL, "unable to create netlink socket");
- destroy(this);
- return NULL;
- }
-
- addr.nl_groups = 0;
- if (bind(this->socket, (struct sockaddr*)&addr, sizeof(addr)))
- {
- DBG1(DBG_KNL, "unable to bind netlink socket");
- destroy(this);
- return NULL;
- }
-
- return &this->public;
-}
-
-/**
- * Described in header.
- */
-void netlink_add_attribute(struct nlmsghdr *hdr, int rta_type, chunk_t data,
- size_t buflen)
-{
- struct rtattr *rta;
-
- if (NLMSG_ALIGN(hdr->nlmsg_len) + RTA_ALIGN(data.len) > buflen)
- {
- DBG1(DBG_KNL, "unable to add attribute, buffer too small");
- return;
- }
-
- rta = (struct rtattr*)(((char*)hdr) + NLMSG_ALIGN(hdr->nlmsg_len));
- rta->rta_type = rta_type;
- rta->rta_len = RTA_LENGTH(data.len);
- memcpy(RTA_DATA(rta), data.ptr, data.len);
- hdr->nlmsg_len = NLMSG_ALIGN(hdr->nlmsg_len) + rta->rta_len;
-}
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h
deleted file mode 100644
index dfd27a21a..000000000
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#ifndef KERNEL_NETLINK_SHARED_H_
-#define KERNEL_NETLINK_SHARED_H_
-
-#include <library.h>
-
-#include <linux/rtnetlink.h>
-
-/**
- * General purpose netlink buffer.
- *
- * 1024 byte is currently sufficient for all operations. Some platform
- * require an enforced aligment to four bytes (e.g. ARM).
- */
-typedef u_char netlink_buf_t[1024] __attribute__((aligned(RTA_ALIGNTO)));
-
-typedef struct netlink_socket_t netlink_socket_t;
-
-/**
- * Wrapper around a netlink socket.
- */
-struct netlink_socket_t {
-
- /**
- * Send a netlink message and wait for a reply.
- *
- * @param in netlink message to send
- * @param out received netlink message
- * @param out_len length of the received message
- */
- status_t (*send)(netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out, size_t *out_len);
-
- /**
- * Send a netlink message and wait for its acknowledge.
- *
- * @param in netlink message to send
- */
- status_t (*send_ack)(netlink_socket_t *this, struct nlmsghdr *in);
-
- /**
- * Destroy the socket.
- */
- void (*destroy)(netlink_socket_t *this);
-};
-
-/**
- * Create a netlink_socket_t object.
- *
- * @param protocol protocol type (e.g. NETLINK_XFRM or NETLINK_ROUTE)
- */
-netlink_socket_t *netlink_socket_create(int protocol);
-
-/**
- * Creates an rtattr and adds it to the given netlink message.
- *
- * @param hdr netlink message
- * @param rta_type type of the rtattr
- * @param data data to add to the rtattr
- * @param buflen length of the netlink message buffer
- */
-void netlink_add_attribute(struct nlmsghdr *hdr, int rta_type, chunk_t data, size_t buflen);
-
-#endif /* KERNEL_NETLINK_SHARED_H_ */
diff --git a/src/libcharon/plugins/kernel_pfkey/Makefile.am b/src/libcharon/plugins/kernel_pfkey/Makefile.am
deleted file mode 100644
index 778a7f9a9..000000000
--- a/src/libcharon/plugins/kernel_pfkey/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-
-INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \
- -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon
-
-AM_CFLAGS = -rdynamic
-
-if MONOLITHIC
-noinst_LTLIBRARIES = libstrongswan-kernel-pfkey.la
-else
-plugin_LTLIBRARIES = libstrongswan-kernel-pfkey.la
-endif
-
-libstrongswan_kernel_pfkey_la_SOURCES = \
- kernel_pfkey_plugin.h kernel_pfkey_plugin.c \
- kernel_pfkey_ipsec.h kernel_pfkey_ipsec.c
-
-libstrongswan_kernel_pfkey_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
deleted file mode 100644
index a64c27f6f..000000000
--- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ /dev/null
@@ -1,2210 +0,0 @@
-/*
- * Copyright (C) 2008-2010 Tobias Brunner
- * Copyright (C) 2008 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#ifdef __FreeBSD__
-#include <limits.h> /* for LONG_MAX */
-#endif
-
-#ifdef HAVE_NET_PFKEYV2_H
-#include <net/pfkeyv2.h>
-#else
-#include <stdint.h>
-#include <linux/pfkeyv2.h>
-#endif
-
-#ifdef SADB_X_EXT_NAT_T_TYPE
-#define HAVE_NATT
-#endif
-
-#ifdef HAVE_NETIPSEC_IPSEC_H
-#include <netipsec/ipsec.h>
-#elif defined(HAVE_NETINET6_IPSEC_H)
-#include <netinet6/ipsec.h>
-#else
-#include <linux/ipsec.h>
-#endif
-
-#ifdef HAVE_NATT
-#ifdef HAVE_LINUX_UDP_H
-#include <linux/udp.h>
-#else
-#include <netinet/udp.h>
-#endif /*HAVE_LINUX_UDP_H*/
-#endif /*HAVE_NATT*/
-
-#include <unistd.h>
-#include <time.h>
-#include <errno.h>
-
-#include "kernel_pfkey_ipsec.h"
-
-#include <daemon.h>
-#include <utils/host.h>
-#include <threading/thread.h>
-#include <threading/mutex.h>
-#include <processing/jobs/callback_job.h>
-#include <processing/jobs/acquire_job.h>
-#include <processing/jobs/migrate_job.h>
-#include <processing/jobs/rekey_child_sa_job.h>
-#include <processing/jobs/delete_child_sa_job.h>
-#include <processing/jobs/update_sa_job.h>
-
-/** non linux specific */
-#ifndef IPPROTO_COMP
-#ifdef IPPROTO_IPCOMP
-#define IPPROTO_COMP IPPROTO_IPCOMP
-#endif
-#endif
-
-#ifndef SADB_X_AALG_SHA2_256HMAC
-#define SADB_X_AALG_SHA2_256HMAC SADB_X_AALG_SHA2_256
-#define SADB_X_AALG_SHA2_384HMAC SADB_X_AALG_SHA2_384
-#define SADB_X_AALG_SHA2_512HMAC SADB_X_AALG_SHA2_512
-#endif
-
-#ifndef SADB_X_EALG_AESCBC
-#define SADB_X_EALG_AESCBC SADB_X_EALG_AES
-#endif
-
-#ifndef SADB_X_EALG_CASTCBC
-#define SADB_X_EALG_CASTCBC SADB_X_EALG_CAST128CBC
-#endif
-
-#ifndef SOL_IP
-#define SOL_IP IPPROTO_IP
-#define SOL_IPV6 IPPROTO_IPV6
-#endif
-
-/** from linux/in.h */
-#ifndef IP_IPSEC_POLICY
-#define IP_IPSEC_POLICY 16
-#endif
-
-/** missing on uclibc */
-#ifndef IPV6_IPSEC_POLICY
-#define IPV6_IPSEC_POLICY 34
-#endif
-
-/** default priority of installed policies */
-#define PRIO_LOW 3000
-#define PRIO_HIGH 2000
-
-#ifdef __APPLE__
-/** from xnu/bsd/net/pfkeyv2.h */
-#define SADB_X_EXT_NATT 0x002
- struct sadb_sa_2 {
- struct sadb_sa sa;
- u_int16_t sadb_sa_natt_port;
- u_int16_t sadb_reserved0;
- u_int32_t sadb_reserved1;
- };
-#endif
-
-/** buffer size for PF_KEY messages */
-#define PFKEY_BUFFER_SIZE 4096
-
-/** PF_KEY messages are 64 bit aligned */
-#define PFKEY_ALIGNMENT 8
-/** aligns len to 64 bits */
-#define PFKEY_ALIGN(len) (((len) + PFKEY_ALIGNMENT - 1) & ~(PFKEY_ALIGNMENT - 1))
-/** calculates the properly padded length in 64 bit chunks */
-#define PFKEY_LEN(len) ((PFKEY_ALIGN(len) / PFKEY_ALIGNMENT))
-/** calculates user mode length i.e. in bytes */
-#define PFKEY_USER_LEN(len) ((len) * PFKEY_ALIGNMENT)
-
-/** given a PF_KEY message header and an extension this updates the length in the header */
-#define PFKEY_EXT_ADD(msg, ext) ((msg)->sadb_msg_len += ((struct sadb_ext*)ext)->sadb_ext_len)
-/** given a PF_KEY message header this returns a pointer to the next extension */
-#define PFKEY_EXT_ADD_NEXT(msg) ((struct sadb_ext*)(((char*)(msg)) + PFKEY_USER_LEN((msg)->sadb_msg_len)))
-/** copy an extension and append it to a PF_KEY message */
-#define PFKEY_EXT_COPY(msg, ext) (PFKEY_EXT_ADD(msg, memcpy(PFKEY_EXT_ADD_NEXT(msg), ext, PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len))))
-/** given a PF_KEY extension this returns a pointer to the next extension */
-#define PFKEY_EXT_NEXT(ext) ((struct sadb_ext*)(((char*)(ext)) + PFKEY_USER_LEN(((struct sadb_ext*)ext)->sadb_ext_len)))
-/** given a PF_KEY extension this returns a pointer to the next extension also updates len (len in 64 bit words) */
-#define PFKEY_EXT_NEXT_LEN(ext,len) ((len) -= (ext)->sadb_ext_len, PFKEY_EXT_NEXT(ext))
-/** true if ext has a valid length and len is large enough to contain ext (assuming len in 64 bit words) */
-#define PFKEY_EXT_OK(ext,len) ((len) >= PFKEY_LEN(sizeof(struct sadb_ext)) && \
- (ext)->sadb_ext_len >= PFKEY_LEN(sizeof(struct sadb_ext)) && \
- (ext)->sadb_ext_len <= (len))
-
-typedef struct private_kernel_pfkey_ipsec_t private_kernel_pfkey_ipsec_t;
-
-/**
- * Private variables and functions of kernel_pfkey class.
- */
-struct private_kernel_pfkey_ipsec_t
-{
- /**
- * Public part of the kernel_pfkey_t object.
- */
- kernel_pfkey_ipsec_t public;
-
- /**
- * mutex to lock access to various lists
- */
- mutex_t *mutex;
-
- /**
- * List of installed policies (policy_entry_t)
- */
- linked_list_t *policies;
-
- /**
- * whether to install routes along policies
- */
- bool install_routes;
-
- /**
- * job receiving PF_KEY events
- */
- callback_job_t *job;
-
- /**
- * mutex to lock access to the PF_KEY socket
- */
- mutex_t *mutex_pfkey;
-
- /**
- * PF_KEY socket to communicate with the kernel
- */
- int socket;
-
- /**
- * PF_KEY socket to receive acquire and expire events
- */
- int socket_events;
-
- /**
- * sequence number for messages sent to the kernel
- */
- int seq;
-};
-
-typedef struct route_entry_t route_entry_t;
-
-/**
- * installed routing entry
- */
-struct route_entry_t {
- /** Name of the interface the route is bound to */
- char *if_name;
-
- /** Source ip of the route */
- host_t *src_ip;
-
- /** gateway for this route */
- host_t *gateway;
-
- /** Destination net */
- chunk_t dst_net;
-
- /** Destination net prefixlen */
- u_int8_t prefixlen;
-};
-
-/**
- * destroy an route_entry_t object
- */
-static void route_entry_destroy(route_entry_t *this)
-{
- free(this->if_name);
- DESTROY_IF(this->src_ip);
- DESTROY_IF(this->gateway);
- chunk_free(&this->dst_net);
- free(this);
-}
-
-typedef struct policy_entry_t policy_entry_t;
-
-/**
- * installed kernel policy.
- */
-struct policy_entry_t {
-
- /** reqid of this policy */
- u_int32_t reqid;
-
- /** index assigned by the kernel */
- u_int32_t index;
-
- /** direction of this policy: in, out, forward */
- u_int8_t direction;
-
- /** parameters of installed policy */
- struct {
- /** subnet and port */
- host_t *net;
- /** subnet mask */
- u_int8_t mask;
- /** protocol */
- u_int8_t proto;
- } src, dst;
-
- /** associated route installed for this policy */
- route_entry_t *route;
-
- /** by how many CHILD_SA's this policy is used */
- u_int refcount;
-};
-
-/**
- * create a policy_entry_t object
- */
-static policy_entry_t *create_policy_entry(traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t dir, u_int32_t reqid)
-{
- policy_entry_t *policy = malloc_thing(policy_entry_t);
- policy->reqid = reqid;
- policy->index = 0;
- policy->direction = dir;
- policy->route = NULL;
- policy->refcount = 0;
-
- src_ts->to_subnet(src_ts, &policy->src.net, &policy->src.mask);
- dst_ts->to_subnet(dst_ts, &policy->dst.net, &policy->dst.mask);
-
- /* src or dest proto may be "any" (0), use more restrictive one */
- policy->src.proto = max(src_ts->get_protocol(src_ts), dst_ts->get_protocol(dst_ts));
- policy->src.proto = policy->src.proto ? policy->src.proto : IPSEC_PROTO_ANY;
- policy->dst.proto = policy->src.proto;
-
- return policy;
-}
-
-/**
- * destroy a policy_entry_t object
- */
-static void policy_entry_destroy(policy_entry_t *this)
-{
- DESTROY_IF(this->src.net);
- DESTROY_IF(this->dst.net);
- if (this->route)
- {
- route_entry_destroy(this->route);
- }
- free(this);
-}
-
-/**
- * compares two policy_entry_t
- */
-static inline bool policy_entry_equals(policy_entry_t *current, policy_entry_t *policy)
-{
- return current->direction == policy->direction &&
- current->src.proto == policy->src.proto &&
- current->dst.proto == policy->dst.proto &&
- current->src.mask == policy->src.mask &&
- current->dst.mask == policy->dst.mask &&
- current->src.net->equals(current->src.net, policy->src.net) &&
- current->dst.net->equals(current->dst.net, policy->dst.net);
-}
-
-/**
- * compare the given kernel index with that of a policy
- */
-static inline bool policy_entry_match_byindex(policy_entry_t *current, u_int32_t *index)
-{
- return current->index == *index;
-}
-
-typedef struct pfkey_msg_t pfkey_msg_t;
-
-struct pfkey_msg_t
-{
- /**
- * PF_KEY message base
- */
- struct sadb_msg *msg;
-
- /**
- * PF_KEY message extensions
- */
- union {
- struct sadb_ext *ext[SADB_EXT_MAX + 1];
- struct {
- struct sadb_ext *reserved; /* SADB_EXT_RESERVED */
- struct sadb_sa *sa; /* SADB_EXT_SA */
- struct sadb_lifetime *lft_current; /* SADB_EXT_LIFETIME_CURRENT */
- struct sadb_lifetime *lft_hard; /* SADB_EXT_LIFETIME_HARD */
- struct sadb_lifetime *lft_soft; /* SADB_EXT_LIFETIME_SOFT */
- struct sadb_address *src; /* SADB_EXT_ADDRESS_SRC */
- struct sadb_address *dst; /* SADB_EXT_ADDRESS_DST */
- struct sadb_address *proxy; /* SADB_EXT_ADDRESS_PROXY */
- struct sadb_key *key_auth; /* SADB_EXT_KEY_AUTH */
- struct sadb_key *key_encr; /* SADB_EXT_KEY_ENCRYPT */
- struct sadb_ident *id_src; /* SADB_EXT_IDENTITY_SRC */
- struct sadb_ident *id_dst; /* SADB_EXT_IDENTITY_DST */
- struct sadb_sens *sensitivity; /* SADB_EXT_SENSITIVITY */
- struct sadb_prop *proposal; /* SADB_EXT_PROPOSAL */
- struct sadb_supported *supported_auth; /* SADB_EXT_SUPPORTED_AUTH */
- struct sadb_supported *supported_encr; /* SADB_EXT_SUPPORTED_ENCRYPT */
- struct sadb_spirange *spirange; /* SADB_EXT_SPIRANGE */
- struct sadb_x_kmprivate *x_kmprivate; /* SADB_X_EXT_KMPRIVATE */
- struct sadb_x_policy *x_policy; /* SADB_X_EXT_POLICY */
- struct sadb_x_sa2 *x_sa2; /* SADB_X_EXT_SA2 */
- struct sadb_x_nat_t_type *x_natt_type; /* SADB_X_EXT_NAT_T_TYPE */
- struct sadb_x_nat_t_port *x_natt_sport; /* SADB_X_EXT_NAT_T_SPORT */
- struct sadb_x_nat_t_port *x_natt_dport; /* SADB_X_EXT_NAT_T_DPORT */
- struct sadb_address *x_natt_oa; /* SADB_X_EXT_NAT_T_OA */
- struct sadb_x_sec_ctx *x_sec_ctx; /* SADB_X_EXT_SEC_CTX */
- struct sadb_x_kmaddress *x_kmaddress; /* SADB_X_EXT_KMADDRESS */
- } __attribute__((__packed__));
- };
-};
-
-ENUM(sadb_ext_type_names, SADB_EXT_RESERVED, SADB_EXT_MAX,
- "SADB_EXT_RESERVED",
- "SADB_EXT_SA",
- "SADB_EXT_LIFETIME_CURRENT",
- "SADB_EXT_LIFETIME_HARD",
- "SADB_EXT_LIFETIME_SOFT",
- "SADB_EXT_ADDRESS_SRC",
- "SADB_EXT_ADDRESS_DST",
- "SADB_EXT_ADDRESS_PROXY",
- "SADB_EXT_KEY_AUTH",
- "SADB_EXT_KEY_ENCRYPT",
- "SADB_EXT_IDENTITY_SRC",
- "SADB_EXT_IDENTITY_DST",
- "SADB_EXT_SENSITIVITY",
- "SADB_EXT_PROPOSAL",
- "SADB_EXT_SUPPORTED_AUTH",
- "SADB_EXT_SUPPORTED_ENCRYPT",
- "SADB_EXT_SPIRANGE",
- "SADB_X_EXT_KMPRIVATE",
- "SADB_X_EXT_POLICY",
- "SADB_X_EXT_SA2",
- "SADB_X_EXT_NAT_T_TYPE",
- "SADB_X_EXT_NAT_T_SPORT",
- "SADB_X_EXT_NAT_T_DPORT",
- "SADB_X_EXT_NAT_T_OA",
- "SADB_X_EXT_SEC_CTX",
- "SADB_X_EXT_KMADDRESS"
-);
-
-/**
- * convert a IKEv2 specific protocol identifier to the PF_KEY sa type
- */
-static u_int8_t proto_ike2satype(protocol_id_t proto)
-{
- switch (proto)
- {
- case PROTO_ESP:
- return SADB_SATYPE_ESP;
- case PROTO_AH:
- return SADB_SATYPE_AH;
- case IPPROTO_COMP:
- return SADB_X_SATYPE_IPCOMP;
- default:
- return proto;
- }
-}
-
-/**
- * convert a PF_KEY sa type to a IKEv2 specific protocol identifier
- */
-static protocol_id_t proto_satype2ike(u_int8_t proto)
-{
- switch (proto)
- {
- case SADB_SATYPE_ESP:
- return PROTO_ESP;
- case SADB_SATYPE_AH:
- return PROTO_AH;
- case SADB_X_SATYPE_IPCOMP:
- return IPPROTO_COMP;
- default:
- return proto;
- }
-}
-
-/**
- * convert a IKEv2 specific protocol identifier to the IP protocol identifier
- */
-static u_int8_t proto_ike2ip(protocol_id_t proto)
-{
- switch (proto)
- {
- case PROTO_ESP:
- return IPPROTO_ESP;
- case PROTO_AH:
- return IPPROTO_AH;
- default:
- return proto;
- }
-}
-
-/**
- * convert the general ipsec mode to the one defined in ipsec.h
- */
-static u_int8_t mode2kernel(ipsec_mode_t mode)
-{
- switch (mode)
- {
- case MODE_TRANSPORT:
- return IPSEC_MODE_TRANSPORT;
- case MODE_TUNNEL:
- return IPSEC_MODE_TUNNEL;
-#ifdef HAVE_IPSEC_MODE_BEET
- case MODE_BEET:
- return IPSEC_MODE_BEET;
-#endif
- default:
- return mode;
- }
-}
-
-/**
- * convert the general policy direction to the one defined in ipsec.h
- */
-static u_int8_t dir2kernel(policy_dir_t dir)
-{
- switch (dir)
- {
- case POLICY_IN:
- return IPSEC_DIR_INBOUND;
- case POLICY_OUT:
- return IPSEC_DIR_OUTBOUND;
-#ifdef HAVE_IPSEC_DIR_FWD
- case POLICY_FWD:
- return IPSEC_DIR_FWD;
-#endif
- default:
- return IPSEC_DIR_INVALID;
- }
-}
-
-#ifdef SADB_X_MIGRATE
-/**
- * convert the policy direction in ipsec.h to the general one.
- */
-static policy_dir_t kernel2dir(u_int8_t dir)
-{
- switch (dir)
- {
- case IPSEC_DIR_INBOUND:
- return POLICY_IN;
- case IPSEC_DIR_OUTBOUND:
- return POLICY_OUT;
-#ifdef HAVE_IPSEC_DIR_FWD
- case IPSEC_DIR_FWD:
- return POLICY_FWD;
-#endif
- default:
- return dir;
- }
-}
-#endif /*SADB_X_MIGRATE*/
-
-typedef struct kernel_algorithm_t kernel_algorithm_t;
-
-/**
- * Mapping of IKEv2 algorithms to PF_KEY algorithms
- */
-struct kernel_algorithm_t {
- /**
- * Identifier specified in IKEv2
- */
- int ikev2;
-
- /**
- * Identifier as defined in pfkeyv2.h
- */
- int kernel;
-};
-
-#define END_OF_LIST -1
-
-/**
- * Algorithms for encryption
- */
-static kernel_algorithm_t encryption_algs[] = {
-/* {ENCR_DES_IV64, 0 }, */
- {ENCR_DES, SADB_EALG_DESCBC },
- {ENCR_3DES, SADB_EALG_3DESCBC },
-/* {ENCR_RC5, 0 }, */
-/* {ENCR_IDEA, 0 }, */
- {ENCR_CAST, SADB_X_EALG_CASTCBC },
- {ENCR_BLOWFISH, SADB_X_EALG_BLOWFISHCBC },
-/* {ENCR_3IDEA, 0 }, */
-/* {ENCR_DES_IV32, 0 }, */
- {ENCR_NULL, SADB_EALG_NULL },
- {ENCR_AES_CBC, SADB_X_EALG_AESCBC },
-/* {ENCR_AES_CTR, SADB_X_EALG_AESCTR }, */
-/* {ENCR_AES_CCM_ICV8, SADB_X_EALG_AES_CCM_ICV8 }, */
-/* {ENCR_AES_CCM_ICV12, SADB_X_EALG_AES_CCM_ICV12 }, */
-/* {ENCR_AES_CCM_ICV16, SADB_X_EALG_AES_CCM_ICV16 }, */
-/* {ENCR_AES_GCM_ICV8, SADB_X_EALG_AES_GCM_ICV8 }, */
-/* {ENCR_AES_GCM_ICV12, SADB_X_EALG_AES_GCM_ICV12 }, */
-/* {ENCR_AES_GCM_ICV16, SADB_X_EALG_AES_GCM_ICV16 }, */
- {END_OF_LIST, 0 },
-};
-
-/**
- * Algorithms for integrity protection
- */
-static kernel_algorithm_t integrity_algs[] = {
- {AUTH_HMAC_MD5_96, SADB_AALG_MD5HMAC },
- {AUTH_HMAC_SHA1_96, SADB_AALG_SHA1HMAC },
- {AUTH_HMAC_SHA2_256_128, SADB_X_AALG_SHA2_256HMAC },
- {AUTH_HMAC_SHA2_384_192, SADB_X_AALG_SHA2_384HMAC },
- {AUTH_HMAC_SHA2_512_256, SADB_X_AALG_SHA2_512HMAC },
-/* {AUTH_DES_MAC, 0, }, */
-/* {AUTH_KPDK_MD5, 0, }, */
-#ifdef SADB_X_AALG_AES_XCBC_MAC
- {AUTH_AES_XCBC_96, SADB_X_AALG_AES_XCBC_MAC, },
-#endif
- {END_OF_LIST, 0, },
-};
-
-#if 0
-/**
- * Algorithms for IPComp, unused yet
- */
-static kernel_algorithm_t compression_algs[] = {
-/* {IPCOMP_OUI, 0 }, */
- {IPCOMP_DEFLATE, SADB_X_CALG_DEFLATE },
- {IPCOMP_LZS, SADB_X_CALG_LZS },
- {IPCOMP_LZJH, SADB_X_CALG_LZJH },
- {END_OF_LIST, 0 },
-};
-#endif
-
-/**
- * Look up a kernel algorithm ID and its key size
- */
-static int lookup_algorithm(kernel_algorithm_t *list, int ikev2)
-{
- while (list->ikev2 != END_OF_LIST)
- {
- if (ikev2 == list->ikev2)
- {
- return list->kernel;
- }
- list++;
- }
- return 0;
-}
-
-/**
- * Copy a host_t as sockaddr_t to the given memory location. Ports are
- * reset to zero as per RFC 2367.
- * @return the number of bytes copied
- */
-static size_t hostcpy(void *dest, host_t *host)
-{
- sockaddr_t *addr = host->get_sockaddr(host), *dest_addr = dest;
- socklen_t *len = host->get_sockaddr_len(host);
- memcpy(dest, addr, *len);
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- dest_addr->sa_len = *len;
-#endif
- switch (dest_addr->sa_family)
- {
- case AF_INET:
- {
- struct sockaddr_in *sin = dest;
- sin->sin_port = 0;
- break;
- }
- case AF_INET6:
- {
- struct sockaddr_in6 *sin6 = dest;
- sin6->sin6_port = 0;
- break;
- }
- }
- return *len;
-}
-
-/**
- * add a host behind an sadb_address extension
- */
-static void host2ext(host_t *host, struct sadb_address *ext)
-{
- size_t len = hostcpy(ext + 1, host);
- ext->sadb_address_len = PFKEY_LEN(sizeof(*ext) + len);
-}
-
-/**
- * add a host to the given sadb_msg
- */
-static void add_addr_ext(struct sadb_msg *msg, host_t *host, u_int16_t type,
- u_int8_t proto, u_int8_t prefixlen)
-{
- struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg);
- addr->sadb_address_exttype = type;
- addr->sadb_address_proto = proto;
- addr->sadb_address_prefixlen = prefixlen;
- host2ext(host, addr);
- PFKEY_EXT_ADD(msg, addr);
-}
-
-/**
- * adds an empty address extension to the given sadb_msg
- */
-static void add_anyaddr_ext(struct sadb_msg *msg, int family, u_int8_t type)
-{
- socklen_t len = (family == AF_INET) ? sizeof(struct sockaddr_in) :
- sizeof(struct sockaddr_in6);
- struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg);
- addr->sadb_address_exttype = type;
- sockaddr_t *saddr = (sockaddr_t*)(addr + 1);
- saddr->sa_family = family;
-#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
- saddr->sa_len = len;
-#endif
- addr->sadb_address_len = PFKEY_LEN(sizeof(*addr) + len);
- PFKEY_EXT_ADD(msg, addr);
-}
-
-#ifdef HAVE_NATT
-/**
- * add udp encap extensions to a sadb_msg
- */
-static void add_encap_ext(struct sadb_msg *msg, host_t *src, host_t *dst)
-{
- struct sadb_x_nat_t_type* nat_type;
- struct sadb_x_nat_t_port* nat_port;
-
- nat_type = (struct sadb_x_nat_t_type*)PFKEY_EXT_ADD_NEXT(msg);
- nat_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
- nat_type->sadb_x_nat_t_type_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_type));
- nat_type->sadb_x_nat_t_type_type = UDP_ENCAP_ESPINUDP;
- PFKEY_EXT_ADD(msg, nat_type);
-
- nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg);
- nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT;
- nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port));
- nat_port->sadb_x_nat_t_port_port = htons(src->get_port(src));
- PFKEY_EXT_ADD(msg, nat_port);
-
- nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg);
- nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT;
- nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port));
- nat_port->sadb_x_nat_t_port_port = htons(dst->get_port(dst));
- PFKEY_EXT_ADD(msg, nat_port);
-}
-#endif /*HAVE_NATT*/
-
-/**
- * Convert a sadb_address to a traffic_selector
- */
-static traffic_selector_t* sadb_address2ts(struct sadb_address *address)
-{
- traffic_selector_t *ts;
- host_t *host;
-
- /* The Linux 2.6 kernel does not set the protocol and port information
- * in the src and dst sadb_address extensions of the SADB_ACQUIRE message.
- */
- host = host_create_from_sockaddr((sockaddr_t*)&address[1]) ;
- ts = traffic_selector_create_from_subnet(host, address->sadb_address_prefixlen,
- address->sadb_address_proto, host->get_port(host));
- return ts;
-}
-
-/**
- * Parses a pfkey message received from the kernel
- */
-static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out)
-{
- struct sadb_ext* ext;
- size_t len;
-
- memset(out, 0, sizeof(pfkey_msg_t));
- out->msg = msg;
-
- len = msg->sadb_msg_len;
- len -= PFKEY_LEN(sizeof(struct sadb_msg));
-
- ext = (struct sadb_ext*)(((char*)msg) + sizeof(struct sadb_msg));
-
- while (len >= PFKEY_LEN(sizeof(struct sadb_ext)))
- {
- DBG3(DBG_KNL, " %N", sadb_ext_type_names, ext->sadb_ext_type);
- if (ext->sadb_ext_len < PFKEY_LEN(sizeof(struct sadb_ext)) ||
- ext->sadb_ext_len > len)
- {
- DBG1(DBG_KNL, "length of %N extension is invalid",
- sadb_ext_type_names, ext->sadb_ext_type);
- break;
- }
-
- if ((ext->sadb_ext_type > SADB_EXT_MAX) || (!ext->sadb_ext_type))
- {
- DBG1(DBG_KNL, "type of PF_KEY extension (%d) is invalid", ext->sadb_ext_type);
- break;
- }
-
- if (out->ext[ext->sadb_ext_type])
- {
- DBG1(DBG_KNL, "duplicate %N extension",
- sadb_ext_type_names, ext->sadb_ext_type);
- break;
- }
-
- out->ext[ext->sadb_ext_type] = ext;
- ext = PFKEY_EXT_NEXT_LEN(ext, len);
- }
-
- if (len)
- {
- DBG1(DBG_KNL, "PF_KEY message length is invalid");
- return FAILED;
- }
-
- return SUCCESS;
-}
-
-/**
- * Send a message to a specific PF_KEY socket and handle the response.
- */
-static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket,
- struct sadb_msg *in, struct sadb_msg **out, size_t *out_len)
-{
- unsigned char buf[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg;
- int in_len, len;
-
- this->mutex_pfkey->lock(this->mutex_pfkey);
-
- /* FIXME: our usage of sequence numbers is probably wrong. check RFC 2367,
- * in particular the behavior in response to an SADB_ACQUIRE. */
- in->sadb_msg_seq = ++this->seq;
- in->sadb_msg_pid = getpid();
-
- in_len = PFKEY_USER_LEN(in->sadb_msg_len);
-
- while (TRUE)
- {
- len = send(socket, in, in_len, 0);
-
- if (len != in_len)
- {
- if (errno == EINTR)
- {
- /* interrupted, try again */
- continue;
- }
- this->mutex_pfkey->unlock(this->mutex_pfkey);
- DBG1(DBG_KNL, "error sending to PF_KEY socket: %s", strerror(errno));
- return FAILED;
- }
- break;
- }
-
- while (TRUE)
- {
- msg = (struct sadb_msg*)buf;
-
- len = recv(socket, buf, sizeof(buf), 0);
-
- if (len < 0)
- {
- if (errno == EINTR)
- {
- DBG1(DBG_KNL, "got interrupted");
- /* interrupted, try again */
- continue;
- }
- DBG1(DBG_KNL, "error reading from PF_KEY socket: %s", strerror(errno));
- this->mutex_pfkey->unlock(this->mutex_pfkey);
- return FAILED;
- }
- if (len < sizeof(struct sadb_msg) ||
- msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg)))
- {
- DBG1(DBG_KNL, "received corrupted PF_KEY message");
- this->mutex_pfkey->unlock(this->mutex_pfkey);
- return FAILED;
- }
- if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT)
- {
- DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message");
- this->mutex_pfkey->unlock(this->mutex_pfkey);
- return FAILED;
- }
- if (msg->sadb_msg_pid != in->sadb_msg_pid)
- {
- DBG2(DBG_KNL, "received PF_KEY message is not intended for us");
- continue;
- }
- if (msg->sadb_msg_seq != this->seq)
- {
- DBG1(DBG_KNL, "received PF_KEY message with unexpected sequence "
- "number, was %d expected %d", msg->sadb_msg_seq, this->seq);
- if (msg->sadb_msg_seq == 0)
- {
- /* FreeBSD and Mac OS X do this for the response to
- * SADB_X_SPDGET (but not for the response to SADB_GET).
- * FreeBSD: 'key_spdget' in /usr/src/sys/netipsec/key.c. */
- }
- else if (msg->sadb_msg_seq < this->seq)
- {
- continue;
- }
- else
- {
- this->mutex_pfkey->unlock(this->mutex_pfkey);
- return FAILED;
- }
- }
- if (msg->sadb_msg_type != in->sadb_msg_type)
- {
- DBG2(DBG_KNL, "received PF_KEY message of wrong type, "
- "was %d expected %d, ignoring",
- msg->sadb_msg_type, in->sadb_msg_type);
- }
- break;
- }
-
- *out_len = len;
- *out = (struct sadb_msg*)malloc(len);
- memcpy(*out, buf, len);
-
- this->mutex_pfkey->unlock(this->mutex_pfkey);
-
- return SUCCESS;
-}
-
-/**
- * Send a message to the default PF_KEY socket and handle the response.
- */
-static status_t pfkey_send(private_kernel_pfkey_ipsec_t *this,
- struct sadb_msg *in, struct sadb_msg **out, size_t *out_len)
-{
- return pfkey_send_socket(this, this->socket, in, out, out_len);
-}
-
-/**
- * Process a SADB_ACQUIRE message from the kernel
- */
-static void process_acquire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
-{
- pfkey_msg_t response;
- u_int32_t index, reqid = 0;
- traffic_selector_t *src_ts, *dst_ts;
- policy_entry_t *policy;
- job_t *job;
-
- switch (msg->sadb_msg_satype)
- {
- case SADB_SATYPE_UNSPEC:
- case SADB_SATYPE_ESP:
- case SADB_SATYPE_AH:
- break;
- default:
- /* acquire for AH/ESP only */
- return;
- }
- DBG2(DBG_KNL, "received an SADB_ACQUIRE");
-
- if (parse_pfkey_message(msg, &response) != SUCCESS)
- {
- DBG1(DBG_KNL, "parsing SADB_ACQUIRE from kernel failed");
- return;
- }
-
- index = response.x_policy->sadb_x_policy_id;
- this->mutex->lock(this->mutex);
- if (this->policies->find_first(this->policies,
- (linked_list_match_t)policy_entry_match_byindex, (void**)&policy, &index) == SUCCESS)
- {
- reqid = policy->reqid;
- }
- else
- {
- DBG1(DBG_KNL, "received an SADB_ACQUIRE with policy id %d but no matching policy found",
- index);
- }
- src_ts = sadb_address2ts(response.src);
- dst_ts = sadb_address2ts(response.dst);
- this->mutex->unlock(this->mutex);
-
- DBG1(DBG_KNL, "creating acquire job for policy %R === %R with reqid {%u}",
- src_ts, dst_ts, reqid);
- job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts);
- charon->processor->queue_job(charon->processor, job);
-}
-
-/**
- * Process a SADB_EXPIRE message from the kernel
- */
-static void process_expire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
-{
- pfkey_msg_t response;
- protocol_id_t protocol;
- u_int32_t spi, reqid;
- bool hard;
- job_t *job;
-
- DBG2(DBG_KNL, "received an SADB_EXPIRE");
-
- if (parse_pfkey_message(msg, &response) != SUCCESS)
- {
- DBG1(DBG_KNL, "parsing SADB_EXPIRE from kernel failed");
- return;
- }
-
- protocol = proto_satype2ike(msg->sadb_msg_satype);
- spi = response.sa->sadb_sa_spi;
- reqid = response.x_sa2->sadb_x_sa2_reqid;
- hard = response.lft_hard != NULL;
-
- if (protocol != PROTO_ESP && protocol != PROTO_AH)
- {
- DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and reqid {%u} "
- "which is not a CHILD_SA", ntohl(spi), reqid);
- return;
- }
-
- DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%u}",
- hard ? "delete" : "rekey", protocol_id_names,
- protocol, ntohl(spi), reqid);
- if (hard)
- {
- job = (job_t*)delete_child_sa_job_create(reqid, protocol, spi);
- }
- else
- {
- job = (job_t*)rekey_child_sa_job_create(reqid, protocol, spi);
- }
- charon->processor->queue_job(charon->processor, job);
-}
-
-#ifdef SADB_X_MIGRATE
-/**
- * Process a SADB_X_MIGRATE message from the kernel
- */
-static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
-{
- pfkey_msg_t response;
- traffic_selector_t *src_ts, *dst_ts;
- policy_dir_t dir;
- u_int32_t reqid = 0;
- host_t *local = NULL, *remote = NULL;
- job_t *job;
-
- DBG2(DBG_KNL, "received an SADB_X_MIGRATE");
-
- if (parse_pfkey_message(msg, &response) != SUCCESS)
- {
- DBG1(DBG_KNL, "parsing SADB_X_MIGRATE from kernel failed");
- return;
- }
- src_ts = sadb_address2ts(response.src);
- dst_ts = sadb_address2ts(response.dst);
- dir = kernel2dir(response.x_policy->sadb_x_policy_dir);
- DBG2(DBG_KNL, " policy %R === %R %N, id %u", src_ts, dst_ts,
- policy_dir_names, dir);
-
- /* SADB_X_EXT_KMADDRESS is not present in unpatched kernels < 2.6.28 */
- if (response.x_kmaddress)
- {
- sockaddr_t *local_addr, *remote_addr;
- u_int32_t local_len;
-
- local_addr = (sockaddr_t*)&response.x_kmaddress[1];
- local = host_create_from_sockaddr(local_addr);
- local_len = (local_addr->sa_family == AF_INET6)?
- sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
- remote_addr = (sockaddr_t*)((u_int8_t*)local_addr + local_len);
- remote = host_create_from_sockaddr(remote_addr);
- DBG2(DBG_KNL, " kmaddress: %H...%H", local, remote);
- }
-
- if (src_ts && dst_ts && local && remote)
- {
- DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}",
- src_ts, dst_ts, policy_dir_names, dir, reqid, local);
- job = (job_t*)migrate_job_create(reqid, src_ts, dst_ts, dir,
- local, remote);
- charon->processor->queue_job(charon->processor, job);
- }
- else
- {
- DESTROY_IF(src_ts);
- DESTROY_IF(dst_ts);
- DESTROY_IF(local);
- DESTROY_IF(remote);
- }
-}
-#endif /*SADB_X_MIGRATE*/
-
-#ifdef SADB_X_NAT_T_NEW_MAPPING
-/**
- * Process a SADB_X_NAT_T_NEW_MAPPING message from the kernel
- */
-static void process_mapping(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
-{
- pfkey_msg_t response;
- u_int32_t spi, reqid;
- host_t *host;
- job_t *job;
-
- DBG2(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING");
-
- if (parse_pfkey_message(msg, &response) != SUCCESS)
- {
- DBG1(DBG_KNL, "parsing SADB_X_NAT_T_NEW_MAPPING from kernel failed");
- return;
- }
-
- if (!response.x_sa2)
- {
- DBG1(DBG_KNL, "received SADB_X_NAT_T_NEW_MAPPING is missing required information");
- return;
- }
-
- spi = response.sa->sadb_sa_spi;
- reqid = response.x_sa2->sadb_x_sa2_reqid;
-
- if (proto_satype2ike(msg->sadb_msg_satype) == PROTO_ESP)
- {
- sockaddr_t *sa = (sockaddr_t*)(response.dst + 1);
- switch (sa->sa_family)
- {
- case AF_INET:
- {
- struct sockaddr_in *sin = (struct sockaddr_in*)sa;
- sin->sin_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port);
- }
- case AF_INET6:
- {
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
- sin6->sin6_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port);
- }
- default:
- break;
- }
- host = host_create_from_sockaddr(sa);
- if (host)
- {
- DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and "
- "reqid {%u} changed, queuing update job", ntohl(spi), reqid);
- job = (job_t*)update_sa_job_create(reqid, host);
- charon->processor->queue_job(charon->processor, job);
- }
- }
-}
-#endif /*SADB_X_NAT_T_NEW_MAPPING*/
-
-/**
- * Receives events from kernel
- */
-static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this)
-{
- unsigned char buf[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg = (struct sadb_msg*)buf;
- int len;
- bool oldstate;
-
- oldstate = thread_cancelability(TRUE);
- len = recvfrom(this->socket_events, buf, sizeof(buf), 0, NULL, 0);
- thread_cancelability(oldstate);
-
- if (len < 0)
- {
- switch (errno)
- {
- case EINTR:
- /* interrupted, try again */
- return JOB_REQUEUE_DIRECT;
- case EAGAIN:
- /* no data ready, select again */
- return JOB_REQUEUE_DIRECT;
- default:
- DBG1(DBG_KNL, "unable to receive from PF_KEY event socket");
- sleep(1);
- return JOB_REQUEUE_FAIR;
- }
- }
-
- if (len < sizeof(struct sadb_msg) ||
- msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg)))
- {
- DBG2(DBG_KNL, "received corrupted PF_KEY message");
- return JOB_REQUEUE_DIRECT;
- }
- if (msg->sadb_msg_pid != 0)
- { /* not from kernel. not interested, try another one */
- return JOB_REQUEUE_DIRECT;
- }
- if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT)
- {
- DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message");
- return JOB_REQUEUE_DIRECT;
- }
-
- switch (msg->sadb_msg_type)
- {
- case SADB_ACQUIRE:
- process_acquire(this, msg);
- break;
- case SADB_EXPIRE:
- process_expire(this, msg);
- break;
-#ifdef SADB_X_MIGRATE
- case SADB_X_MIGRATE:
- process_migrate(this, msg);
- break;
-#endif /*SADB_X_MIGRATE*/
-#ifdef SADB_X_NAT_T_NEW_MAPPING
- case SADB_X_NAT_T_NEW_MAPPING:
- process_mapping(this, msg);
- break;
-#endif /*SADB_X_NAT_T_NEW_MAPPING*/
- default:
- break;
- }
-
- return JOB_REQUEUE_DIRECT;
-}
-
-METHOD(kernel_ipsec_t, get_spi, status_t,
- private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
- protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_x_sa2 *sa2;
- struct sadb_spirange *range;
- pfkey_msg_t response;
- u_int32_t received_spi = 0;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_GETSPI;
- msg->sadb_msg_satype = proto_ike2satype(protocol);
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg);
- sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange));
- sa2->sadb_x_sa2_reqid = reqid;
- PFKEY_EXT_ADD(msg, sa2);
-
- add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0);
- add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0);
-
- range = (struct sadb_spirange*)PFKEY_EXT_ADD_NEXT(msg);
- range->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
- range->sadb_spirange_len = PFKEY_LEN(sizeof(struct sadb_spirange));
- range->sadb_spirange_min = 0xc0000000;
- range->sadb_spirange_max = 0xcFFFFFFF;
- PFKEY_EXT_ADD(msg, range);
-
- if (pfkey_send(this, msg, &out, &len) == SUCCESS)
- {
- if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "allocating SPI failed: %s (%d)",
- strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- }
- else if (parse_pfkey_message(out, &response) == SUCCESS)
- {
- received_spi = response.sa->sadb_sa_spi;
- }
- free(out);
- }
-
- if (received_spi == 0)
- {
- return FAILED;
- }
-
- *spi = received_spi;
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, get_cpi, status_t,
- private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
-{
- return FAILED;
-}
-
-METHOD(kernel_ipsec_t, add_sa, status_t,
- private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi,
- protocol_id_t protocol, u_int32_t reqid, mark_t mark,
- lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
- u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
- u_int16_t ipcomp, u_int16_t cpi, bool encap, bool inbound,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_sa *sa;
- struct sadb_x_sa2 *sa2;
- struct sadb_lifetime *lft;
- struct sadb_key *key;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}", ntohl(spi), reqid);
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = inbound ? SADB_UPDATE : SADB_ADD;
- msg->sadb_msg_satype = proto_ike2satype(protocol);
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
-#ifdef __APPLE__
- if (encap)
- {
- struct sadb_sa_2 *sa_2;
- sa_2 = (struct sadb_sa_2*)PFKEY_EXT_ADD_NEXT(msg);
- sa_2->sadb_sa_natt_port = dst->get_port(dst);
- sa = &sa_2->sa;
- sa->sadb_sa_flags |= SADB_X_EXT_NATT;
- len = sizeof(struct sadb_sa_2);
- }
- else
-#endif
- {
- sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
- len = sizeof(struct sadb_sa);
- }
- sa->sadb_sa_exttype = SADB_EXT_SA;
- sa->sadb_sa_len = PFKEY_LEN(len);
- sa->sadb_sa_spi = spi;
- sa->sadb_sa_replay = (protocol == IPPROTO_COMP) ? 0 : 32;
- sa->sadb_sa_auth = lookup_algorithm(integrity_algs, int_alg);
- sa->sadb_sa_encrypt = lookup_algorithm(encryption_algs, enc_alg);
- PFKEY_EXT_ADD(msg, sa);
-
- sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg);
- sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
- sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange));
- sa2->sadb_x_sa2_mode = mode2kernel(mode);
- sa2->sadb_x_sa2_reqid = reqid;
- PFKEY_EXT_ADD(msg, sa2);
-
- add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0);
- add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0);
-
- lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg);
- lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
- lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime));
- lft->sadb_lifetime_allocations = lifetime->packets.rekey;
- lft->sadb_lifetime_bytes = lifetime->bytes.rekey;
- lft->sadb_lifetime_addtime = lifetime->time.rekey;
- lft->sadb_lifetime_usetime = 0; /* we only use addtime */
- PFKEY_EXT_ADD(msg, lft);
-
- lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg);
- lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
- lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime));
- lft->sadb_lifetime_allocations = lifetime->packets.life;
- lft->sadb_lifetime_bytes = lifetime->bytes.life;
- lft->sadb_lifetime_addtime = lifetime->time.life;
- lft->sadb_lifetime_usetime = 0; /* we only use addtime */
- PFKEY_EXT_ADD(msg, lft);
-
- if (enc_alg != ENCR_UNDEFINED)
- {
- if (!sa->sadb_sa_encrypt)
- {
- DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- encryption_algorithm_names, enc_alg);
- return FAILED;
- }
- DBG2(DBG_KNL, " using encryption algorithm %N with key size %d",
- encryption_algorithm_names, enc_alg, enc_key.len * 8);
-
- key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg);
- key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
- key->sadb_key_bits = enc_key.len * 8;
- key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + enc_key.len);
- memcpy(key + 1, enc_key.ptr, enc_key.len);
-
- PFKEY_EXT_ADD(msg, key);
- }
-
- if (int_alg != AUTH_UNDEFINED)
- {
- if (!sa->sadb_sa_auth)
- {
- DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- integrity_algorithm_names, int_alg);
- return FAILED;
- }
- DBG2(DBG_KNL, " using integrity algorithm %N with key size %d",
- integrity_algorithm_names, int_alg, int_key.len * 8);
-
- key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg);
- key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
- key->sadb_key_bits = int_key.len * 8;
- key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + int_key.len);
- memcpy(key + 1, int_key.ptr, int_key.len);
-
- PFKEY_EXT_ADD(msg, key);
- }
-
- if (ipcomp != IPCOMP_NONE)
- {
- /*TODO*/
- }
-
-#ifdef HAVE_NATT
- if (encap)
- {
- add_encap_ext(msg, src, dst);
- }
-#endif /*HAVE_NATT*/
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi));
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x: %s (%d)",
- ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
-
- free(out);
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, update_sa, status_t,
- private_kernel_pfkey_ipsec_t *this, u_int32_t spi, protocol_id_t protocol,
- u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
- bool encap, bool new_encap, mark_t mark)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_sa *sa;
- pfkey_msg_t response;
- size_t len;
-
- /* we can't update the SA if any of the ip addresses have changed.
- * that's because we can't use SADB_UPDATE and by deleting and readding the
- * SA the sequence numbers would get lost */
- if (!src->ip_equals(src, new_src) ||
- !dst->ip_equals(dst, new_dst))
- {
- DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: address changes"
- " are not supported", ntohl(spi));
- return NOT_SUPPORTED;
- }
-
- memset(&request, 0, sizeof(request));
-
- DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi));
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_GET;
- msg->sadb_msg_satype = proto_ike2satype(protocol);
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
- sa->sadb_sa_exttype = SADB_EXT_SA;
- sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
- sa->sadb_sa_spi = spi;
- PFKEY_EXT_ADD(msg, sa);
-
- /* the kernel wants a SADB_EXT_ADDRESS_SRC to be present even though
- * it is not used for anything. */
- add_anyaddr_ext(msg, dst->get_family(dst), SADB_EXT_ADDRESS_SRC);
- add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x",
- ntohl(spi));
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: %s (%d)",
- ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- else if (parse_pfkey_message(out, &response) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: parsing response "
- "from kernel failed", ntohl(spi));
- free(out);
- return FAILED;
- }
-
- DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H",
- ntohl(spi), src, dst, new_src, new_dst);
-
- memset(&request, 0, sizeof(request));
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_UPDATE;
- msg->sadb_msg_satype = proto_ike2satype(protocol);
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
-#ifdef __APPLE__
- {
- struct sadb_sa_2 *sa_2;
- sa_2 = (struct sadb_sa_2*)PFKEY_EXT_ADD_NEXT(msg);
- sa_2->sa.sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa_2));
- memcpy(&sa_2->sa, response.sa, sizeof(struct sadb_sa));
- if (encap)
- {
- sa_2->sadb_sa_natt_port = new_dst->get_port(new_dst);
- sa_2->sa.sadb_sa_flags |= SADB_X_EXT_NATT;
- }
- }
-#else
- PFKEY_EXT_COPY(msg, response.sa);
-#endif
- PFKEY_EXT_COPY(msg, response.x_sa2);
-
- PFKEY_EXT_COPY(msg, response.src);
- PFKEY_EXT_COPY(msg, response.dst);
-
- PFKEY_EXT_COPY(msg, response.lft_soft);
- PFKEY_EXT_COPY(msg, response.lft_hard);
-
- if (response.key_encr)
- {
- PFKEY_EXT_COPY(msg, response.key_encr);
- }
-
- if (response.key_auth)
- {
- PFKEY_EXT_COPY(msg, response.key_auth);
- }
-
-#ifdef HAVE_NATT
- if (new_encap)
- {
- add_encap_ext(msg, new_src, new_dst);
- }
-#endif /*HAVE_NATT*/
-
- free(out);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi));
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: %s (%d)",
- ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- free(out);
-
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, query_sa, status_t,
- private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_sa *sa;
- pfkey_msg_t response;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi));
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_GET;
- msg->sadb_msg_satype = proto_ike2satype(protocol);
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
- sa->sadb_sa_exttype = SADB_EXT_SA;
- sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
- sa->sadb_sa_spi = spi;
- PFKEY_EXT_ADD(msg, sa);
-
- /* the Linux Kernel doesn't care for the src address, but other systems do
- * (e.g. FreeBSD)
- */
- add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0);
- add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi));
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x: %s (%d)",
- ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- else if (parse_pfkey_message(out, &response) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi));
- free(out);
- return FAILED;
- }
- *bytes = response.lft_current->sadb_lifetime_bytes;
-
- free(out);
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, del_sa, status_t,
- private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_sa *sa;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi));
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_DELETE;
- msg->sadb_msg_satype = proto_ike2satype(protocol);
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg);
- sa->sadb_sa_exttype = SADB_EXT_SA;
- sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa));
- sa->sadb_sa_spi = spi;
- PFKEY_EXT_ADD(msg, sa);
-
- /* the Linux Kernel doesn't care for the src address, but other systems do
- * (e.g. FreeBSD)
- */
- add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0);
- add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi));
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x: %s (%d)",
- ntohl(spi), strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
-
- DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi));
- free(out);
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, add_policy, status_t,
- private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
- policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
- u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool routed)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_x_policy *pol;
- struct sadb_x_ipsecrequest *req;
- policy_entry_t *policy, *found = NULL;
- pfkey_msg_t response;
- size_t len;
-
- if (dir2kernel(direction) == IPSEC_DIR_INVALID)
- {
- /* FWD policies are not supported on all platforms */
- return SUCCESS;
- }
-
- /* create a policy */
- policy = create_policy_entry(src_ts, dst_ts, direction, reqid);
-
- /* find a matching policy */
- this->mutex->lock(this->mutex);
- if (this->policies->find_first(this->policies,
- (linked_list_match_t)policy_entry_equals, (void**)&found, policy) == SUCCESS)
- {
- /* use existing policy */
- found->refcount++;
- DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing "
- "refcount", src_ts, dst_ts,
- policy_dir_names, direction);
- policy_entry_destroy(policy);
- policy = found;
- }
- else
- {
- /* apply the new one, if we have no such policy */
- this->policies->insert_last(this->policies, policy);
- policy->refcount = 1;
- }
-
- memset(&request, 0, sizeof(request));
-
- DBG2(DBG_KNL, "adding policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = found ? SADB_X_SPDUPDATE : SADB_X_SPDADD;
- msg->sadb_msg_satype = 0;
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg);
- pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy));
- pol->sadb_x_policy_id = 0;
- pol->sadb_x_policy_dir = dir2kernel(direction);
- pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
-#ifdef HAVE_STRUCT_SADB_X_POLICY_SADB_X_POLICY_PRIORITY
- /* calculate priority based on source selector size, small size = high prio */
- pol->sadb_x_policy_priority = routed ? PRIO_LOW : PRIO_HIGH;
- pol->sadb_x_policy_priority -= policy->src.mask * 10;
- pol->sadb_x_policy_priority -= policy->src.proto != IPSEC_PROTO_ANY ? 2 : 0;
- pol->sadb_x_policy_priority -= policy->src.net->get_port(policy->src.net) ? 1 : 0;
-#endif
-
- /* one or more sadb_x_ipsecrequest extensions are added to the sadb_x_policy extension */
- req = (struct sadb_x_ipsecrequest*)(pol + 1);
- req->sadb_x_ipsecrequest_proto = proto_ike2ip(protocol);
- /* !!! the length of this struct MUST be in octets instead of 64 bit words */
- req->sadb_x_ipsecrequest_len = sizeof(struct sadb_x_ipsecrequest);
- req->sadb_x_ipsecrequest_mode = mode2kernel(mode);
- req->sadb_x_ipsecrequest_reqid = reqid;
- req->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
- if (mode == MODE_TUNNEL)
- {
- len = hostcpy(req + 1, src);
- req->sadb_x_ipsecrequest_len += len;
- len = hostcpy((char*)(req + 1) + len, dst);
- req->sadb_x_ipsecrequest_len += len;
- }
-
- pol->sadb_x_policy_len += PFKEY_LEN(req->sadb_x_ipsecrequest_len);
- PFKEY_EXT_ADD(msg, pol);
-
- add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto,
- policy->src.mask);
- add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto,
- policy->dst.mask);
-
-#ifdef __FreeBSD__
- { /* on FreeBSD a lifetime has to be defined to be able to later query
- * the current use time. */
- struct sadb_lifetime *lft;
- lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg);
- lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
- lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime));
- lft->sadb_lifetime_addtime = LONG_MAX;
- PFKEY_EXT_ADD(msg, lft);
- }
-#endif
-
- this->mutex->unlock(this->mutex);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to add policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to add policy %R === %R %N: %s (%d)", src_ts, dst_ts,
- policy_dir_names, direction,
- strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- else if (parse_pfkey_message(out, &response) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to add policy %R === %R %N: parsing response "
- "from kernel failed", src_ts, dst_ts, policy_dir_names, direction);
- free(out);
- return FAILED;
- }
-
- this->mutex->lock(this->mutex);
-
- /* we try to find the policy again and update the kernel index */
- if (this->policies->find_last(this->policies, NULL, (void**)&policy) != SUCCESS)
- {
- DBG2(DBG_KNL, "unable to update index, the policy %R === %R %N is "
- "already gone, ignoring", src_ts, dst_ts, policy_dir_names, direction);
- this->mutex->unlock(this->mutex);
- free(out);
- return SUCCESS;
- }
- policy->index = response.x_policy->sadb_x_policy_id;
- free(out);
-
- /* install a route, if:
- * - we are NOT updating a policy
- * - this is a forward policy (to just get one for each child)
- * - we are in tunnel mode
- * - we are not using IPv6 (does not work correctly yet!)
- * - routing is not disabled via strongswan.conf
- */
- if (policy->route == NULL && direction == POLICY_FWD &&
- mode != MODE_TRANSPORT && src->get_family(src) != AF_INET6 &&
- this->install_routes)
- {
- route_entry_t *route = malloc_thing(route_entry_t);
-
- if (charon->kernel_interface->get_address_by_ts(charon->kernel_interface,
- dst_ts, &route->src_ip) == SUCCESS)
- {
- /* get the nexthop to src (src as we are in POLICY_FWD).*/
- route->gateway = charon->kernel_interface->get_nexthop(
- charon->kernel_interface, src);
- route->if_name = charon->kernel_interface->get_interface(
- charon->kernel_interface, dst);
- route->dst_net = chunk_clone(policy->src.net->get_address(policy->src.net));
- route->prefixlen = policy->src.mask;
-
- if (route->if_name)
- {
- switch (charon->kernel_interface->add_route(
- charon->kernel_interface, route->dst_net,
- route->prefixlen, route->gateway,
- route->src_ip, route->if_name))
- {
- default:
- DBG1(DBG_KNL, "unable to install source route for %H",
- route->src_ip);
- /* FALL */
- case ALREADY_DONE:
- /* route exists, do not uninstall */
- route_entry_destroy(route);
- break;
- case SUCCESS:
- /* cache the installed route */
- policy->route = route;
- break;
- }
- }
- else
- {
- route_entry_destroy(route);
- }
- }
- else
- {
- free(route);
- }
- }
-
- this->mutex->unlock(this->mutex);
-
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, query_policy, status_t,
- private_kernel_pfkey_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
- u_int32_t *use_time)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_x_policy *pol;
- policy_entry_t *policy, *found = NULL;
- pfkey_msg_t response;
- size_t len;
-
- if (dir2kernel(direction) == IPSEC_DIR_INVALID)
- {
- /* FWD policies are not supported on all platforms */
- return NOT_FOUND;
- }
-
- DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
-
- /* create a policy */
- policy = create_policy_entry(src_ts, dst_ts, direction, 0);
-
- /* find a matching policy */
- this->mutex->lock(this->mutex);
- if (this->policies->find_first(this->policies,
- (linked_list_match_t)policy_entry_equals, (void**)&found, policy) != SUCCESS)
- {
- DBG1(DBG_KNL, "querying policy %R === %R %N failed, not found", src_ts,
- dst_ts, policy_dir_names, direction);
- policy_entry_destroy(policy);
- this->mutex->unlock(this->mutex);
- return NOT_FOUND;
- }
- policy_entry_destroy(policy);
- policy = found;
-
- memset(&request, 0, sizeof(request));
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_X_SPDGET;
- msg->sadb_msg_satype = 0;
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg);
- pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- pol->sadb_x_policy_id = policy->index;
- pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy));
- pol->sadb_x_policy_dir = dir2kernel(direction);
- pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
- PFKEY_EXT_ADD(msg, pol);
-
- add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto,
- policy->src.mask);
- add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto,
- policy->dst.mask);
-
- this->mutex->unlock(this->mutex);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to query policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to query policy %R === %R %N: %s (%d)", src_ts,
- dst_ts, policy_dir_names, direction,
- strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- else if (parse_pfkey_message(out, &response) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to query policy %R === %R %N: parsing response "
- "from kernel failed", src_ts, dst_ts, policy_dir_names, direction);
- free(out);
- return FAILED;
- }
- else if (response.lft_current == NULL)
- {
- DBG1(DBG_KNL, "unable to query policy %R === %R %N: kernel reports no "
- "use time", src_ts, dst_ts, policy_dir_names, direction);
- free(out);
- return FAILED;
- }
- /* we need the monotonic time, but the kernel returns system time. */
- if (response.lft_current->sadb_lifetime_usetime)
- {
- *use_time = time_monotonic(NULL) -
- (time(NULL) - response.lft_current->sadb_lifetime_usetime);
- }
- else
- {
- *use_time = 0;
- }
- free(out);
-
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, del_policy, status_t,
- private_kernel_pfkey_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
- bool unrouted)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- struct sadb_x_policy *pol;
- policy_entry_t *policy, *found = NULL;
- route_entry_t *route;
- size_t len;
-
- if (dir2kernel(direction) == IPSEC_DIR_INVALID)
- {
- /* FWD policies are not supported on all platforms */
- return SUCCESS;
- }
-
- DBG2(DBG_KNL, "deleting policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
-
- /* create a policy */
- policy = create_policy_entry(src_ts, dst_ts, direction, 0);
-
- /* find a matching policy */
- this->mutex->lock(this->mutex);
- if (this->policies->find_first(this->policies,
- (linked_list_match_t)policy_entry_equals, (void**)&found, policy) == SUCCESS)
- {
- if (--found->refcount > 0)
- {
- /* is used by more SAs, keep in kernel */
- DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed");
- policy_entry_destroy(policy);
- this->mutex->unlock(this->mutex);
- return SUCCESS;
- }
- /* remove if last reference */
- this->policies->remove(this->policies, found, NULL);
- policy_entry_destroy(policy);
- policy = found;
- }
- else
- {
- DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", src_ts,
- dst_ts, policy_dir_names, direction);
- policy_entry_destroy(policy);
- this->mutex->unlock(this->mutex);
- return NOT_FOUND;
- }
- this->mutex->unlock(this->mutex);
-
- memset(&request, 0, sizeof(request));
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_X_SPDDELETE;
- msg->sadb_msg_satype = 0;
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg);
- pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy));
- pol->sadb_x_policy_dir = dir2kernel(direction);
- pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
- PFKEY_EXT_ADD(msg, pol);
-
- add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto,
- policy->src.mask);
- add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto,
- policy->dst.mask);
-
- route = policy->route;
- policy->route = NULL;
- policy_entry_destroy(policy);
-
- if (pfkey_send(this, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to delete policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to delete policy %R === %R %N: %s (%d)", src_ts,
- dst_ts, policy_dir_names, direction,
- strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- free(out);
-
- if (route)
- {
- if (charon->kernel_interface->del_route(charon->kernel_interface,
- route->dst_net, route->prefixlen, route->gateway,
- route->src_ip, route->if_name) != SUCCESS)
- {
- DBG1(DBG_KNL, "error uninstalling route installed with "
- "policy %R === %R %N", src_ts, dst_ts,
- policy_dir_names, direction);
- }
- route_entry_destroy(route);
- }
-
- return SUCCESS;
-}
-
-/**
- * Register a socket for AQUIRE/EXPIRE messages
- */
-static status_t register_pfkey_socket(private_kernel_pfkey_ipsec_t *this,
- u_int8_t satype)
-{
- unsigned char request[PFKEY_BUFFER_SIZE];
- struct sadb_msg *msg, *out;
- size_t len;
-
- memset(&request, 0, sizeof(request));
-
- msg = (struct sadb_msg*)request;
- msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = SADB_REGISTER;
- msg->sadb_msg_satype = satype;
- msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
-
- if (pfkey_send_socket(this, this->socket_events, msg, &out, &len) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to register PF_KEY socket");
- return FAILED;
- }
- else if (out->sadb_msg_errno)
- {
- DBG1(DBG_KNL, "unable to register PF_KEY socket: %s (%d)",
- strerror(out->sadb_msg_errno), out->sadb_msg_errno);
- free(out);
- return FAILED;
- }
- free(out);
- return SUCCESS;
-}
-
-METHOD(kernel_ipsec_t, bypass_socket, bool,
- private_kernel_pfkey_ipsec_t *this, int fd, int family)
-{
- struct sadb_x_policy policy;
- u_int sol, ipsec_policy;
-
- switch (family)
- {
- case AF_INET:
- {
- sol = SOL_IP;
- ipsec_policy = IP_IPSEC_POLICY;
- break;
- }
- case AF_INET6:
- {
- sol = SOL_IPV6;
- ipsec_policy = IPV6_IPSEC_POLICY;
- break;
- }
- default:
- return FALSE;
- }
-
- memset(&policy, 0, sizeof(policy));
- policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
- policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
-
- policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
- if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
- {
- DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
- strerror(errno));
- return FALSE;
- }
- policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
- if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
- {
- DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
- strerror(errno));
- return FALSE;
- }
- return TRUE;
-}
-
-METHOD(kernel_ipsec_t, destroy, void,
- private_kernel_pfkey_ipsec_t *this)
-{
- if (this->job)
- {
- this->job->cancel(this->job);
- }
- if (this->socket > 0)
- {
- close(this->socket);
- }
- if (this->socket_events > 0)
- {
- close(this->socket_events);
- }
- this->policies->destroy_function(this->policies, (void*)policy_entry_destroy);
- this->mutex->destroy(this->mutex);
- this->mutex_pfkey->destroy(this->mutex_pfkey);
- free(this);
-}
-
-/*
- * Described in header.
- */
-kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
-{
- private_kernel_pfkey_ipsec_t *this;
-
- INIT(this,
- .public.interface = {
- .get_spi = _get_spi,
- .get_cpi = _get_cpi,
- .add_sa = _add_sa,
- .update_sa = _update_sa,
- .query_sa = _query_sa,
- .del_sa = _del_sa,
- .add_policy = _add_policy,
- .query_policy = _query_policy,
- .del_policy = _del_policy,
- .bypass_socket = _bypass_socket,
- .destroy = _destroy,
- },
- .policies = linked_list_create(),
- .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
- .mutex_pfkey = mutex_create(MUTEX_TYPE_DEFAULT),
- .install_routes = lib->settings->get_bool(lib->settings,
- "charon.install_routes", TRUE),
- );
-
- /* create a PF_KEY socket to communicate with the kernel */
- this->socket = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
- if (this->socket <= 0)
- {
- DBG1(DBG_KNL, "unable to create PF_KEY socket");
- destroy(this);
- return NULL;
- }
-
- /* create a PF_KEY socket for ACQUIRE & EXPIRE */
- this->socket_events = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
- if (this->socket_events <= 0)
- {
- DBG1(DBG_KNL, "unable to create PF_KEY event socket");
- destroy(this);
- return NULL;
- }
-
- /* register the event socket */
- if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS ||
- register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to register PF_KEY event socket");
- destroy(this);
- return NULL;
- }
-
- this->job = callback_job_create((callback_job_cb_t)receive_events,
- this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
-
- return &this->public;
-}
-
diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h
deleted file mode 100644
index 649f93733..000000000
--- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup kernel_pfkey_ipsec_i kernel_pfkey_ipsec
- * @{ @ingroup kernel_pfkey
- */
-
-#ifndef KERNEL_PFKEY_IPSEC_H_
-#define KERNEL_PFKEY_IPSEC_H_
-
-#include <kernel/kernel_ipsec.h>
-
-typedef struct kernel_pfkey_ipsec_t kernel_pfkey_ipsec_t;
-
-/**
- * Implementation of the kernel ipsec interface using PF_KEY.
- */
-struct kernel_pfkey_ipsec_t {
-
- /**
- * Implements kernel_ipsec_t interface
- */
- kernel_ipsec_t interface;
-};
-
-/**
- * Create a PF_KEY kernel ipsec interface instance.
- *
- * @return kernel_pfkey_ipsec_t instance
- */
-kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create();
-
-#endif /** KERNEL_PFKEY_IPSEC_H_ @}*/
diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c
deleted file mode 100644
index b84ccf150..000000000
--- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-
-#include "kernel_pfkey_plugin.h"
-
-#include "kernel_pfkey_ipsec.h"
-
-#include <daemon.h>
-
-typedef struct private_kernel_pfkey_plugin_t private_kernel_pfkey_plugin_t;
-
-/**
- * private data of kernel PF_KEY plugin
- */
-struct private_kernel_pfkey_plugin_t {
- /**
- * implements plugin interface
- */
- kernel_pfkey_plugin_t public;
-};
-
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(private_kernel_pfkey_plugin_t *this)
-{
- charon->kernel_interface->remove_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_pfkey_ipsec_create);
- free(this);
-}
-
-/*
- * see header file
- */
-plugin_t *kernel_pfkey_plugin_create()
-{
- private_kernel_pfkey_plugin_t *this = malloc_thing(private_kernel_pfkey_plugin_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
-
- charon->kernel_interface->add_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_pfkey_ipsec_create);
-
- return &this->public.plugin;
-}
diff --git a/src/libcharon/plugins/kernel_pfroute/Makefile.am b/src/libcharon/plugins/kernel_pfroute/Makefile.am
deleted file mode 100644
index 83db48160..000000000
--- a/src/libcharon/plugins/kernel_pfroute/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-
-INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \
- -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon
-
-AM_CFLAGS = -rdynamic
-
-if MONOLITHIC
-noinst_LTLIBRARIES = libstrongswan-kernel-pfroute.la
-else
-plugin_LTLIBRARIES = libstrongswan-kernel-pfroute.la
-endif
-
-libstrongswan_kernel_pfroute_la_SOURCES = \
- kernel_pfroute_plugin.h kernel_pfroute_plugin.c \
- kernel_pfroute_net.h kernel_pfroute_net.c
-
-libstrongswan_kernel_pfroute_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c
deleted file mode 100644
index 97c019b58..000000000
--- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * Copyright (C) 2009 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <ifaddrs.h>
-#include <net/route.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "kernel_pfroute_net.h"
-
-#include <daemon.h>
-#include <utils/host.h>
-#include <threading/thread.h>
-#include <threading/mutex.h>
-#include <utils/linked_list.h>
-#include <processing/jobs/callback_job.h>
-#include <processing/jobs/roam_job.h>
-
-#ifndef HAVE_STRUCT_SOCKADDR_SA_LEN
-#error Cannot compile this plugin on systems where 'struct sockaddr' has no sa_len member.
-#endif
-
-/** delay before firing roam jobs (ms) */
-#define ROAM_DELAY 100
-
-/** buffer size for PF_ROUTE messages */
-#define PFROUTE_BUFFER_SIZE 4096
-
-typedef struct addr_entry_t addr_entry_t;
-
-/**
- * IP address in an inface_entry_t
- */
-struct addr_entry_t {
-
- /** The ip address */
- host_t *ip;
-
- /** virtual IP managed by us */
- bool virtual;
-
- /** Number of times this IP is used, if virtual */
- u_int refcount;
-};
-
-/**
- * destroy a addr_entry_t object
- */
-static void addr_entry_destroy(addr_entry_t *this)
-{
- this->ip->destroy(this->ip);
- free(this);
-}
-
-typedef struct iface_entry_t iface_entry_t;
-
-/**
- * A network interface on this system, containing addr_entry_t's
- */
-struct iface_entry_t {
-
- /** interface index */
- int ifindex;
-
- /** name of the interface */
- char ifname[IFNAMSIZ];
-
- /** interface flags, as in netdevice(7) SIOCGIFFLAGS */
- u_int flags;
-
- /** list of addresses as host_t */
- linked_list_t *addrs;
-};
-
-/**
- * destroy an interface entry
- */
-static void iface_entry_destroy(iface_entry_t *this)
-{
- this->addrs->destroy_function(this->addrs, (void*)addr_entry_destroy);
- free(this);
-}
-
-
-typedef struct private_kernel_pfroute_net_t private_kernel_pfroute_net_t;
-
-/**
- * Private variables and functions of kernel_pfroute class.
- */
-struct private_kernel_pfroute_net_t
-{
- /**
- * Public part of the kernel_pfroute_t object.
- */
- kernel_pfroute_net_t public;
-
- /**
- * mutex to lock access to various lists
- */
- mutex_t *mutex;
-
- /**
- * Cached list of interfaces and their addresses (iface_entry_t)
- */
- linked_list_t *ifaces;
-
- /**
- * job receiving PF_ROUTE events
- */
- callback_job_t *job;
-
- /**
- * mutex to lock access to the PF_ROUTE socket
- */
- mutex_t *mutex_pfroute;
-
- /**
- * PF_ROUTE socket to communicate with the kernel
- */
- int socket;
-
- /**
- * PF_ROUTE socket to receive events
- */
- int socket_events;
-
- /**
- * sequence number for messages sent to the kernel
- */
- int seq;
-
- /**
- * time of last roam job
- */
- timeval_t last_roam;
-};
-
-/**
- * Start a roaming job. We delay it a bit and fire only one job
- * for multiple events. Otherwise we would create too many jobs.
- */
-static void fire_roam_job(private_kernel_pfroute_net_t *this, bool address)
-{
- timeval_t now;
-
- time_monotonic(&now);
- if (timercmp(&now, &this->last_roam, >))
- {
- now.tv_usec += ROAM_DELAY * 1000;
- while (now.tv_usec > 1000000)
- {
- now.tv_sec++;
- now.tv_usec -= 1000000;
- }
- this->last_roam = now;
- charon->scheduler->schedule_job_ms(charon->scheduler,
- (job_t*)roam_job_create(address), ROAM_DELAY);
- }
-}
-
-/**
- * Process an RTM_*ADDR message from the kernel
- */
-static void process_addr(private_kernel_pfroute_net_t *this,
- struct rt_msghdr *msg)
-{
- struct ifa_msghdr *ifa = (struct ifa_msghdr*)msg;
- sockaddr_t *sockaddr = (sockaddr_t*)(ifa + 1);
- host_t *host = NULL;
- enumerator_t *ifaces, *addrs;
- iface_entry_t *iface;
- addr_entry_t *addr;
- bool found = FALSE, changed = FALSE, roam = FALSE;
- int i;
-
- for (i = 1; i < (1 << RTAX_MAX); i <<= 1)
- {
- if (ifa->ifam_addrs & i)
- {
- if (RTA_IFA & i)
- {
- host = host_create_from_sockaddr(sockaddr);
- break;
- }
- sockaddr = (sockaddr_t*)((char*)sockaddr + sockaddr->sa_len);
- }
- }
-
- if (!host)
- {
- return;
- }
-
- this->mutex->lock(this->mutex);
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &iface))
- {
- if (iface->ifindex == ifa->ifam_index)
- {
- addrs = iface->addrs->create_enumerator(iface->addrs);
- while (addrs->enumerate(addrs, &addr))
- {
- if (host->ip_equals(host, addr->ip))
- {
- found = TRUE;
- if (ifa->ifam_type == RTM_DELADDR)
- {
- iface->addrs->remove_at(iface->addrs, addrs);
- if (!addr->virtual)
- {
- changed = TRUE;
- DBG1(DBG_KNL, "%H disappeared from %s",
- host, iface->ifname);
- }
- addr_entry_destroy(addr);
- }
- else if (ifa->ifam_type == RTM_NEWADDR && addr->virtual)
- {
- addr->refcount = 1;
- }
- }
- }
- addrs->destroy(addrs);
-
- if (!found && ifa->ifam_type == RTM_NEWADDR)
- {
- changed = TRUE;
- addr = malloc_thing(addr_entry_t);
- addr->ip = host->clone(host);
- addr->virtual = FALSE;
- addr->refcount = 1;
- iface->addrs->insert_last(iface->addrs, addr);
- DBG1(DBG_KNL, "%H appeared on %s", host, iface->ifname);
- }
-
- if (changed && (iface->flags & IFF_UP))
- {
- roam = TRUE;
- }
- break;
- }
- }
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
- host->destroy(host);
-
- if (roam)
- {
- fire_roam_job(this, TRUE);
- }
-}
-
-/**
- * Process an RTM_IFINFO message from the kernel
- */
-static void process_link(private_kernel_pfroute_net_t *this,
- struct rt_msghdr *hdr)
-{
- struct if_msghdr *msg = (struct if_msghdr*)hdr;
- enumerator_t *enumerator;
- iface_entry_t *iface;
- bool roam = FALSE;
-
- if (msg->ifm_flags & IFF_LOOPBACK)
- { /* ignore loopback interfaces */
- return;
- }
-
- this->mutex->lock(this->mutex);
- enumerator = this->ifaces->create_enumerator(this->ifaces);
- while (enumerator->enumerate(enumerator, &iface))
- {
- if (iface->ifindex == msg->ifm_index)
- {
- if (!(iface->flags & IFF_UP) && (msg->ifm_flags & IFF_UP))
- {
- roam = TRUE;
- DBG1(DBG_KNL, "interface %s activated", iface->ifname);
- }
- else if ((iface->flags & IFF_UP) && !(msg->ifm_flags & IFF_UP))
- {
- roam = TRUE;
- DBG1(DBG_KNL, "interface %s deactivated", iface->ifname);
- }
- iface->flags = msg->ifm_flags;
- break;
- }
- }
- enumerator->destroy(enumerator);
- this->mutex->unlock(this->mutex);
-
- if (roam)
- {
- fire_roam_job(this, TRUE);
- }
-}
-
-/**
- * Process an RTM_*ROUTE message from the kernel
- */
-static void process_route(private_kernel_pfroute_net_t *this,
- struct rt_msghdr *msg)
-{
-
-}
-
-/**
- * Receives events from kernel
- */
-static job_requeue_t receive_events(private_kernel_pfroute_net_t *this)
-{
- unsigned char buf[PFROUTE_BUFFER_SIZE];
- struct rt_msghdr *msg = (struct rt_msghdr*)buf;
- int len;
- bool oldstate;
-
- oldstate = thread_cancelability(TRUE);
- len = recvfrom(this->socket_events, buf, sizeof(buf), 0, NULL, 0);
- thread_cancelability(oldstate);
-
- if (len < 0)
- {
- switch (errno)
- {
- case EINTR:
- /* interrupted, try again */
- return JOB_REQUEUE_DIRECT;
- case EAGAIN:
- /* no data ready, select again */
- return JOB_REQUEUE_DIRECT;
- default:
- DBG1(DBG_KNL, "unable to receive from PF_ROUTE event socket");
- sleep(1);
- return JOB_REQUEUE_FAIR;
- }
- }
-
- if (len < sizeof(msg->rtm_msglen) || len < msg->rtm_msglen ||
- msg->rtm_version != RTM_VERSION)
- {
- DBG2(DBG_KNL, "received corrupted PF_ROUTE message");
- return JOB_REQUEUE_DIRECT;
- }
-
- switch (msg->rtm_type)
- {
- case RTM_NEWADDR:
- case RTM_DELADDR:
- process_addr(this, msg);
- break;
- case RTM_IFINFO:
- /*case RTM_IFANNOUNCE <- what about this*/
- process_link(this, msg);
- break;
- case RTM_ADD:
- case RTM_DELETE:
- process_route(this, msg);
- default:
- break;
- }
-
- return JOB_REQUEUE_DIRECT;
-}
-
-
-/** enumerator over addresses */
-typedef struct {
- private_kernel_pfroute_net_t* this;
- /** whether to enumerate down interfaces */
- bool include_down_ifaces;
- /** whether to enumerate virtual ip addresses */
- bool include_virtual_ips;
-} address_enumerator_t;
-
-/**
- * cleanup function for address enumerator
- */
-static void address_enumerator_destroy(address_enumerator_t *data)
-{
- data->this->mutex->unlock(data->this->mutex);
- free(data);
-}
-
-/**
- * filter for addresses
- */
-static bool filter_addresses(address_enumerator_t *data, addr_entry_t** in, host_t** out)
-{
- host_t *ip;
- if (!data->include_virtual_ips && (*in)->virtual)
- { /* skip virtual interfaces added by us */
- return FALSE;
- }
- ip = (*in)->ip;
- if (ip->get_family(ip) == AF_INET6)
- {
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip);
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
- { /* skip addresses with a unusable scope */
- return FALSE;
- }
- }
- *out = ip;
- return TRUE;
-}
-
-/**
- * enumerator constructor for interfaces
- */
-static enumerator_t *create_iface_enumerator(iface_entry_t *iface, address_enumerator_t *data)
-{
- return enumerator_create_filter(iface->addrs->create_enumerator(iface->addrs),
- (void*)filter_addresses, data, NULL);
-}
-
-/**
- * filter for interfaces
- */
-static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in, iface_entry_t** out)
-{
- if (!data->include_down_ifaces && !((*in)->flags & IFF_UP))
- { /* skip interfaces not up */
- return FALSE;
- }
- *out = *in;
- return TRUE;
-}
-
-/**
- * implementation of kernel_net_t.create_address_enumerator
- */
-static enumerator_t *create_address_enumerator(private_kernel_pfroute_net_t *this,
- bool include_down_ifaces, bool include_virtual_ips)
-{
- address_enumerator_t *data = malloc_thing(address_enumerator_t);
- data->this = this;
- data->include_down_ifaces = include_down_ifaces;
- data->include_virtual_ips = include_virtual_ips;
-
- this->mutex->lock(this->mutex);
- return enumerator_create_nested(
- enumerator_create_filter(this->ifaces->create_enumerator(this->ifaces),
- (void*)filter_interfaces, data, NULL),
- (void*)create_iface_enumerator, data, (void*)address_enumerator_destroy);
-}
-
-/**
- * implementation of kernel_net_t.get_interface_name
- */
-static char *get_interface_name(private_kernel_pfroute_net_t *this, host_t* ip)
-{
- enumerator_t *ifaces, *addrs;
- iface_entry_t *iface;
- addr_entry_t *addr;
- char *name = NULL;
-
- DBG2(DBG_KNL, "getting interface name for %H", ip);
-
- this->mutex->lock(this->mutex);
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &iface))
- {
- addrs = iface->addrs->create_enumerator(iface->addrs);
- while (addrs->enumerate(addrs, &addr))
- {
- if (ip->ip_equals(ip, addr->ip))
- {
- name = strdup(iface->ifname);
- break;
- }
- }
- addrs->destroy(addrs);
- if (name)
- {
- break;
- }
- }
- ifaces->destroy(ifaces);
- this->mutex->unlock(this->mutex);
-
- if (name)
- {
- DBG2(DBG_KNL, "%H is on interface %s", ip, name);
- }
- else
- {
- DBG2(DBG_KNL, "%H is not a local address", ip);
- }
- return name;
-}
-
-/**
- * Implementation of kernel_net_t.get_source_addr.
- */
-static host_t* get_source_addr(private_kernel_pfroute_net_t *this,
- host_t *dest, host_t *src)
-{
- return NULL;
-}
-
-/**
- * Implementation of kernel_net_t.get_nexthop.
- */
-static host_t* get_nexthop(private_kernel_pfroute_net_t *this, host_t *dest)
-{
- return NULL;
-}
-
-/**
- * Implementation of kernel_net_t.add_ip.
- */
-static status_t add_ip(private_kernel_pfroute_net_t *this,
- host_t *virtual_ip, host_t *iface_ip)
-{
- return FAILED;
-}
-
-/**
- * Implementation of kernel_net_t.del_ip.
- */
-static status_t del_ip(private_kernel_pfroute_net_t *this, host_t *virtual_ip)
-{
- return FAILED;
-}
-
-/**
- * Implementation of kernel_net_t.add_route.
- */
-static status_t add_route(private_kernel_pfroute_net_t *this, chunk_t dst_net,
- u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
-{
- return FAILED;
-}
-
-/**
- * Implementation of kernel_net_t.del_route.
- */
-static status_t del_route(private_kernel_pfroute_net_t *this, chunk_t dst_net,
- u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
-{
- return FAILED;
-}
-
-/**
- * Initialize a list of local addresses.
- */
-static status_t init_address_list(private_kernel_pfroute_net_t *this)
-{
- struct ifaddrs *ifap, *ifa;
- iface_entry_t *iface, *current;
- addr_entry_t *addr;
- enumerator_t *ifaces, *addrs;
-
- DBG1(DBG_KNL, "listening on interfaces:");
-
- if (getifaddrs(&ifap) < 0)
- {
- DBG1(DBG_KNL, " failed to get interfaces!");
- return FAILED;
- }
-
- for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
- {
- if (ifa->ifa_addr == NULL)
- {
- continue;
- }
- switch(ifa->ifa_addr->sa_family)
- {
- case AF_LINK:
- case AF_INET:
- case AF_INET6:
- {
- if (ifa->ifa_flags & IFF_LOOPBACK)
- { /* ignore loopback interfaces */
- continue;
- }
-
- iface = NULL;
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &current))
- {
- if (streq(current->ifname, ifa->ifa_name))
- {
- iface = current;
- break;
- }
- }
- ifaces->destroy(ifaces);
-
- if (!iface)
- {
- iface = malloc_thing(iface_entry_t);
- memcpy(iface->ifname, ifa->ifa_name, IFNAMSIZ);
- iface->ifindex = if_nametoindex(ifa->ifa_name);
- iface->flags = ifa->ifa_flags;
- iface->addrs = linked_list_create();
- this->ifaces->insert_last(this->ifaces, iface);
- }
-
- if (ifa->ifa_addr->sa_family != AF_LINK)
- {
- addr = malloc_thing(addr_entry_t);
- addr->ip = host_create_from_sockaddr(ifa->ifa_addr);
- addr->virtual = FALSE;
- addr->refcount = 1;
- iface->addrs->insert_last(iface->addrs, addr);
- }
- }
- }
- }
- freeifaddrs(ifap);
-
- ifaces = this->ifaces->create_enumerator(this->ifaces);
- while (ifaces->enumerate(ifaces, &iface))
- {
- if (iface->flags & IFF_UP)
- {
- DBG1(DBG_KNL, " %s", iface->ifname);
- addrs = iface->addrs->create_enumerator(iface->addrs);
- while (addrs->enumerate(addrs, (void**)&addr))
- {
- DBG1(DBG_KNL, " %H", addr->ip);
- }
- addrs->destroy(addrs);
- }
- }
- ifaces->destroy(ifaces);
-
- return SUCCESS;
-}
-
-/**
- * Implementation of kernel_netlink_net_t.destroy.
- */
-static void destroy(private_kernel_pfroute_net_t *this)
-{
- if (this->job)
- {
- this->job->cancel(this->job);
- }
- if (this->socket > 0)
- {
- close(this->socket);
- }
- if (this->socket_events)
- {
- close(this->socket_events);
- }
- this->ifaces->destroy_function(this->ifaces, (void*)iface_entry_destroy);
- this->mutex->destroy(this->mutex);
- this->mutex_pfroute->destroy(this->mutex_pfroute);
- free(this);
-}
-
-/*
- * Described in header.
- */
-kernel_pfroute_net_t *kernel_pfroute_net_create()
-{
- private_kernel_pfroute_net_t *this = malloc_thing(private_kernel_pfroute_net_t);
-
- /* public functions */
- this->public.interface.get_interface = (char*(*)(kernel_net_t*,host_t*))get_interface_name;
- this->public.interface.create_address_enumerator = (enumerator_t*(*)(kernel_net_t*,bool,bool))create_address_enumerator;
- this->public.interface.get_source_addr = (host_t*(*)(kernel_net_t*, host_t *dest, host_t *src))get_source_addr;
- this->public.interface.get_nexthop = (host_t*(*)(kernel_net_t*, host_t *dest))get_nexthop;
- this->public.interface.add_ip = (status_t(*)(kernel_net_t*,host_t*,host_t*)) add_ip;
- this->public.interface.del_ip = (status_t(*)(kernel_net_t*,host_t*)) del_ip;
- this->public.interface.add_route = (status_t(*)(kernel_net_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) add_route;
- this->public.interface.del_route = (status_t(*)(kernel_net_t*,chunk_t,u_int8_t,host_t*,host_t*,char*)) del_route;
-
- this->public.interface.destroy = (void(*)(kernel_net_t*)) destroy;
-
- /* private members */
- this->ifaces = linked_list_create();
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
- this->mutex_pfroute = mutex_create(MUTEX_TYPE_DEFAULT);
-
- this->seq = 0;
- this->socket_events = 0;
- this->job = NULL;
-
- /* create a PF_ROUTE socket to communicate with the kernel */
- this->socket = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
- if (this->socket < 0)
- {
- DBG1(DBG_KNL, "unable to create PF_ROUTE socket");
- destroy(this);
- return NULL;
- }
-
- /* create a PF_ROUTE socket to receive events */
- this->socket_events = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
- if (this->socket_events < 0)
- {
- DBG1(DBG_KNL, "unable to create PF_ROUTE event socket");
- destroy(this);
- return NULL;
- }
-
- this->job = callback_job_create((callback_job_cb_t)receive_events,
- this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
-
- if (init_address_list(this) != SUCCESS)
- {
- DBG1(DBG_KNL, "unable to get interface list");
- destroy(this);
- return NULL;
- }
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h
deleted file mode 100644
index 10c3c9eb7..000000000
--- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2009 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup kernel_pfroute_net_i kernel_pfroute_net
- * @{ @ingroup kernel_pfroute
- */
-
-#ifndef KERNEL_PFROUTE_NET_H_
-#define KERNEL_PFROUTE_NET_H_
-
-#include <kernel/kernel_net.h>
-
-typedef struct kernel_pfroute_net_t kernel_pfroute_net_t;
-
-/**
- * Implementation of the kernel net interface using PF_ROUTE.
- */
-struct kernel_pfroute_net_t {
-
- /**
- * Implements kernel_net_t interface
- */
- kernel_net_t interface;
-};
-
-/**
- * Create a PF_ROUTE kernel net interface instance.
- *
- * @return kernel_pfroute_net_t instance
- */
-kernel_pfroute_net_t *kernel_pfroute_net_create();
-
-#endif /** KERNEL_PFROUTE_NET_H_ @}*/
diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c
deleted file mode 100644
index 97139fb56..000000000
--- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2009 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-
-#include "kernel_pfroute_plugin.h"
-
-#include "kernel_pfroute_net.h"
-
-#include <daemon.h>
-
-typedef struct private_kernel_pfroute_plugin_t private_kernel_pfroute_plugin_t;
-
-/**
- * private data of kernel PF_ROUTE plugin
- */
-struct private_kernel_pfroute_plugin_t {
- /**
- * implements plugin interface
- */
- kernel_pfroute_plugin_t public;
-};
-
-/**
- * Implementation of plugin_t.destroy
- */
-static void destroy(private_kernel_pfroute_plugin_t *this)
-{
- charon->kernel_interface->remove_net_interface(charon->kernel_interface,
- (kernel_net_constructor_t)kernel_pfroute_net_create);
- free(this);
-}
-
-/*
- * see header file
- */
-plugin_t *kernel_pfroute_plugin_create()
-{
- private_kernel_pfroute_plugin_t *this = malloc_thing(private_kernel_pfroute_plugin_t);
-
- this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
-
- charon->kernel_interface->add_net_interface(charon->kernel_interface,
- (kernel_net_constructor_t)kernel_pfroute_net_create);
-
- return &this->public.plugin;
-}
diff --git a/src/libcharon/plugins/led/Makefile.am b/src/libcharon/plugins/led/Makefile.am
new file mode 100644
index 000000000..6428361fc
--- /dev/null
+++ b/src/libcharon/plugins/led/Makefile.am
@@ -0,0 +1,16 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-led.la
+else
+plugin_LTLIBRARIES = libstrongswan-led.la
+endif
+
+libstrongswan_led_la_SOURCES = led_plugin.h led_plugin.c \
+ led_listener.h led_listener.c
+
+libstrongswan_led_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/kernel_klips/Makefile.in b/src/libcharon/plugins/led/Makefile.in
index 9cac89ec3..a4e529d89 100644
--- a/src/libcharon/plugins/kernel_klips/Makefile.in
+++ b/src/libcharon/plugins/led/Makefile.in
@@ -34,7 +34,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-subdir = src/libcharon/plugins/kernel_klips
+subdir = src/libcharon/plugins/led
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -73,18 +74,14 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_kernel_klips_la_LIBADD =
-am_libstrongswan_kernel_klips_la_OBJECTS = kernel_klips_plugin.lo \
- kernel_klips_ipsec.lo
-libstrongswan_kernel_klips_la_OBJECTS = \
- $(am_libstrongswan_kernel_klips_la_OBJECTS)
-libstrongswan_kernel_klips_la_LINK = $(LIBTOOL) --tag=CC \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
- $(AM_CFLAGS) $(CFLAGS) \
- $(libstrongswan_kernel_klips_la_LDFLAGS) $(LDFLAGS) -o $@
-@MONOLITHIC_FALSE@am_libstrongswan_kernel_klips_la_rpath = -rpath \
-@MONOLITHIC_FALSE@ $(plugindir)
-@MONOLITHIC_TRUE@am_libstrongswan_kernel_klips_la_rpath =
+libstrongswan_led_la_LIBADD =
+am_libstrongswan_led_la_OBJECTS = led_plugin.lo led_listener.lo
+libstrongswan_led_la_OBJECTS = $(am_libstrongswan_led_la_OBJECTS)
+libstrongswan_led_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_led_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_led_la_rpath = -rpath $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_led_la_rpath =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -98,8 +95,8 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libstrongswan_kernel_klips_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_kernel_klips_la_SOURCES)
+SOURCES = $(libstrongswan_led_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_led_la_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -168,6 +165,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +198,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +223,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +255,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
@@ -262,13 +274,12 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon
AM_CFLAGS = -rdynamic
-@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-klips.la
-@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-klips.la
-libstrongswan_kernel_klips_la_SOURCES = \
- kernel_klips_plugin.h kernel_klips_plugin.c \
- kernel_klips_ipsec.h kernel_klips_ipsec.c pfkeyv2.h
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-led.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-led.la
+libstrongswan_led_la_SOURCES = led_plugin.h led_plugin.c \
+ led_listener.h led_listener.c
-libstrongswan_kernel_klips_la_LDFLAGS = -module -avoid-version
+libstrongswan_led_la_LDFLAGS = -module -avoid-version
all: all-am
.SUFFIXES:
@@ -282,9 +293,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_klips/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/led/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_klips/Makefile
+ $(AUTOMAKE) --gnu src/libcharon/plugins/led/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -343,8 +354,8 @@ clean-pluginLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libstrongswan-kernel-klips.la: $(libstrongswan_kernel_klips_la_OBJECTS) $(libstrongswan_kernel_klips_la_DEPENDENCIES)
- $(libstrongswan_kernel_klips_la_LINK) $(am_libstrongswan_kernel_klips_la_rpath) $(libstrongswan_kernel_klips_la_OBJECTS) $(libstrongswan_kernel_klips_la_LIBADD) $(LIBS)
+libstrongswan-led.la: $(libstrongswan_led_la_OBJECTS) $(libstrongswan_led_la_DEPENDENCIES)
+ $(libstrongswan_led_la_LINK) $(am_libstrongswan_led_la_rpath) $(libstrongswan_led_la_OBJECTS) $(libstrongswan_led_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -352,8 +363,8 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_klips_ipsec.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_klips_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/led_listener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/led_plugin.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/libcharon/plugins/led/led_listener.c b/src/libcharon/plugins/led/led_listener.c
new file mode 100644
index 000000000..18def8005
--- /dev/null
+++ b/src/libcharon/plugins/led/led_listener.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "led_listener.h"
+
+#include <errno.h>
+
+#include <daemon.h>
+#include <threading/mutex.h>
+#include <processing/jobs/callback_job.h>
+
+typedef struct private_led_listener_t private_led_listener_t;
+
+/**
+ * Private data of an led_listener_t object.
+ */
+struct private_led_listener_t {
+
+ /**
+ * Public led_listener_t interface.
+ */
+ led_listener_t public;
+
+ /**
+ * Mutex
+ */
+ mutex_t *mutex;
+
+ /**
+ * Number of established IKE_SAs
+ */
+ int count;
+
+ /**
+ * LED blink on/off time, in ms
+ */
+ int blink_time;
+
+ /**
+ * Activity LED fd, if any
+ */
+ FILE *activity;
+
+ /**
+ * Activity LED maximum brightness
+ */
+ int activity_max;
+};
+
+/**
+ * Open a LED brightness control file, get max brightness
+ */
+static FILE *open_led(char *name, int *max_brightness)
+{
+ char path[PATH_MAX];
+ FILE *f;
+
+ if (!name)
+ {
+ return NULL;
+ }
+
+ *max_brightness = 1;
+ snprintf(path, sizeof(path), "/sys/class/leds/%s/max_brightness", name);
+ f = fopen(path, "r");
+ if (f)
+ {
+ if (fscanf(f, "%d\n", max_brightness) != 1)
+ {
+ DBG1(DBG_CFG, "reading max brightness for '%s' failed: %s, using 1",
+ name, strerror(errno));
+ }
+ fclose(f);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "reading max_brightness for '%s' failed: %s, using 1",
+ name, strerror(errno));
+ }
+
+ snprintf(path, sizeof(path), "/sys/class/leds/%s/brightness", name);
+ f = fopen(path, "w");
+ if (!f)
+ {
+ DBG1(DBG_CFG, "opening LED file '%s' failed: %s", path, strerror(errno));
+ }
+ return f;
+}
+
+/**
+ * Set a LED to a given brightness
+ */
+static void set_led(FILE *led, int brightness)
+{
+ if (led)
+ {
+ if (fprintf(led, "%d\n", brightness) <= 0 ||
+ fflush(led) != 0)
+ {
+ DBG1(DBG_CFG, "setting LED brightness failed: %s", strerror(errno));
+ }
+ }
+}
+
+/**
+ * Plugin unloaded?
+ */
+static bool plugin_gone = FALSE;
+
+/**
+ * Reset activity LED after timeout
+ */
+static job_requeue_t reset_activity_led(private_led_listener_t *this)
+{
+ if (!plugin_gone)
+ { /* TODO: fix race */
+ this->mutex->lock(this->mutex);
+ if (this->count)
+ {
+ set_led(this->activity, this->activity_max);
+ }
+ else
+ {
+ set_led(this->activity, 0);
+ }
+ this->mutex->unlock(this->mutex);
+ }
+ return JOB_REQUEUE_NONE;
+}
+
+/**
+ * Blink the activity LED
+ */
+static void blink_activity(private_led_listener_t *this)
+{
+ if (this->activity)
+ {
+ this->mutex->lock(this->mutex);
+ if (this->count)
+ {
+ set_led(this->activity, 0);
+ }
+ else
+ {
+ set_led(this->activity, this->activity_max);
+ }
+ lib->scheduler->schedule_job_ms(lib->scheduler,
+ (job_t*)callback_job_create((callback_job_cb_t)reset_activity_led,
+ this, NULL, NULL), this->blink_time);
+ this->mutex->unlock(this->mutex);
+ }
+}
+
+METHOD(listener_t, ike_state_change, bool,
+ private_led_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
+{
+ this->mutex->lock(this->mutex);
+ if (state == IKE_ESTABLISHED && ike_sa->get_state(ike_sa) != IKE_ESTABLISHED)
+ {
+ this->count++;
+ if (this->count == 1)
+ {
+ set_led(this->activity, this->activity_max);
+ }
+ }
+ if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED && state != IKE_ESTABLISHED)
+ {
+ this->count--;
+ if (this->count == 0)
+ {
+ set_led(this->activity, 0);
+ }
+ }
+ this->mutex->unlock(this->mutex);
+ return TRUE;
+}
+
+METHOD(listener_t, message_hook, bool,
+ private_led_listener_t *this, ike_sa_t *ike_sa,
+ message_t *message, bool incoming)
+{
+ if (incoming || message->get_request(message))
+ {
+ blink_activity(this);
+ }
+ return TRUE;
+}
+
+METHOD(led_listener_t, destroy, void,
+ private_led_listener_t *this)
+{
+ this->mutex->lock(this->mutex);
+ set_led(this->activity, 0);
+ plugin_gone = TRUE;
+ this->mutex->unlock(this->mutex);
+ if (this->activity)
+ {
+ fclose(this->activity);
+ }
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/**
+ * See header
+ */
+led_listener_t *led_listener_create()
+{
+ private_led_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .ike_state_change = _ike_state_change,
+ .message = _message_hook,
+ },
+ .destroy = _destroy,
+ },
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .blink_time = lib->settings->get_int(lib->settings,
+ "charon.plugins.led.blink_time", 50),
+ );
+
+ this->activity = open_led(lib->settings->get_str(lib->settings,
+ "charon.plugins.led.activity_led", NULL), &this->activity_max);
+ set_led(this->activity, 0);
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/led/led_listener.h b/src/libcharon/plugins/led/led_listener.h
new file mode 100644
index 000000000..05ae28275
--- /dev/null
+++ b/src/libcharon/plugins/led/led_listener.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup led_listener led_listener
+ * @{ @ingroup led
+ */
+
+#ifndef LED_LISTENER_H_
+#define LED_LISTENER_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct led_listener_t led_listener_t;
+
+/**
+ * Listener that controls LEDs based on IKEv2 activity/state.
+ */
+struct led_listener_t {
+
+ /**
+ * Implements listener_t interface.
+ */
+ listener_t listener;
+
+ /**
+ * Destroy a led_listener_t.
+ */
+ void (*destroy)(led_listener_t *this);
+};
+
+/**
+ * Create a led_listener instance.
+ */
+led_listener_t *led_listener_create();
+
+#endif /** LED_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/led/led_plugin.c b/src/libcharon/plugins/led/led_plugin.c
new file mode 100644
index 000000000..322d198ff
--- /dev/null
+++ b/src/libcharon/plugins/led/led_plugin.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "led_plugin.h"
+
+#include "led_listener.h"
+
+#include <daemon.h>
+
+typedef struct private_led_plugin_t private_led_plugin_t;
+
+/**
+ * private data of led plugin
+ */
+struct private_led_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ led_plugin_t public;
+
+ /**
+ * Listener controlling LEDs
+ */
+ led_listener_t *listener;
+};
+
+METHOD(plugin_t, destroy, void,
+ private_led_plugin_t *this)
+{
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ this->listener->destroy(this->listener);
+ free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *led_plugin_create()
+{
+ private_led_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
+ .listener = led_listener_create(),
+ );
+
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.h b/src/libcharon/plugins/led/led_plugin.h
index 50642a572..a7449addd 100644
--- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.h
+++ b/src/libcharon/plugins/led/led_plugin.h
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2009 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -14,24 +14,24 @@
*/
/**
- * @defgroup kernel_pfroute kernel_pfroute
+ * @defgroup led led
* @ingroup cplugins
*
- * @defgroup kernel_pfroute_plugin kernel_pfroute_plugin
- * @{ @ingroup kernel_pfroute
+ * @defgroup led_plugin led_plugin
+ * @{ @ingroup led
*/
-#ifndef KERNEL_PFROUTE_PLUGIN_H_
-#define KERNEL_PFROUTE_PLUGIN_H_
+#ifndef LED_PLUGIN_H_
+#define LED_PLUGIN_H_
#include <plugins/plugin.h>
-typedef struct kernel_pfroute_plugin_t kernel_pfroute_plugin_t;
+typedef struct led_plugin_t led_plugin_t;
/**
- * PF_ROUTE kernel interface plugin
+ * Linux LED control based on IKE activity/state.
*/
-struct kernel_pfroute_plugin_t {
+struct led_plugin_t {
/**
* implements plugin interface
@@ -39,4 +39,4 @@ struct kernel_pfroute_plugin_t {
plugin_t plugin;
};
-#endif /** KERNEL_PFROUTE_PLUGIN_H_ @}*/
+#endif /** LED_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in
index d049bb41b..85db9a10b 100644
--- a/src/libcharon/plugins/load_tester/Makefile.in
+++ b/src/libcharon/plugins/load_tester/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -170,6 +171,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -201,14 +204,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -223,24 +229,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -248,7 +261,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
index 43c0ef009..aece95e12 100644
--- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c
+++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
@@ -36,7 +36,7 @@ struct private_load_tester_ipsec_t {
METHOD(kernel_ipsec_t, get_spi, status_t,
private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
- protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi)
+ u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
{
*spi = ++this->spi;
return SUCCESS;
@@ -51,7 +51,7 @@ METHOD(kernel_ipsec_t, get_cpi, status_t,
METHOD(kernel_ipsec_t, add_sa, status_t,
private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int32_t reqid, mark_t mark,
+ u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
u_int16_t cpi, bool encap, bool inbound, traffic_selector_t *src_ts,
@@ -61,7 +61,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
}
METHOD(kernel_ipsec_t, update_sa, status_t,
- private_load_tester_ipsec_t *this, u_int32_t spi, protocol_id_t protocol,
+ private_load_tester_ipsec_t *this, u_int32_t spi, u_int8_t protocol,
u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src,
host_t *new_dst, bool encap, bool new_encap, mark_t mark)
{
@@ -70,14 +70,14 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
METHOD(kernel_ipsec_t, query_sa, status_t,
private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
+ u_int32_t spi, u_int8_t protocol, mark_t mark, u_int64_t *bytes)
{
return NOT_SUPPORTED;
}
METHOD(kernel_ipsec_t, del_sa, status_t,
private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark)
+ u_int32_t spi, u_int8_t protocol, u_int16_t cpi, mark_t mark)
{
return SUCCESS;
}
@@ -85,9 +85,8 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
METHOD(kernel_ipsec_t, add_policy, status_t,
private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
- policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
- u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool routed)
+ policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
+ mark_t mark, bool routed)
{
return SUCCESS;
}
diff --git a/src/libcharon/plugins/load_tester/load_tester_listener.c b/src/libcharon/plugins/load_tester/load_tester_listener.c
index 96b0cf1ec..cf6dd0562 100644
--- a/src/libcharon/plugins/load_tester/load_tester_listener.c
+++ b/src/libcharon/plugins/load_tester/load_tester_listener.c
@@ -59,7 +59,7 @@ static bool ike_state_change(private_load_tester_listener_t *this,
if (this->delete_after_established)
{
- charon->processor->queue_job(charon->processor,
+ lib->processor->queue_job(lib->processor,
(job_t*)delete_ike_sa_job_create(id, TRUE));
}
diff --git a/src/libcharon/plugins/load_tester/load_tester_plugin.c b/src/libcharon/plugins/load_tester/load_tester_plugin.c
index 15dbccb00..cb9b80c7f 100644
--- a/src/libcharon/plugins/load_tester/load_tester_plugin.c
+++ b/src/libcharon/plugins/load_tester/load_tester_plugin.c
@@ -22,6 +22,7 @@
#include <unistd.h>
+#include <hydra.h>
#include <daemon.h>
#include <processing/jobs/callback_job.h>
#include <threading/condvar.h>
@@ -155,7 +156,7 @@ static void destroy(private_load_tester_plugin_t *this)
this->condvar->wait(this->condvar, this->mutex);
}
this->mutex->unlock(this->mutex);
- charon->kernel_interface->remove_ipsec_interface(charon->kernel_interface,
+ hydra->kernel_interface->remove_ipsec_interface(hydra->kernel_interface,
(kernel_ipsec_constructor_t)load_tester_ipsec_create);
charon->backends->remove_backend(charon->backends, &this->config->backend);
lib->credmgr->remove_set(lib->credmgr, &this->creds->credential_set);
@@ -215,13 +216,13 @@ plugin_t *load_tester_plugin_create()
if (lib->settings->get_bool(lib->settings,
"charon.plugins.load-tester.fake_kernel", FALSE))
{
- charon->kernel_interface->add_ipsec_interface(charon->kernel_interface,
+ hydra->kernel_interface->add_ipsec_interface(hydra->kernel_interface,
(kernel_ipsec_constructor_t)load_tester_ipsec_create);
}
this->running = 0;
for (i = 0; i < this->initiators; i++)
{
- charon->processor->queue_job(charon->processor,
+ lib->processor->queue_job(lib->processor,
(job_t*)callback_job_create((callback_job_cb_t)do_load_test,
this, NULL, NULL));
}
diff --git a/src/libcharon/plugins/maemo/Makefile.am b/src/libcharon/plugins/maemo/Makefile.am
new file mode 100644
index 000000000..ed6c76c0f
--- /dev/null
+++ b/src/libcharon/plugins/maemo/Makefile.am
@@ -0,0 +1,23 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon ${maemo_CFLAGS}
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-maemo.la
+else
+plugin_LTLIBRARIES = libstrongswan-maemo.la
+endif
+
+libstrongswan_maemo_la_SOURCES = \
+ maemo_plugin.h maemo_plugin.c \
+ maemo_service.h maemo_service.c
+
+libstrongswan_maemo_la_LDFLAGS = -module -avoid-version
+libstrongswan_maemo_la_LIBADD = ${maemo_LIBS}
+
+dbusservice_DATA = org.strongswan.charon.service
+
+EXTRA_DIST = $(dbusservice_DATA)
+
diff --git a/src/libcharon/plugins/maemo/Makefile.in b/src/libcharon/plugins/maemo/Makefile.in
new file mode 100644
index 000000000..978950d22
--- /dev/null
+++ b/src/libcharon/plugins/maemo/Makefile.in
@@ -0,0 +1,631 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/libcharon/plugins/maemo
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(plugindir)" \
+ "$(DESTDIR)$(dbusservicedir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libstrongswan_maemo_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libstrongswan_maemo_la_OBJECTS = maemo_plugin.lo maemo_service.lo
+libstrongswan_maemo_la_OBJECTS = $(am_libstrongswan_maemo_la_OBJECTS)
+libstrongswan_maemo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_maemo_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_maemo_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_maemo_la_rpath =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_maemo_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_maemo_la_SOURCES)
+DATA = $(dbusservice_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+default_pkcs11 = @default_pkcs11@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgid = @ipsecgid@
+ipsecgroup = @ipsecgroup@
+ipsecuid = @ipsecuid@
+ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
+libdir = @libdir@
+libexecdir = @libexecdir@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon ${maemo_CFLAGS}
+
+AM_CFLAGS = -rdynamic
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-maemo.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-maemo.la
+libstrongswan_maemo_la_SOURCES = \
+ maemo_plugin.h maemo_plugin.c \
+ maemo_service.h maemo_service.c
+
+libstrongswan_maemo_la_LDFLAGS = -module -avoid-version
+libstrongswan_maemo_la_LIBADD = ${maemo_LIBS}
+dbusservice_DATA = org.strongswan.charon.service
+EXTRA_DIST = $(dbusservice_DATA)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/maemo/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/maemo/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-maemo.la: $(libstrongswan_maemo_la_OBJECTS) $(libstrongswan_maemo_la_DEPENDENCIES)
+ $(libstrongswan_maemo_la_LINK) $(am_libstrongswan_maemo_la_rpath) $(libstrongswan_maemo_la_OBJECTS) $(libstrongswan_maemo_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maemo_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maemo_service.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-dbusserviceDATA: $(dbusservice_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(dbusservicedir)" || $(MKDIR_P) "$(DESTDIR)$(dbusservicedir)"
+ @list='$(dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbusservicedir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(dbusservicedir)" || exit $$?; \
+ done
+
+uninstall-dbusserviceDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(dbusservicedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(dbusservicedir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(dbusservicedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dbusserviceDATA install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dbusserviceDATA uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dbusserviceDATA install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-pluginLTLIBRARIES \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-dbusserviceDATA \
+ uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/maemo/maemo_plugin.c b/src/libcharon/plugins/maemo/maemo_plugin.c
new file mode 100644
index 000000000..d4549f43a
--- /dev/null
+++ b/src/libcharon/plugins/maemo/maemo_plugin.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "maemo_plugin.h"
+#include "maemo_service.h"
+
+#include <daemon.h>
+
+typedef struct private_maemo_plugin_t private_maemo_plugin_t;
+
+/**
+ * private data of maemo plugin
+ */
+struct private_maemo_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ maemo_plugin_t public;
+
+ /**
+ * service
+ */
+ maemo_service_t *service;
+
+};
+
+METHOD(plugin_t, destroy, void,
+ private_maemo_plugin_t *this)
+{
+ this->service->destroy(this->service);
+ free(this);
+}
+
+/*
+ * See header
+ */
+plugin_t *maemo_plugin_create()
+{
+ private_maemo_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
+ );
+
+ this->service = maemo_service_create();
+ if (!this->service)
+ {
+ return NULL;
+ }
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libcharon/plugins/kernel_klips/kernel_klips_plugin.h b/src/libcharon/plugins/maemo/maemo_plugin.h
index 6086217ad..23d139b49 100644
--- a/src/libcharon/plugins/kernel_klips/kernel_klips_plugin.h
+++ b/src/libcharon/plugins/maemo/maemo_plugin.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2010 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -14,24 +14,24 @@
*/
/**
- * @defgroup kernel_klips kernel_klips
+ * @defgroup maemo maemo
* @ingroup cplugins
*
- * @defgroup kernel_klips_plugin kernel_klips_plugin
- * @{ @ingroup kernel_klips
+ * @defgroup maemo_plugin maemo_plugin
+ * @{ @ingroup maemo
*/
-#ifndef KERNEL_KLIPS_PLUGIN_H_
-#define KERNEL_KLIPS_PLUGIN_H_
+#ifndef MAEMO_PLUGIN_H_
+#define MAEMO_PLUGIN_H_
#include <plugins/plugin.h>
-typedef struct kernel_klips_plugin_t kernel_klips_plugin_t;
+typedef struct maemo_plugin_t maemo_plugin_t;
/**
- * PF_KEY kernel interface plugin
+ * Maemo integration plugin.
*/
-struct kernel_klips_plugin_t {
+struct maemo_plugin_t {
/**
* implements plugin interface
@@ -39,4 +39,4 @@ struct kernel_klips_plugin_t {
plugin_t plugin;
};
-#endif /** KERNEL_KLIPS_PLUGIN_H_ @}*/
+#endif /** MAEMO_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/maemo/maemo_service.c b/src/libcharon/plugins/maemo/maemo_service.c
new file mode 100644
index 000000000..efd914a00
--- /dev/null
+++ b/src/libcharon/plugins/maemo/maemo_service.c
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <glib.h>
+#include <libosso.h>
+#include <sys/stat.h>
+
+#include "maemo_service.h"
+
+#include <daemon.h>
+#include <credentials/sets/mem_cred.h>
+#include <processing/jobs/callback_job.h>
+
+#define OSSO_STATUS_NAME "status"
+#define OSSO_STATUS_SERVICE "org.strongswan."OSSO_STATUS_NAME
+#define OSSO_STATUS_OBJECT "/org/strongswan/"OSSO_STATUS_NAME
+#define OSSO_STATUS_IFACE "org.strongswan."OSSO_STATUS_NAME
+
+#define OSSO_CHARON_NAME "charon"
+#define OSSO_CHARON_SERVICE "org.strongswan."OSSO_CHARON_NAME
+#define OSSO_CHARON_OBJECT "/org/strongswan/"OSSO_CHARON_NAME
+#define OSSO_CHARON_IFACE "org.strongswan."OSSO_CHARON_NAME
+
+#define MAEMO_COMMON_CA_DIR "/etc/certs/common-ca"
+#define MAEMO_USER_CA_DIR "/home/user/.maemosec-certs/wifi-ca"
+/* there is also an smime-ca and an ssl-ca sub-directory and the same for
+ * ...-user, which store end user/server certificates */
+
+typedef enum {
+ VPN_STATUS_DISCONNECTED,
+ VPN_STATUS_CONNECTING,
+ VPN_STATUS_CONNECTED,
+ VPN_STATUS_AUTH_FAILED,
+ VPN_STATUS_CONNECTION_FAILED,
+} vpn_status_t;
+
+typedef struct private_maemo_service_t private_maemo_service_t;
+
+/**
+ * private data of maemo service
+ */
+struct private_maemo_service_t {
+
+ /**
+ * public interface
+ */
+ maemo_service_t public;
+
+ /**
+ * credentials
+ */
+ mem_cred_t *creds;
+
+ /**
+ * Glib main loop for a thread, handles DBUS calls
+ */
+ GMainLoop *loop;
+
+ /**
+ * Context for OSSO
+ */
+ osso_context_t *context;
+
+ /**
+ * Current IKE_SA
+ */
+ ike_sa_t *ike_sa;
+
+ /**
+ * Status of the current connection
+ */
+ vpn_status_t status;
+
+ /**
+ * Name of the current connection
+ */
+ gchar *current;
+
+};
+
+static gint change_status(private_maemo_service_t *this, int status)
+{
+ osso_rpc_t retval;
+ gint res;
+ this->status = status;
+ res = osso_rpc_run (this->context, OSSO_STATUS_SERVICE, OSSO_STATUS_OBJECT,
+ OSSO_STATUS_IFACE, "StatusChanged", &retval,
+ DBUS_TYPE_INT32, status,
+ DBUS_TYPE_INVALID);
+ return res;
+}
+
+METHOD(listener_t, ike_updown, bool,
+ private_maemo_service_t *this, ike_sa_t *ike_sa, bool up)
+{
+ /* this callback is only registered during initiation, so if the IKE_SA
+ * goes down we assume an authentication error */
+ if (this->ike_sa == ike_sa && !up)
+ {
+ change_status(this, VPN_STATUS_AUTH_FAILED);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, child_state_change, bool,
+ private_maemo_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
+ child_sa_state_t state)
+{
+ /* this call back is only registered during initiation */
+ if (this->ike_sa == ike_sa && state == CHILD_DESTROYING)
+ {
+ change_status(this, VPN_STATUS_CONNECTION_FAILED);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, child_updown, bool,
+ private_maemo_service_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
+ bool up)
+{
+ if (this->ike_sa == ike_sa)
+ {
+ if (up)
+ {
+ /* disable hooks registered to catch initiation failures */
+ this->public.listener.ike_updown = NULL;
+ this->public.listener.child_state_change = NULL;
+ change_status(this, VPN_STATUS_CONNECTED);
+ }
+ else
+ {
+ change_status(this, VPN_STATUS_CONNECTION_FAILED);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, ike_rekey, bool,
+ private_maemo_service_t *this, ike_sa_t *old, ike_sa_t *new)
+{
+ if (this->ike_sa == old)
+ {
+ this->ike_sa = new;
+ }
+ return TRUE;
+}
+
+/**
+ * load all CA certificates in the given directory
+ */
+static void load_ca_dir(private_maemo_service_t *this, char *dir)
+{
+ enumerator_t *enumerator;
+ char *rel, *abs;
+ struct stat st;
+
+ enumerator = enumerator_create_directory(dir);
+ if (enumerator)
+ {
+ while (enumerator->enumerate(enumerator, &rel, &abs, &st))
+ {
+ if (rel[0] != '.')
+ {
+ if (S_ISREG(st.st_mode))
+ {
+ certificate_t *cert;
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
+ CERT_X509, BUILD_FROM_FILE, abs,
+ BUILD_END);
+ if (!cert)
+ {
+ DBG1(DBG_CFG, "loading CA certificate '%s' failed",
+ abs);
+ continue;
+ }
+ DBG2(DBG_CFG, "loaded CA certificate '%Y'",
+ cert->get_subject(cert));
+ this->creds->add_cert(this->creds, TRUE, cert);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+}
+
+static void disconnect(private_maemo_service_t *this)
+{
+ ike_sa_t *ike_sa;
+ u_int id;
+
+ if (!this->current)
+ {
+ return;
+ }
+
+ /* avoid status updates, as this is called from the Glib main loop */
+ charon->bus->remove_listener(charon->bus, &this->public.listener);
+
+ ike_sa = charon->ike_sa_manager->checkout_by_name(charon->ike_sa_manager,
+ this->current, FALSE);
+ if (ike_sa)
+ {
+ id = ike_sa->get_unique_id(ike_sa);
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ charon->controller->terminate_ike(charon->controller, id,
+ NULL, NULL);
+ }
+ this->current = (g_free(this->current), NULL);
+ this->status = VPN_STATUS_DISCONNECTED;
+}
+
+static gboolean initiate_connection(private_maemo_service_t *this,
+ GArray *arguments)
+{
+ gint i;
+ gchar *hostname = NULL, *cacert = NULL, *username = NULL, *password = NULL;
+ identification_t *gateway = NULL, *user = NULL;
+ ike_sa_t *ike_sa;
+ ike_cfg_t *ike_cfg;
+ peer_cfg_t *peer_cfg;
+ child_cfg_t *child_cfg;
+ traffic_selector_t *ts;
+ auth_cfg_t *auth;
+ certificate_t *cert;
+ lifetime_cfg_t lifetime = {
+ .time = {
+ .life = 10800, /* 3h */
+ .rekey = 10200, /* 2h50min */
+ .jitter = 300 /* 5min */
+ }
+ };
+
+ if (this->status == VPN_STATUS_CONNECTED ||
+ this->status == VPN_STATUS_CONNECTING)
+ {
+ DBG1(DBG_CFG, "currently connected to '%s', disconnecting first",
+ this->current);
+ disconnect (this);
+ }
+
+ if (arguments->len != 5)
+ {
+ DBG1(DBG_CFG, "wrong number of arguments: %d", arguments->len);
+ return FALSE;
+ }
+
+ for (i = 0; i < arguments->len; i++)
+ {
+ osso_rpc_t *arg = &g_array_index(arguments, osso_rpc_t, i);
+ if (arg->type != DBUS_TYPE_STRING)
+ {
+ DBG1(DBG_CFG, "invalid argument [%d]: %d", i, arg->type);
+ return FALSE;
+ }
+ switch (i)
+ {
+ case 0: /* name */
+ this->current = (g_free(this->current), NULL);
+ this->current = g_strdup(arg->value.s);
+ break;
+ case 1: /* hostname */
+ hostname = arg->value.s;
+ break;
+ case 2: /* CA certificate path */
+ cacert = arg->value.s;
+ break;
+ case 3: /* username */
+ username = arg->value.s;
+ break;
+ case 4: /* password */
+ password = arg->value.s;
+ break;
+ }
+ }
+
+ DBG1(DBG_CFG, "received initiate for connection '%s'", this->current);
+
+ this->creds->clear(this->creds);
+
+ if (cacert && !streq(cacert, ""))
+ {
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, cacert, BUILD_END);
+ if (cert)
+ {
+ this->creds->add_cert(this->creds, TRUE, cert);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "failed to load CA certificate");
+ }
+ /* if this is a server cert we could use the cert subject as id */
+ }
+ else
+ {
+ load_ca_dir(this, MAEMO_COMMON_CA_DIR);
+ load_ca_dir(this, MAEMO_USER_CA_DIR);
+ }
+
+ gateway = identification_create_from_string(hostname);
+ DBG1(DBG_CFG, "using CA certificate, gateway identitiy '%Y'", gateway);
+
+ {
+ shared_key_t *shared_key;
+ chunk_t secret = chunk_create(password, strlen(password));
+ user = identification_create_from_string(username);
+ shared_key = shared_key_create(SHARED_EAP, chunk_clone(secret));
+ this->creds->add_shared(this->creds, shared_key, user->clone(user),
+ NULL);
+ }
+
+ ike_cfg = ike_cfg_create(TRUE, FALSE, "0.0.0.0", IKEV2_UDP_PORT,
+ hostname, IKEV2_UDP_PORT);
+ ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+
+ peer_cfg = peer_cfg_create(this->current, 2, ike_cfg, CERT_SEND_IF_ASKED,
+ UNIQUE_REPLACE, 1, /* keyingtries */
+ 36000, 0, /* rekey 10h, reauth none */
+ 600, 600, /* jitter, over 10min */
+ TRUE, 0, /* mobike, DPD */
+ host_create_from_string("0.0.0.0", 0) /* virt */,
+ NULL, FALSE, NULL, NULL); /* pool, mediation */
+
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
+ auth->add(auth, AUTH_RULE_IDENTITY, user);
+ peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
+ auth = auth_cfg_create();
+ auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+ auth->add(auth, AUTH_RULE_IDENTITY, gateway);
+ peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
+
+ child_cfg = child_cfg_create(this->current, &lifetime, NULL /* updown */,
+ TRUE, MODE_TUNNEL, ACTION_NONE, ACTION_NONE,
+ FALSE, 0, 0, NULL, NULL);
+ child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+ ts = traffic_selector_create_dynamic(0, 0, 65535);
+ child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
+ ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, "0.0.0.0",
+ 0, "255.255.255.255", 65535);
+ child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
+ peer_cfg->add_child_cfg(peer_cfg, child_cfg);
+ /* get an additional reference because initiate consumes one */
+ child_cfg->get_ref(child_cfg);
+
+ /* get us an IKE_SA */
+ ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
+ peer_cfg);
+ if (!ike_sa->get_peer_cfg(ike_sa))
+ {
+ ike_sa->set_peer_cfg(ike_sa, peer_cfg);
+ }
+ peer_cfg->destroy(peer_cfg);
+
+ /* store the IKE_SA, so we can track its progress */
+ this->ike_sa = ike_sa;
+ this->status = VPN_STATUS_CONNECTING;
+ this->public.listener.ike_updown = _ike_updown;
+ this->public.listener.child_state_change = _child_state_change;
+ charon->bus->add_listener(charon->bus, &this->public.listener);
+
+ if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
+ {
+ DBG1(DBG_CFG, "failed to initiate tunnel");
+ charon->bus->remove_listener(charon->bus, &this->public.listener);
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+ ike_sa);
+ this->status = VPN_STATUS_CONNECTION_FAILED;
+ return FALSE;
+ }
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return TRUE;
+}
+
+/**
+ * Callback for libosso dbus wrapper
+ */
+static gint dbus_req_handler(const gchar *interface, const gchar *method,
+ GArray *arguments, private_maemo_service_t *this,
+ osso_rpc_t *retval)
+{
+ if (streq(method, "Start"))
+ { /* void start (void), dummy function to start charon as root */
+ return OSSO_OK;
+ }
+ else if (streq(method, "Connect"))
+ { /* bool connect (name, host, cert, user, pass) */
+ retval->value.b = initiate_connection(this, arguments);
+ retval->type = DBUS_TYPE_BOOLEAN;
+ }
+ else if (streq(method, "Disconnect"))
+ { /* void disconnect (void) */
+ disconnect(this);
+ }
+ else
+ {
+ return OSSO_ERROR;
+ }
+ return OSSO_OK;
+}
+
+/**
+ * Main loop to handle D-BUS messages.
+ */
+static job_requeue_t run(private_maemo_service_t *this)
+{
+ this->loop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(this->loop);
+ return JOB_REQUEUE_NONE;
+}
+
+METHOD(maemo_service_t, destroy, void,
+ private_maemo_service_t *this)
+{
+ if (this->loop)
+ {
+ if (g_main_loop_is_running(this->loop))
+ {
+ g_main_loop_quit(this->loop);
+ }
+ g_main_loop_unref(this->loop);
+ }
+ if (this->context)
+ {
+ osso_rpc_unset_cb_f(this->context,
+ OSSO_CHARON_SERVICE,
+ OSSO_CHARON_OBJECT,
+ OSSO_CHARON_IFACE,
+ (osso_rpc_cb_f*)dbus_req_handler,
+ this);
+ osso_deinitialize(this->context);
+ }
+ charon->bus->remove_listener(charon->bus, &this->public.listener);
+ lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
+ this->creds->destroy(this->creds);
+ this->current = (g_free(this->current), NULL);
+ free(this);
+}
+
+/*
+ * See header
+ */
+maemo_service_t *maemo_service_create()
+{
+ osso_return_t result;
+ private_maemo_service_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .ike_updown = _ike_updown,
+ .child_state_change = _child_state_change,
+ .child_updown = _child_updown,
+ .ike_rekey = _ike_rekey,
+ },
+ .destroy = _destroy,
+ },
+ .creds = mem_cred_create(),
+ );
+
+ lib->credmgr->add_set(lib->credmgr, &this->creds->set);
+
+ this->context = osso_initialize(OSSO_CHARON_SERVICE, "0.0.1", TRUE, NULL);
+ if (!this->context)
+ {
+ DBG1(DBG_CFG, "failed to initialize OSSO context");
+ destroy(this);
+ return NULL;
+ }
+
+ result = osso_rpc_set_cb_f(this->context,
+ OSSO_CHARON_SERVICE,
+ OSSO_CHARON_OBJECT,
+ OSSO_CHARON_IFACE,
+ (osso_rpc_cb_f*)dbus_req_handler,
+ this);
+ if (result != OSSO_OK)
+ {
+ DBG1(DBG_CFG, "failed to set D-BUS callback (%d)", result);
+ destroy(this);
+ return NULL;
+ }
+
+ this->loop = NULL;
+ if (!g_thread_supported())
+ {
+ g_thread_init(NULL);
+ }
+
+ lib->processor->queue_job(lib->processor,
+ (job_t*)callback_job_create((callback_job_cb_t)run, this, NULL, NULL));
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/plugins/maemo/maemo_service.h b/src/libcharon/plugins/maemo/maemo_service.h
new file mode 100644
index 000000000..b0240cbaa
--- /dev/null
+++ b/src/libcharon/plugins/maemo/maemo_service.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup maemo_service maemo_service
+ * @{ @ingroup maemo
+ */
+
+#ifndef MAEMO_SERVICE_H_
+#define MAEMO_SERVICE_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct maemo_service_t maemo_service_t;
+
+/**
+ * Maemo connection management.
+ */
+struct maemo_service_t {
+
+ /**
+ * Implements listener_t.
+ */
+ listener_t listener;
+
+ /**
+ * Destroy a maemo_service_t.
+ */
+ void (*destroy)(maemo_service_t *this);
+};
+
+/**
+ * Create an instance of maemo_service_t.
+ */
+maemo_service_t *maemo_service_create();
+
+#endif /** MAEMO_SERVICE_H_ @}*/
diff --git a/src/libcharon/plugins/maemo/org.strongswan.charon.service b/src/libcharon/plugins/maemo/org.strongswan.charon.service
new file mode 100644
index 000000000..7dd31ed60
--- /dev/null
+++ b/src/libcharon/plugins/maemo/org.strongswan.charon.service
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.strongswan.charon
+Exec=/usr/bin/run-standalone.sh /usr/libexec/ipsec/charon
+User=root
diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in
index c26d325a9..6dcbc99dd 100644
--- a/src/libcharon/plugins/medcli/Makefile.in
+++ b/src/libcharon/plugins/medcli/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -167,6 +168,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -198,14 +201,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -220,24 +226,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -245,7 +258,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/medcli/medcli_config.c b/src/libcharon/plugins/medcli/medcli_config.c
index 6cbaf36f2..870d87c7e 100644
--- a/src/libcharon/plugins/medcli/medcli_config.c
+++ b/src/libcharon/plugins/medcli/medcli_config.c
@@ -126,11 +126,11 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
med_cfg = peer_cfg_create(
"mediation", 2, ike_cfg,
CERT_NEVER_SEND, UNIQUE_REPLACE,
- 1, this->rekey*60, 0, /* keytries, rekey, reauth */
- this->rekey*5, this->rekey*3, /* jitter, overtime */
- TRUE, this->dpd, /* mobike, dpddelay */
- NULL, NULL, /* vip, pool */
- TRUE, NULL, NULL); /* mediation, med by, peer id */
+ 1, this->rekey*60, 0, /* keytries, rekey, reauth */
+ this->rekey*5, this->rekey*3, /* jitter, overtime */
+ TRUE, this->dpd, /* mobike, dpddelay */
+ NULL, NULL, /* vip, pool */
+ TRUE, NULL, NULL); /* mediation, med by, peer id */
e->destroy(e);
auth = auth_cfg_create();
@@ -163,10 +163,10 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
peer_cfg = peer_cfg_create(
name, 2, this->ike->get_ref(this->ike),
CERT_NEVER_SEND, UNIQUE_REPLACE,
- 1, this->rekey*60, 0, /* keytries, rekey, reauth */
- this->rekey*5, this->rekey*3, /* jitter, overtime */
- TRUE, this->dpd, /* mobike, dpddelay */
- NULL, NULL, /* vip, pool */
+ 1, this->rekey*60, 0, /* keytries, rekey, reauth */
+ this->rekey*5, this->rekey*3, /* jitter, overtime */
+ TRUE, this->dpd, /* mobike, dpddelay */
+ NULL, NULL, /* vip, pool */
FALSE, med_cfg, /* mediation, med by */
identification_create_from_encoding(ID_KEY_ID, other));
@@ -243,11 +243,11 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
this->current = peer_cfg_create(
name, 2, this->ike->get_ref(this->ike),
CERT_NEVER_SEND, UNIQUE_REPLACE,
- 1, this->rekey*60, 0, /* keytries, rekey, reauth */
- this->rekey*5, this->rekey*3, /* jitter, overtime */
- TRUE, this->dpd, /* mobike, dpddelay */
- NULL, NULL, /* vip, pool */
- FALSE, NULL, NULL); /* mediation, med by, peer id */
+ 1, this->rekey*60, 0, /* keytries, rekey, reauth */
+ this->rekey*5, this->rekey*3, /* jitter, overtime */
+ TRUE, this->dpd, /* mobike, dpddelay */
+ NULL, NULL, /* vip, pool */
+ FALSE, NULL, NULL); /* mediation, med by, peer id */
auth = auth_cfg_create();
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
@@ -364,7 +364,7 @@ static void schedule_autoinit(private_medcli_config_t *this)
if (peer_cfg)
{
/* schedule asynchronous initiation job */
- charon->processor->queue_job(charon->processor,
+ lib->processor->queue_job(lib->processor,
(job_t*)callback_job_create(
(callback_job_cb_t)initiate_config,
peer_cfg, (void*)peer_cfg->destroy, NULL));
diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in
index 4dc9c00d0..f6db7d834 100644
--- a/src/libcharon/plugins/medsrv/Makefile.in
+++ b/src/libcharon/plugins/medsrv/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -167,6 +168,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -198,14 +201,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -220,24 +226,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -245,7 +258,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/nm/Makefile.in b/src/libcharon/plugins/nm/Makefile.in
index 1b3e4c5a6..2f5c20971 100644
--- a/src/libcharon/plugins/nm/Makefile.in
+++ b/src/libcharon/plugins/nm/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -166,6 +167,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -197,14 +200,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -219,24 +225,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -244,7 +257,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/nm/nm_creds.c b/src/libcharon/plugins/nm/nm_creds.c
index 193838e6b..638787019 100644
--- a/src/libcharon/plugins/nm/nm_creds.c
+++ b/src/libcharon/plugins/nm/nm_creds.c
@@ -51,6 +51,16 @@ struct private_nm_creds_t {
char *pass;
/**
+ * Private key decryption password / smartcard pin
+ */
+ char *keypass;
+
+ /**
+ * private key ID of smartcard key
+ */
+ chunk_t keyid;
+
+ /**
* users certificate
*/
certificate_t *usercert;
@@ -239,8 +249,14 @@ static bool shared_enumerate(shared_enumerator_t *this, shared_key_t **key,
return FALSE;
}
*key = this->key;
- *me = ID_MATCH_PERFECT;
- *other = ID_MATCH_ANY;
+ if (me)
+ {
+ *me = ID_MATCH_PERFECT;
+ }
+ if (other)
+ {
+ *other = ID_MATCH_ANY;
+ }
this->done = TRUE;
return TRUE;
}
@@ -262,18 +278,39 @@ static enumerator_t* create_shared_enumerator(private_nm_creds_t *this,
identification_t *other)
{
shared_enumerator_t *enumerator;
+ chunk_t key;
- if (!this->pass || !this->user)
+ switch (type)
{
- return NULL;
- }
- if (type != SHARED_EAP && type != SHARED_IKE)
- {
- return NULL;
- }
- if (me && !me->equals(me, this->user))
- {
- return NULL;
+ case SHARED_EAP:
+ case SHARED_IKE:
+ if (!this->pass || !this->user)
+ {
+ return NULL;
+ }
+ if (me && !me->equals(me, this->user))
+ {
+ return NULL;
+ }
+ key = chunk_create(this->pass, strlen(this->pass));
+ break;
+ case SHARED_PRIVATE_KEY_PASS:
+ if (!this->keypass)
+ {
+ return NULL;
+ }
+ key = chunk_create(this->keypass, strlen(this->keypass));
+ break;
+ case SHARED_PIN:
+ if (!this->keypass || !me ||
+ !chunk_equals(me->get_encoding(me), this->keyid))
+ {
+ return NULL;
+ }
+ key = chunk_create(this->keypass, strlen(this->keypass));
+ break;
+ default:
+ return NULL;
}
enumerator = malloc_thing(shared_enumerator_t);
@@ -282,9 +319,7 @@ static enumerator_t* create_shared_enumerator(private_nm_creds_t *this,
enumerator->this = this;
enumerator->done = FALSE;
this->lock->read_lock(this->lock);
- enumerator->key = shared_key_create(type,
- chunk_clone(chunk_create(this->pass,
- strlen(this->pass))));
+ enumerator->key = shared_key_create(type, chunk_clone(key));
return &enumerator->public;
}
@@ -370,6 +405,30 @@ static void set_username_password(private_nm_creds_t *this, identification_t *id
}
/**
+ * Implementation of nm_creds_t.set_key_password
+ */
+static void set_key_password(private_nm_creds_t *this, char *password)
+{
+ this->lock->write_lock(this->lock);
+ free(this->keypass);
+ this->keypass = password ? strdup(password) : NULL;
+ this->lock->unlock(this->lock);
+}
+
+/**
+ * Implementation of nm_creds_t.set_pin
+ */
+static void set_pin(private_nm_creds_t *this, chunk_t keyid, char *pin)
+{
+ this->lock->write_lock(this->lock);
+ free(this->keypass);
+ free(this->keyid.ptr);
+ this->keypass = pin ? strdup(pin) : NULL;
+ this->keyid = chunk_clone(keyid);
+ this->lock->unlock(this->lock);
+}
+
+/**
* Implementation of nm_creds_t.set_cert_and_key
*/
static void set_cert_and_key(private_nm_creds_t *this, certificate_t *cert,
@@ -396,12 +455,16 @@ static void clear(private_nm_creds_t *this)
}
DESTROY_IF(this->user);
free(this->pass);
+ free(this->keypass);
+ free(this->keyid.ptr);
DESTROY_IF(this->usercert);
DESTROY_IF(this->key);
this->key = NULL;
this->usercert = NULL;
this->pass = NULL;
this->user = NULL;
+ this->keypass = NULL;
+ this->keyid = chunk_empty;
}
/**
@@ -430,6 +493,8 @@ nm_creds_t *nm_creds_create()
this->public.add_certificate = (void(*)(nm_creds_t*, certificate_t *cert))add_certificate;
this->public.load_ca_dir = (void(*)(nm_creds_t*, char *dir))load_ca_dir;
this->public.set_username_password = (void(*)(nm_creds_t*, identification_t *id, char *password))set_username_password;
+ this->public.set_key_password = (void(*)(nm_creds_t*, char *password))set_key_password;
+ this->public.set_pin = (void(*)(nm_creds_t*, chunk_t keyid, char *pin))set_pin;
this->public.set_cert_and_key = (void(*)(nm_creds_t*, certificate_t *cert, private_key_t *key))set_cert_and_key;
this->public.clear = (void(*)(nm_creds_t*))clear;
this->public.destroy = (void(*)(nm_creds_t*))destroy;
@@ -441,6 +506,8 @@ nm_creds_t *nm_creds_create()
this->pass = NULL;
this->usercert = NULL;
this->key = NULL;
+ this->keypass = NULL;
+ this->keyid = chunk_empty;
return &this->public;
}
diff --git a/src/libcharon/plugins/nm/nm_creds.h b/src/libcharon/plugins/nm/nm_creds.h
index b55cff31e..91f645c7e 100644
--- a/src/libcharon/plugins/nm/nm_creds.h
+++ b/src/libcharon/plugins/nm/nm_creds.h
@@ -58,6 +58,22 @@ struct nm_creds_t {
*/
void (*set_username_password)(nm_creds_t *this, identification_t *id,
char *password);
+
+ /**
+ * Set the passphrase to use for private key decryption.
+ *
+ * @param password password to use
+ */
+ void (*set_key_password)(nm_creds_t *this, char *password);
+
+ /**
+ * Set the PIN to unlock a smartcard.
+ *
+ * @param keyid keyid of the smartcard key
+ * @param pin PIN
+ */
+ void (*set_pin)(nm_creds_t *this, chunk_t keyid, char *pin);
+
/**
* Set the certificate and private key to use for client authentication.
*
@@ -66,6 +82,7 @@ struct nm_creds_t {
*/
void (*set_cert_and_key)(nm_creds_t *this, certificate_t *cert,
private_key_t *key);
+
/**
* Clear the stored credentials.
*/
diff --git a/src/libcharon/plugins/nm/nm_plugin.c b/src/libcharon/plugins/nm/nm_plugin.c
index 250e6f7f9..fd0580bd6 100644
--- a/src/libcharon/plugins/nm/nm_plugin.c
+++ b/src/libcharon/plugins/nm/nm_plugin.c
@@ -122,7 +122,7 @@ plugin_t *nm_plugin_create()
/* bypass file permissions to read from users ssh-agent */
charon->keep_cap(charon, CAP_DAC_OVERRIDE);
- charon->processor->queue_job(charon->processor,
+ lib->processor->queue_job(lib->processor,
(job_t*)callback_job_create((callback_job_cb_t)run, this, NULL, NULL));
return &this->public.plugin;
diff --git a/src/libcharon/plugins/nm/nm_service.c b/src/libcharon/plugins/nm/nm_service.c
index 07318bbbf..72c5bbbb5 100644
--- a/src/libcharon/plugins/nm/nm_service.c
+++ b/src/libcharon/plugins/nm/nm_service.c
@@ -204,6 +204,59 @@ static bool ike_rekey(listener_t *listener, ike_sa_t *old, ike_sa_t *new)
}
/**
+ * Find a certificate for which we have a private key on a smartcard
+ */
+static identification_t *find_smartcard_key(NMStrongswanPluginPrivate *priv,
+ char *pin)
+{
+ enumerator_t *enumerator, *sans;
+ identification_t *id = NULL;
+ certificate_t *cert;
+ x509_t *x509;
+ private_key_t *key;
+ chunk_t keyid;
+
+ enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
+ CERT_X509, KEY_ANY, NULL, FALSE);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ x509 = (x509_t*)cert;
+
+ /* there might be a lot of certificates, filter them by usage */
+ if ((x509->get_flags(x509) & X509_CLIENT_AUTH) &&
+ !(x509->get_flags(x509) & X509_CA))
+ {
+ keyid = x509->get_subjectKeyIdentifier(x509);
+ if (keyid.ptr)
+ {
+ /* try to find a private key by the certificate keyid */
+ priv->creds->set_pin(priv->creds, keyid, pin);
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
+ KEY_ANY, BUILD_PKCS11_KEYID, keyid, BUILD_END);
+ if (key)
+ {
+ /* prefer a more convenient subjectAltName */
+ sans = x509->create_subjectAltName_enumerator(x509);
+ if (!sans->enumerate(sans, &id))
+ {
+ id = cert->get_subject(cert);
+ }
+ id = id->clone(id);
+ sans->destroy(sans);
+
+ DBG1(DBG_CFG, "using smartcard certificate '%Y'", id);
+ priv->creds->set_cert_and_key(priv->creds,
+ cert->get_ref(cert), key);
+ break;
+ }
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ return id;
+}
+
+/**
* Connect function called from NM via DBUS
*/
static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
@@ -224,7 +277,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
auth_class_t auth_class = AUTH_CLASS_EAP;
certificate_t *cert = NULL;
x509_t *x509;
- bool agent = FALSE;
+ bool agent = FALSE, smartcard = FALSE;
lifetime_cfg_t lifetime = {
.time = {
.life = 10800 /* 3h */,
@@ -279,6 +332,11 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
{
auth_class = AUTH_CLASS_PUBKEY;
}
+ else if (streq(str, "smartcard"))
+ {
+ auth_class = AUTH_CLASS_PUBKEY;
+ smartcard = TRUE;
+ }
}
/**
@@ -338,9 +396,26 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
if (auth_class == AUTH_CLASS_PUBKEY)
{
+ if (smartcard)
+ {
+ char *pin;
+
+ pin = (char*)nm_setting_vpn_get_secret(vpn, "password");
+ if (pin)
+ {
+ user = find_smartcard_key(priv, pin);
+ }
+ if (!user)
+ {
+ g_set_error(err, NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ "no usable smartcard certificate found.");
+ gateway->destroy(gateway);
+ return FALSE;
+ }
+ }
/* ... or certificate/private key authenitcation */
- str = nm_setting_vpn_get_data_item(vpn, "usercert");
- if (str)
+ else if ((str = nm_setting_vpn_get_data_item(vpn, "usercert")))
{
public_key_t *public;
private_key_t *private = NULL;
@@ -380,16 +455,15 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
str = nm_setting_vpn_get_data_item(vpn, "userkey");
if (!agent && str)
{
- chunk_t secret;
+ char *secret;
- secret.ptr = (char*)nm_setting_vpn_get_secret(vpn, "password");
- if (secret.ptr)
+ secret = (char*)nm_setting_vpn_get_secret(vpn, "password");
+ if (secret)
{
- secret.len = strlen(secret.ptr);
+ priv->creds->set_key_password(priv->creds, secret);
}
private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
- KEY_RSA, BUILD_FROM_FILE, str,
- BUILD_PASSPHRASE, secret, BUILD_END);
+ KEY_RSA, BUILD_FROM_FILE, str, BUILD_END);
if (!private)
{
g_set_error(err, NM_VPN_PLUGIN_ERROR,
@@ -524,17 +598,10 @@ static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection,
if (path)
{
private_key_t *key;
- chunk_t secret;
- secret.ptr = (char*)nm_setting_vpn_get_secret(settings, "password");
- if (secret.ptr)
- {
- secret.len = strlen(secret.ptr);
- }
/* try to load/decrypt the private key */
key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
- KEY_RSA, BUILD_FROM_FILE, path,
- BUILD_PASSPHRASE, secret, BUILD_END);
+ KEY_RSA, BUILD_FROM_FILE, path, BUILD_END);
if (key)
{
key->destroy(key);
@@ -542,6 +609,13 @@ static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection,
}
}
}
+ else if streq(method, "smartcard")
+ {
+ if (nm_setting_vpn_get_secret(settings, "password"))
+ {
+ return FALSE;
+ }
+ }
}
*setting_name = NM_SETTING_VPN_SETTING_NAME;
return TRUE;
diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in
index 35fb8367f..f24e2d1e7 100644
--- a/src/libcharon/plugins/smp/Makefile.in
+++ b/src/libcharon/plugins/smp/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -165,6 +166,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -196,14 +199,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -218,24 +224,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -243,7 +256,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/smp/smp.c b/src/libcharon/plugins/smp/smp.c
index 64820eb45..60937f23d 100644
--- a/src/libcharon/plugins/smp/smp.c
+++ b/src/libcharon/plugins/smp/smp.c
@@ -702,7 +702,7 @@ static job_requeue_t dispatch(private_smp_t *this)
fdp = malloc_thing(int);
*fdp = fd;
job = callback_job_create((callback_job_cb_t)process, fdp, free, this->job);
- charon->processor->queue_job(charon->processor, (job_t*)job);
+ lib->processor->queue_job(lib->processor, (job_t*)job);
return JOB_REQUEUE_DIRECT;
}
@@ -761,7 +761,7 @@ plugin_t *smp_plugin_create()
}
this->job = callback_job_create((callback_job_cb_t)dispatch, this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in
index df63d862e..bd85386b2 100644
--- a/src/libcharon/plugins/socket_default/Makefile.in
+++ b/src/libcharon/plugins/socket_default/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -168,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/socket_default/socket_default_plugin.c b/src/libcharon/plugins/socket_default/socket_default_plugin.c
index 45390ddae..b5dea68b6 100644
--- a/src/libcharon/plugins/socket_default/socket_default_plugin.c
+++ b/src/libcharon/plugins/socket_default/socket_default_plugin.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -31,17 +33,13 @@ struct private_socket_default_plugin_t {
*/
socket_default_plugin_t public;
- /**
- * Socket instance.
- */
- socket_default_socket_t *socket;
};
METHOD(plugin_t, destroy, void,
private_socket_default_plugin_t *this)
{
- charon->socket->remove_socket(charon->socket, &this->socket->socket);
- this->socket->destroy(this->socket);
+ charon->socket->remove_socket(charon->socket,
+ (socket_constructor_t)socket_default_socket_create);
free(this);
}
@@ -53,16 +51,15 @@ plugin_t *socket_default_plugin_create()
private_socket_default_plugin_t *this;
INIT(this,
- .public.plugin.destroy = _destroy,
- .socket = socket_default_socket_create(),
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
);
- if (!this->socket)
- {
- free(this);
- return NULL;
- }
- charon->socket->add_socket(charon->socket, &this->socket->socket);
+ charon->socket->add_socket(charon->socket,
+ (socket_constructor_t)socket_default_socket_create);
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c
index bc998182e..e95646643 100644
--- a/src/libcharon/plugins/socket_default/socket_default_socket.c
+++ b/src/libcharon/plugins/socket_default/socket_default_socket.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2009 Tobias Brunner
+ * Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -42,11 +42,12 @@
#include <sys/sysctl.h>
#endif
+#include <hydra.h>
#include <daemon.h>
#include <threading/thread.h>
/* Maximum size of a packet */
-#define MAX_PACKET 5000
+#define MAX_PACKET 10000
/* length of non-esp marker */
#define MARKER_LEN sizeof(u_int32_t)
@@ -116,12 +117,17 @@ struct private_socket_default_socket_t {
* IPv6 socket for NATT (4500)
*/
int ipv6_natt;
+
+ /**
+ * Maximum packet size to receive
+ */
+ int max_packet;
};
METHOD(socket_t, receiver, status_t,
private_socket_default_socket_t *this, packet_t **packet)
{
- char buffer[MAX_PACKET];
+ char buffer[this->max_packet];
chunk_t data;
packet_t *pkt;
host_t *source = NULL, *dest = NULL;
@@ -195,7 +201,7 @@ METHOD(socket_t, receiver, status_t,
msg.msg_name = &src;
msg.msg_namelen = sizeof(src);
iov.iov_base = buffer;
- iov.iov_len = sizeof(buffer);
+ iov.iov_len = this->max_packet;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = ancillary;
@@ -207,6 +213,11 @@ METHOD(socket_t, receiver, status_t,
DBG1(DBG_NET, "error reading socket: %s", strerror(errno));
return FAILED;
}
+ if (msg.msg_flags & MSG_TRUNC)
+ {
+ DBG1(DBG_NET, "receive buffer too small, packet discarded");
+ return FAILED;
+ }
DBG3(DBG_NET, "received packet %b", buffer, bytes_read);
if (bytes_read < MARKER_LEN)
@@ -351,12 +362,6 @@ METHOD(socket_t, sender, status_t,
if (data.len != 1 || data.ptr[0] != 0xFF)
{
/* add non esp marker to packet */
- if (data.len > MAX_PACKET - MARKER_LEN)
- {
- DBG1(DBG_NET, "unable to send packet: it's too big (%d bytes)",
- data.len);
- return FAILED;
- }
marked = chunk_alloc(data.len + MARKER_LEN);
memset(marked.ptr, 0, MARKER_LEN);
memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len);
@@ -521,8 +526,8 @@ static int open_socket(private_socket_default_socket_t *this,
}
}
- if (!charon->kernel_interface->bypass_socket(charon->kernel_interface,
- skt, family))
+ if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface,
+ skt, family))
{
DBG1(DBG_NET, "installing IKE bypass policy failed");
}
@@ -541,7 +546,7 @@ static int open_socket(private_socket_default_socket_t *this,
return skt;
}
-METHOD(socket_default_socket_t, destroy, void,
+METHOD(socket_t, destroy, void,
private_socket_default_socket_t *this)
{
if (this->ipv4)
@@ -575,9 +580,11 @@ socket_default_socket_t *socket_default_socket_create()
.socket = {
.send = _sender,
.receive = _receiver,
+ .destroy = _destroy,
},
- .destroy = _destroy,
},
+ .max_packet = lib->settings->get_int(lib->settings,
+ "charon.max_packet", MAX_PACKET),
);
#ifdef __APPLE__
diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.h b/src/libcharon/plugins/socket_default/socket_default_socket.h
index 755016662..89aa6f435 100644
--- a/src/libcharon/plugins/socket_default/socket_default_socket.h
+++ b/src/libcharon/plugins/socket_default/socket_default_socket.h
@@ -35,10 +35,6 @@ struct socket_default_socket_t {
*/
socket_t socket;
- /**
- * Destroy a socket_default_socket_t.
- */
- void (*destroy)(socket_default_socket_t *this);
};
/**
diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in
index 8a3a15188..8e0790671 100644
--- a/src/libcharon/plugins/socket_dynamic/Makefile.in
+++ b/src/libcharon/plugins/socket_dynamic/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -168,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
index 3410fc7a4..a6ff14efd 100644
--- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
+++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -31,17 +33,13 @@ struct private_socket_dynamic_plugin_t {
*/
socket_dynamic_plugin_t public;
- /**
- * Socket instance.
- */
- socket_dynamic_socket_t *socket;
};
METHOD(plugin_t, destroy, void,
private_socket_dynamic_plugin_t *this)
{
- charon->socket->remove_socket(charon->socket, &this->socket->socket);
- this->socket->destroy(this->socket);
+ charon->socket->remove_socket(charon->socket,
+ (socket_constructor_t)socket_dynamic_socket_create);
free(this);
}
@@ -53,16 +51,15 @@ plugin_t *socket_dynamic_plugin_create()
private_socket_dynamic_plugin_t *this;
INIT(this,
- .public.plugin.destroy = _destroy,
- .socket = socket_dynamic_socket_create(),
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
);
- if (!this->socket)
- {
- free(this);
- return NULL;
- }
- charon->socket->add_socket(charon->socket, &this->socket->socket);
+ charon->socket->add_socket(charon->socket,
+ (socket_constructor_t)socket_dynamic_socket_create);
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
index a7db59ce5..74dba82cc 100644
--- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
+++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2009 Tobias Brunner
+ * Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -36,13 +36,14 @@
#include <netinet/udp.h>
#include <net/if.h>
+#include <hydra.h>
#include <daemon.h>
#include <threading/thread.h>
#include <threading/rwlock.h>
#include <utils/hashtable.h>
/* Maximum size of a packet */
-#define MAX_PACKET 5000
+#define MAX_PACKET 10000
/* length of non-esp marker */
#define MARKER_LEN sizeof(u_int32_t)
@@ -100,6 +101,11 @@ struct private_socket_dynamic_socket_t {
* Notification pipe to signal receiver
*/
int notify[2];
+
+ /**
+ * Maximum packet size to receive
+ */
+ int max_packet;
};
/**
@@ -197,7 +203,7 @@ static packet_t *receive_packet(private_socket_dynamic_socket_t *this,
{
host_t *source = NULL, *dest = NULL;
ssize_t len;
- char buffer[MAX_PACKET];
+ char buffer[this->max_packet];
chunk_t data;
packet_t *packet;
struct msghdr msg;
@@ -212,7 +218,7 @@ static packet_t *receive_packet(private_socket_dynamic_socket_t *this,
msg.msg_name = &src;
msg.msg_namelen = sizeof(src);
iov.iov_base = buffer;
- iov.iov_len = sizeof(buffer);
+ iov.iov_len = this->max_packet;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = ancillary;
@@ -224,6 +230,11 @@ static packet_t *receive_packet(private_socket_dynamic_socket_t *this,
DBG1(DBG_NET, "error reading socket: %s", strerror(errno));
return NULL;
}
+ if (msg.msg_flags & MSG_TRUNC)
+ {
+ DBG1(DBG_NET, "receive buffer too small, packet discarded");
+ return NULL;
+ }
DBG3(DBG_NET, "received packet %b", buffer, len);
if (len < MARKER_LEN)
@@ -412,8 +423,8 @@ static int open_socket(private_socket_dynamic_socket_t *this,
return 0;
}
- if (!charon->kernel_interface->bypass_socket(charon->kernel_interface,
- fd, family))
+ if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface,
+ fd, family))
{
DBG1(DBG_NET, "installing IKE bypass policy failed");
}
@@ -495,12 +506,6 @@ METHOD(socket_t, sender, status_t,
!(data.len == 1 && data.ptr[0] == 0xFF))
{
/* add non esp marker to packet */
- if (data.len > MAX_PACKET - MARKER_LEN)
- {
- DBG1(DBG_NET, "unable to send packet: it's too big (%d bytes)",
- data.len);
- return FAILED;
- }
marked = chunk_alloc(data.len + MARKER_LEN);
memset(marked.ptr, 0, MARKER_LEN);
memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len);
@@ -567,7 +572,7 @@ METHOD(socket_t, sender, status_t,
return SUCCESS;
}
-METHOD(socket_dynamic_socket_t, destroy, void,
+METHOD(socket_t, destroy, void,
private_socket_dynamic_socket_t *this)
{
enumerator_t *enumerator;
@@ -600,10 +605,12 @@ socket_dynamic_socket_t *socket_dynamic_socket_create()
.socket = {
.send = _sender,
.receive = _receiver,
+ .destroy = _destroy,
},
- .destroy = _destroy,
},
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ .max_packet = lib->settings->get_int(lib->settings,
+ "charon.max_packet", MAX_PACKET),
);
if (pipe(this->notify) != 0)
diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.h b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.h
index 72551e545..8c93f53d6 100644
--- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.h
+++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.h
@@ -35,10 +35,6 @@ struct socket_dynamic_socket_t {
*/
socket_t socket;
- /**
- * Destroy a socket_dynamic_socket_t.
- */
- void (*destroy)(socket_dynamic_socket_t *this);
};
/**
diff --git a/src/libcharon/plugins/socket_raw/Makefile.in b/src/libcharon/plugins/socket_raw/Makefile.in
index 32bd9e0a1..5f4cba131 100644
--- a/src/libcharon/plugins/socket_raw/Makefile.in
+++ b/src/libcharon/plugins/socket_raw/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -168,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
index 5b011abcf..17a3a8db7 100644
--- a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
+++ b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
@@ -1,4 +1,6 @@
/*
+ * Copyright (C) 2010 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -31,17 +33,13 @@ struct private_socket_raw_plugin_t {
*/
socket_raw_plugin_t public;
- /**
- * Raw socket instance.
- */
- socket_raw_socket_t *socket;
};
METHOD(plugin_t, destroy, void,
private_socket_raw_plugin_t *this)
{
- charon->socket->remove_socket(charon->socket, &this->socket->socket);
- this->socket->destroy(this->socket);
+ charon->socket->remove_socket(charon->socket,
+ (socket_constructor_t)socket_raw_socket_create);
free(this);
}
@@ -53,16 +51,15 @@ plugin_t *socket_raw_plugin_create()
private_socket_raw_plugin_t *this;
INIT(this,
- .public.plugin.destroy = _destroy,
- .socket = socket_raw_socket_create(),
+ .public = {
+ .plugin = {
+ .destroy = _destroy,
+ },
+ },
);
- if (!this->socket)
- {
- free(this);
- return NULL;
- }
- charon->socket->add_socket(charon->socket, &this->socket->socket);
+ charon->socket->add_socket(charon->socket,
+ (socket_constructor_t)socket_raw_socket_create);
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/socket_raw/socket_raw_socket.c b/src/libcharon/plugins/socket_raw/socket_raw_socket.c
index 166870421..f6e87a86f 100644
--- a/src/libcharon/plugins/socket_raw/socket_raw_socket.c
+++ b/src/libcharon/plugins/socket_raw/socket_raw_socket.c
@@ -1,6 +1,7 @@
/*
- * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi
+ * Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -36,11 +37,12 @@
#include <linux/filter.h>
#include <net/if.h>
+#include <hydra.h>
#include <daemon.h>
#include <threading/thread.h>
/* Maximum size of a packet */
-#define MAX_PACKET 5000
+#define MAX_PACKET 10000
/* constants for packet handling */
#define IP_LEN sizeof(struct iphdr)
@@ -119,12 +121,17 @@ struct private_socket_raw_socket_t {
* send socket on nat-t port for IPv6
*/
int send6_natt;
+
+ /**
+ * Maximum packet size to receive
+ */
+ int max_packet;
};
METHOD(socket_t, receiver, status_t,
private_socket_raw_socket_t *this, packet_t **packet)
{
- char buffer[MAX_PACKET];
+ char buffer[this->max_packet];
chunk_t data;
packet_t *pkt;
struct udphdr *udp;
@@ -161,12 +168,17 @@ METHOD(socket_t, receiver, status_t,
struct iphdr *ip;
struct sockaddr_in src, dst;
- bytes_read = recv(this->recv4, buffer, MAX_PACKET, 0);
+ bytes_read = recv(this->recv4, buffer, this->max_packet, 0);
if (bytes_read < 0)
{
DBG1(DBG_NET, "error reading from IPv4 socket: %s", strerror(errno));
return FAILED;
}
+ if (bytes_read == this->max_packet)
+ {
+ DBG1(DBG_NET, "receive buffer too small, packet discarded");
+ return FAILED;
+ }
DBG3(DBG_NET, "received IPv4 packet %b", buffer, bytes_read);
/* read source/dest from raw IP/UDP header */
@@ -216,7 +228,7 @@ METHOD(socket_t, receiver, status_t,
msg.msg_name = &src;
msg.msg_namelen = sizeof(src);
iov.iov_base = buffer;
- iov.iov_len = sizeof(buffer);
+ iov.iov_len = this->max_packet;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = ancillary;
@@ -343,12 +355,6 @@ METHOD(socket_t, sender, status_t,
if (data.len != 1 || data.ptr[0] != 0xFF)
{
/* add non esp marker to packet */
- if (data.len > MAX_PACKET - MARKER_LEN)
- {
- DBG1(DBG_NET, "unable to send packet: it's too big (%d bytes)",
- data.len);
- return FAILED;
- }
marked = chunk_alloc(data.len + MARKER_LEN);
memset(marked.ptr, 0, MARKER_LEN);
memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len);
@@ -492,8 +498,8 @@ static int open_send_socket(private_socket_raw_socket_t *this,
}
}
- if (!charon->kernel_interface->bypass_socket(charon->kernel_interface,
- skt, family))
+ if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface,
+ skt, family))
{
DBG1(DBG_NET, "installing bypass policy on send socket failed");
}
@@ -598,8 +604,8 @@ static int open_recv_socket(private_socket_raw_socket_t *this, int family)
return 0;
}
- if (!charon->kernel_interface->bypass_socket(charon->kernel_interface,
- skt, family))
+ if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface,
+ skt, family))
{
DBG1(DBG_NET, "installing bypass policy on receive socket failed");
}
@@ -607,7 +613,7 @@ static int open_recv_socket(private_socket_raw_socket_t *this, int family)
return skt;
}
-METHOD(socket_raw_socket_t, destroy, void,
+METHOD(socket_t, destroy, void,
private_socket_raw_socket_t *this)
{
if (this->recv4)
@@ -649,9 +655,11 @@ socket_raw_socket_t *socket_raw_socket_create()
.socket = {
.send = _sender,
.receive = _receiver,
+ .destroy = _destroy,
},
- .destroy = _destroy,
},
+ .max_packet = lib->settings->get_int(lib->settings,
+ "charon.max_packet", MAX_PACKET),
);
this->recv4 = open_recv_socket(this, AF_INET);
diff --git a/src/libcharon/plugins/socket_raw/socket_raw_socket.h b/src/libcharon/plugins/socket_raw/socket_raw_socket.h
index 94cf666e8..23ff304a8 100644
--- a/src/libcharon/plugins/socket_raw/socket_raw_socket.h
+++ b/src/libcharon/plugins/socket_raw/socket_raw_socket.h
@@ -41,10 +41,6 @@ struct socket_raw_socket_t {
*/
socket_t socket;
- /**
- * Destroy a socket_raw_socket_t.
- */
- void (*destroy)(socket_raw_socket_t *this);
};
/**
diff --git a/src/libcharon/plugins/sql/Makefile.am b/src/libcharon/plugins/sql/Makefile.am
index 68b7e8cb2..37b87117c 100644
--- a/src/libcharon/plugins/sql/Makefile.am
+++ b/src/libcharon/plugins/sql/Makefile.am
@@ -2,9 +2,6 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon
-AM_CFLAGS = -rdynamic \
- -DPLUGINS=\""${libstrongswan_plugins}\""
-
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-sql.la
else
diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in
index e32dc7b57..7c4521785 100644
--- a/src/libcharon/plugins/sql/Makefile.in
+++ b/src/libcharon/plugins/sql/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -165,6 +166,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -196,14 +199,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -218,24 +224,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -243,7 +256,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
@@ -258,9 +274,6 @@ xml_LIBS = @xml_LIBS@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon
-AM_CFLAGS = -rdynamic \
- -DPLUGINS=\""${libstrongswan_plugins}\""
-
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-sql.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-sql.la
libstrongswan_sql_la_SOURCES = \
diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in
index e094200ca..e6e98838b 100644
--- a/src/libcharon/plugins/stroke/Makefile.in
+++ b/src/libcharon/plugins/stroke/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -168,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index 617069432..165212a5e 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -15,6 +15,7 @@
#include "stroke_config.h"
+#include <hydra.h>
#include <daemon.h>
#include <threading/mutex.h>
#include <utils/lexparser.h>
@@ -199,8 +200,8 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
host = host_create_from_dns(msg->add_conn.other.address, 0, 0);
if (host)
{
- interface = charon->kernel_interface->get_interface(
- charon->kernel_interface, host);
+ interface = hydra->kernel_interface->get_interface(
+ hydra->kernel_interface, host);
host->destroy(host);
if (interface)
{
@@ -215,8 +216,8 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
host = host_create_from_dns(msg->add_conn.me.address, 0, 0);
if (host)
{
- interface = charon->kernel_interface->get_interface(
- charon->kernel_interface, host);
+ interface = hydra->kernel_interface->get_interface(
+ hydra->kernel_interface, host);
host->destroy(host);
if (!interface)
{
@@ -362,7 +363,16 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
}
}
else
- { /* no second authentication round, fine */
+ { /* no second authentication round, fine. But load certificates
+ * for other purposes (EAP-TLS) */
+ if (cert)
+ {
+ certificate = this->cred->load_peer(this->cred, cert);
+ if (certificate)
+ {
+ certificate->destroy(certificate);
+ }
+ }
return NULL;
}
}
@@ -502,6 +512,11 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
}
cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, identity);
}
+ if (msg->add_conn.aaa_identity)
+ {
+ cfg->add(cfg, AUTH_RULE_AAA_IDENTITY,
+ identification_create_from_string(msg->add_conn.aaa_identity));
+ }
}
else
{
diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c
index f64421551..e0398ba78 100644
--- a/src/libcharon/plugins/stroke/stroke_control.c
+++ b/src/libcharon/plugins/stroke/stroke_control.c
@@ -354,7 +354,7 @@ static void terminate_srcip(private_stroke_control_t *this,
}
/* schedule delete asynchronously */
- charon->processor->queue_job(charon->processor, (job_t*)
+ lib->processor->queue_job(lib->processor, (job_t*)
delete_ike_sa_job_create(ike_sa->get_id(ike_sa), TRUE));
}
enumerator->destroy(enumerator);
diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c
index 2816b9bb2..91e71f1f4 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.c
+++ b/src/libcharon/plugins/stroke/stroke_cred.c
@@ -14,10 +14,15 @@
* for more details.
*/
+#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <glob.h>
#include <libgen.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
#include "stroke_cred.h"
#include "stroke_shared_key.h"
@@ -25,6 +30,8 @@
#include <credentials/certificates/x509.h>
#include <credentials/certificates/crl.h>
#include <credentials/certificates/ac.h>
+#include <credentials/sets/mem_cred.h>
+#include <credentials/sets/callback_cred.h>
#include <utils/linked_list.h>
#include <utils/lexparser.h>
#include <threading/rwlock.h>
@@ -88,7 +95,8 @@ struct private_stroke_cred_t {
typedef struct {
private_stroke_cred_t *this;
identification_t *id;
- certificate_type_t type;
+ certificate_type_t cert;
+ key_type_t key;
} id_data_t;
/**
@@ -109,15 +117,18 @@ static bool private_filter(id_data_t *data,
private_key_t *key;
key = *in;
- if (data->id == NULL)
+ if (data->key == KEY_ANY || data->key == key->get_type(key))
{
- *out = key;
- return TRUE;
- }
- if (key->has_fingerprint(key, data->id->get_encoding(data->id)))
- {
- *out = key;
- return TRUE;
+ if (data->id == NULL)
+ {
+ *out = key;
+ return TRUE;
+ }
+ if (key->has_fingerprint(key, data->id->get_encoding(data->id)))
+ {
+ *out = key;
+ return TRUE;
+ }
}
return FALSE;
}
@@ -133,6 +144,7 @@ static enumerator_t* create_private_enumerator(private_stroke_cred_t *this,
data = malloc_thing(id_data_t);
data->this = this;
data->id = id;
+ data->key = type;
this->lock->read_lock(this->lock);
return enumerator_create_filter(this->private->create_enumerator(this->private),
@@ -148,7 +160,7 @@ static bool certs_filter(id_data_t *data, certificate_t **in, certificate_t **ou
public_key_t *public;
certificate_t *cert = *in;
- if (data->type != CERT_ANY && data->type != cert->get_type(cert))
+ if (data->cert != CERT_ANY && data->cert != cert->get_type(cert))
{
return FALSE;
}
@@ -161,11 +173,14 @@ static bool certs_filter(id_data_t *data, certificate_t **in, certificate_t **ou
public = cert->get_public_key(cert);
if (public)
{
- if (public->has_fingerprint(public, data->id->get_encoding(data->id)))
+ if (data->key == KEY_ANY || data->key != public->get_type(public))
{
- public->destroy(public);
- *out = *in;
- return TRUE;
+ if (public->has_fingerprint(public, data->id->get_encoding(data->id)))
+ {
+ public->destroy(public);
+ *out = *in;
+ return TRUE;
+ }
}
public->destroy(public);
}
@@ -188,7 +203,8 @@ static enumerator_t* create_cert_enumerator(private_stroke_cred_t *this,
data = malloc_thing(id_data_t);
data->this = this;
data->id = id;
- data->type = cert;
+ data->cert = cert;
+ data->key = key;
this->lock->read_lock(this->lock);
return enumerator_create_filter(this->certs->create_enumerator(this->certs),
@@ -667,47 +683,443 @@ static err_t extract_secret(chunk_t *secret, chunk_t *line)
}
/**
- * Data to pass to passphrase_cb
+ * Data for passphrase callback
*/
typedef struct {
/** socket we use for prompting */
FILE *prompt;
/** private key file */
- char *file;
- /** buffer for passphrase */
- char buf[256];
+ char *path;
+ /** number of tries */
+ int try;
} passphrase_cb_data_t;
/**
- * Passphrase callback to read from whack fd
+ * Callback function to receive Passphrases
*/
-chunk_t passphrase_cb(passphrase_cb_data_t *data, int try)
+static shared_key_t* passphrase_cb(passphrase_cb_data_t *data,
+ shared_key_type_t type,
+ identification_t *me, identification_t *other,
+ id_match_t *match_me, id_match_t *match_other)
{
- chunk_t secret = chunk_empty;;
+ chunk_t secret;
+ char buf[256];
- if (try > 5)
+ if (type != SHARED_ANY && type != SHARED_PRIVATE_KEY_PASS)
{
- fprintf(data->prompt, "invalid passphrase, too many trials\n");
- return chunk_empty;
+ return NULL;
}
- if (try == 1)
+
+ if (data->try > 1)
{
- fprintf(data->prompt, "Private key '%s' is encrypted\n", data->file);
+ if (data->try > 5)
+ {
+ fprintf(data->prompt, "PIN invalid, giving up.\n");
+ return NULL;
+ }
+ fprintf(data->prompt, "PIN invalid!\n");
}
- else
+ data->try++;
+ fprintf(data->prompt, "Private key '%s' is encrypted.\n", data->path);
+ fprintf(data->prompt, "Passphrase:\n");
+ if (fgets(buf, sizeof(buf), data->prompt))
{
- fprintf(data->prompt, "invalid passphrase\n");
+ secret = chunk_create(buf, strlen(buf));
+ if (secret.len > 1)
+ { /* trim appended \n */
+ secret.len--;
+ if (match_me)
+ {
+ *match_me = ID_MATCH_PERFECT;
+ }
+ if (match_other)
+ {
+ *match_other = ID_MATCH_NONE;
+ }
+ return shared_key_create(SHARED_PRIVATE_KEY_PASS, chunk_clone(secret));
+ }
}
- fprintf(data->prompt, "Passphrase:\n");
- if (fgets(data->buf, sizeof(data->buf), data->prompt))
+ return NULL;
+}
+
+/**
+ * Data for PIN callback
+ */
+typedef struct {
+ /** socket we use for prompting */
+ FILE *prompt;
+ /** card label */
+ char *card;
+ /** card keyid */
+ chunk_t keyid;
+ /** number of tries */
+ int try;
+} pin_cb_data_t;
+
+/**
+ * Callback function to receive PINs
+ */
+static shared_key_t* pin_cb(pin_cb_data_t *data, shared_key_type_t type,
+ identification_t *me, identification_t *other,
+ id_match_t *match_me, id_match_t *match_other)
+{
+ chunk_t secret;
+ char buf[256];
+
+ if (type != SHARED_ANY && type != SHARED_PIN)
+ {
+ return NULL;
+ }
+
+ if (!me || !chunk_equals(me->get_encoding(me), data->keyid))
+ {
+ return NULL;
+ }
+
+ if (data->try > 1)
+ {
+ fprintf(data->prompt, "PIN invalid, aborting.\n");
+ return NULL;
+ }
+ data->try++;
+ fprintf(data->prompt, "Login to '%s' required\n", data->card);
+ fprintf(data->prompt, "PIN:\n");
+ if (fgets(buf, sizeof(buf), data->prompt))
{
- secret = chunk_create(data->buf, strlen(data->buf));
- if (secret.len)
+ secret = chunk_create(buf, strlen(buf));
+ if (secret.len > 1)
{ /* trim appended \n */
secret.len--;
+ if (match_me)
+ {
+ *match_me = ID_MATCH_PERFECT;
+ }
+ if (match_other)
+ {
+ *match_other = ID_MATCH_NONE;
+ }
+ return shared_key_create(SHARED_PIN, chunk_clone(secret));
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Load a smartcard with a PIN
+ */
+static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr,
+ FILE *prompt)
+{
+ chunk_t sc = chunk_empty, secret = chunk_empty;
+ char smartcard[64], keyid[64], module[64], *pos;
+ private_key_t *key = NULL;
+ u_int slot;
+ chunk_t chunk;
+ shared_key_t *shared;
+ identification_t *id;
+ mem_cred_t *mem = NULL;
+ callback_cred_t *cb = NULL;
+ pin_cb_data_t pin_data;
+ enum {
+ SC_FORMAT_SLOT_MODULE_KEYID,
+ SC_FORMAT_SLOT_KEYID,
+ SC_FORMAT_KEYID,
+ } format;
+
+ err_t ugh = extract_value(&sc, &line);
+
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
+ return FALSE;
+ }
+ if (sc.len == 0)
+ {
+ DBG1(DBG_CFG, "line %d: expected %%smartcard specifier", line_nr);
+ return FALSE;
+ }
+ snprintf(smartcard, sizeof(smartcard), "%.*s", sc.len, sc.ptr);
+ smartcard[sizeof(smartcard) - 1] = '\0';
+
+ /* parse slot and key id. Three formats are supported:
+ * - %smartcard<slot>@<module>:<keyid>
+ * - %smartcard<slot>:<keyid>
+ * - %smartcard:<keyid>
+ */
+ if (sscanf(smartcard, "%%smartcard%u@%s", &slot, module) == 2)
+ {
+ pos = strchr(module, ':');
+ if (!pos)
+ {
+ DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is "
+ "invalid", line_nr);
+ return FALSE;
+ }
+ *pos = '\0';
+ strcpy(keyid, pos + 1);
+ format = SC_FORMAT_SLOT_MODULE_KEYID;
+ }
+ else if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2)
+ {
+ format = SC_FORMAT_SLOT_KEYID;
+ }
+ else if (sscanf(smartcard, "%%smartcard:%s", keyid) == 1)
+ {
+ format = SC_FORMAT_KEYID;
+ }
+ else
+ {
+ DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is not"
+ " supported or invalid", line_nr);
+ return FALSE;
+ }
+
+ if (!eat_whitespace(&line))
+ {
+ DBG1(DBG_CFG, "line %d: expected PIN", line_nr);
+ return FALSE;
+ }
+ ugh = extract_secret(&secret, &line);
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "line %d: malformed PIN: %s", line_nr, ugh);
+ return FALSE;
+ }
+
+ chunk = chunk_from_hex(chunk_create(keyid, strlen(keyid)), NULL);
+ if (secret.len == 7 && strneq(secret.ptr, "%prompt", 7))
+ {
+ free(secret.ptr);
+ if (!prompt)
+ { /* no IO channel to prompt, skip */
+ free(chunk.ptr);
+ return TRUE;
+ }
+ /* use callback credential set to prompt for the pin */
+ pin_data.prompt = prompt;
+ pin_data.card = smartcard;
+ pin_data.keyid = chunk;
+ pin_data.try = 1;
+ cb = callback_cred_create_shared((void*)pin_cb, &pin_data);
+ lib->credmgr->add_local_set(lib->credmgr, &cb->set);
+ }
+ else
+ {
+ /* provide our pin in a temporary credential set */
+ shared = shared_key_create(SHARED_PIN, secret);
+ id = identification_create_from_encoding(ID_KEY_ID, chunk);
+ mem = mem_cred_create();
+ mem->add_shared(mem, shared, id, NULL);
+ lib->credmgr->add_local_set(lib->credmgr, &mem->set);
+ }
+
+ /* unlock: smartcard needs the pin and potentially calls public set */
+ this->lock->unlock(this->lock);
+ switch (format)
+ {
+ case SC_FORMAT_SLOT_MODULE_KEYID:
+ key = lib->creds->create(lib->creds,
+ CRED_PRIVATE_KEY, KEY_ANY,
+ BUILD_PKCS11_SLOT, slot,
+ BUILD_PKCS11_MODULE, module,
+ BUILD_PKCS11_KEYID, chunk, BUILD_END);
+ break;
+ case SC_FORMAT_SLOT_KEYID:
+ key = lib->creds->create(lib->creds,
+ CRED_PRIVATE_KEY, KEY_ANY,
+ BUILD_PKCS11_SLOT, slot,
+ BUILD_PKCS11_KEYID, chunk, BUILD_END);
+ break;
+ case SC_FORMAT_KEYID:
+ key = lib->creds->create(lib->creds,
+ CRED_PRIVATE_KEY, KEY_ANY,
+ BUILD_PKCS11_KEYID, chunk, BUILD_END);
+ break;
+ }
+ this->lock->write_lock(this->lock);
+ if (mem)
+ {
+ lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
+ mem->destroy(mem);
+ }
+ if (cb)
+ {
+ lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
+ cb->destroy(cb);
+ }
+
+ if (key)
+ {
+ DBG1(DBG_CFG, " loaded private key from %.*s", sc.len, sc.ptr);
+ this->private->insert_last(this->private, key);
+ }
+ return TRUE;
+}
+
+/**
+ * Load a private key
+ */
+static bool load_private(private_stroke_cred_t *this, chunk_t line, int line_nr,
+ FILE *prompt, key_type_t key_type)
+{
+ char path[PATH_MAX];
+ chunk_t filename;
+ chunk_t secret = chunk_empty;
+ private_key_t *key;
+
+ err_t ugh = extract_value(&filename, &line);
+
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
+ return FALSE;
+ }
+ if (filename.len == 0)
+ {
+ DBG1(DBG_CFG, "line %d: empty filename", line_nr);
+ return FALSE;
+ }
+ if (*filename.ptr == '/')
+ {
+ /* absolute path name */
+ snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
+ }
+ else
+ {
+ /* relative path name */
+ snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR,
+ filename.len, filename.ptr);
+ }
+
+ /* check for optional passphrase */
+ if (eat_whitespace(&line))
+ {
+ ugh = extract_secret(&secret, &line);
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
+ return FALSE;
+ }
+ }
+ if (secret.len == 7 && strneq(secret.ptr, "%prompt", 7))
+ {
+ callback_cred_t *cb = NULL;
+ passphrase_cb_data_t pp_data = {
+ .prompt = prompt,
+ .path = path,
+ .try = 1,
+ };
+
+ free(secret.ptr);
+ if (!prompt)
+ {
+ return TRUE;
+ }
+ /* use callback credential set to prompt for the passphrase */
+ pp_data.prompt = prompt;
+ pp_data.path = path;
+ pp_data.try = 1;
+ cb = callback_cred_create_shared((void*)passphrase_cb, &pp_data);
+ lib->credmgr->add_local_set(lib->credmgr, &cb->set);
+
+ /* unlock, as the builder might ask for a secret */
+ this->lock->unlock(this->lock);
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type,
+ BUILD_FROM_FILE, path, BUILD_END);
+ this->lock->write_lock(this->lock);
+
+ lib->credmgr->remove_local_set(lib->credmgr, &cb->set);
+ cb->destroy(cb);
+ }
+ else
+ {
+ mem_cred_t *mem = NULL;
+ shared_key_t *shared;
+
+ /* provide our pin in a temporary credential set */
+ shared = shared_key_create(SHARED_PRIVATE_KEY_PASS, secret);
+ mem = mem_cred_create();
+ mem->add_shared(mem, shared, NULL);
+ lib->credmgr->add_local_set(lib->credmgr, &mem->set);
+
+ /* unlock, as the builder might ask for a secret */
+ this->lock->unlock(this->lock);
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type,
+ BUILD_FROM_FILE, path, BUILD_END);
+ this->lock->write_lock(this->lock);
+
+ lib->credmgr->remove_local_set(lib->credmgr, &mem->set);
+ mem->destroy(mem);
+ }
+ if (key)
+ {
+ DBG1(DBG_CFG, " loaded %N private key from '%s'",
+ key_type_names, key->get_type(key), path);
+ this->private->insert_last(this->private, key);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loading private key from '%s' failed", path);
+ }
+ return TRUE;
+}
+
+/**
+ * Load a shared key
+ */
+static bool load_shared(private_stroke_cred_t *this, chunk_t line, int line_nr,
+ shared_key_type_t type, chunk_t ids)
+{
+ stroke_shared_key_t *shared_key;
+ chunk_t secret = chunk_empty;
+ bool any = TRUE;
+
+ err_t ugh = extract_secret(&secret, &line);
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
+ return FALSE;
+ }
+ shared_key = stroke_shared_key_create(type, secret);
+ DBG1(DBG_CFG, " loaded %N secret for %s", shared_key_type_names, type,
+ ids.len > 0 ? (char*)ids.ptr : "%any");
+ DBG4(DBG_CFG, " secret: %#B", &secret);
+
+ this->shared->insert_last(this->shared, shared_key);
+ while (ids.len > 0)
+ {
+ chunk_t id;
+ identification_t *peer_id;
+
+ ugh = extract_value(&id, &ids);
+ if (ugh != NULL)
+ {
+ DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
+ return FALSE;
+ }
+ if (id.len == 0)
+ {
+ continue;
+ }
+
+ /* NULL terminate the ID string */
+ *(id.ptr + id.len) = '\0';
+ peer_id = identification_create_from_string(id.ptr);
+ if (peer_id->get_type(peer_id) == ID_ANY)
+ {
+ peer_id->destroy(peer_id);
+ continue;
}
+
+ shared_key->add_owner(shared_key, peer_id);
+ any = FALSE;
+ }
+ if (any)
+ {
+ shared_key->add_owner(shared_key,
+ identification_create_from_encoding(ID_ANY, chunk_empty));
}
- return secret;
+ return TRUE;
}
/**
@@ -716,30 +1128,36 @@ chunk_t passphrase_cb(passphrase_cb_data_t *data, int try)
static void load_secrets(private_stroke_cred_t *this, char *file, int level,
FILE *prompt)
{
- size_t bytes;
- int line_nr = 0;
- chunk_t chunk, src, line;
- FILE *fd;
+ int line_nr = 0, fd;
+ chunk_t src, line;
private_key_t *private;
shared_key_t *shared;
+ struct stat sb;
+ void *addr;
DBG1(DBG_CFG, "loading secrets from '%s'", file);
-
- fd = fopen(file, "r");
- if (fd == NULL)
+ fd = open(file, O_RDONLY);
+ if (fd == -1)
{
- DBG1(DBG_CFG, "opening secrets file '%s' failed", file);
+ DBG1(DBG_CFG, "opening secrets file '%s' failed: %s", file,
+ strerror(errno));
return;
}
-
- /* TODO: do error checks */
- fseek(fd, 0, SEEK_END);
- chunk.len = ftell(fd);
- rewind(fd);
- chunk.ptr = malloc(chunk.len);
- bytes = fread(chunk.ptr, 1, chunk.len, fd);
- fclose(fd);
- src = chunk;
+ if (fstat(fd, &sb) == -1)
+ {
+ DBG1(DBG_LIB, "getting file size of '%s' failed: %s", file,
+ strerror(errno));
+ close(fd);
+ return;
+ }
+ addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ if (addr == MAP_FAILED)
+ {
+ DBG1(DBG_LIB, "mapping '%s' failed: %s", file, strerror(errno));
+ close(fd);
+ return;
+ }
+ src = chunk_create(addr, sb.st_size);
if (level == 0)
{
@@ -844,223 +1262,52 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
else
{
DBG1(DBG_CFG, "line %d: missing ' : ' separator", line_nr);
- goto error;
+ break;
}
if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
{
DBG1(DBG_CFG, "line %d: missing token", line_nr);
- goto error;
+ break;
}
if (match("RSA", &token) || match("ECDSA", &token))
{
- char path[PATH_MAX];
- chunk_t filename;
- chunk_t secret = chunk_empty;
- private_key_t *key = NULL;
- key_type_t key_type = match("RSA", &token) ? KEY_RSA : KEY_ECDSA;
-
- err_t ugh = extract_value(&filename, &line);
-
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
- goto error;
- }
- if (filename.len == 0)
- {
- DBG1(DBG_CFG, "line %d: empty filename", line_nr);
- goto error;
- }
- if (*filename.ptr == '/')
- {
- /* absolute path name */
- snprintf(path, sizeof(path), "%.*s", filename.len, filename.ptr);
- }
- else
- {
- /* relative path name */
- snprintf(path, sizeof(path), "%s/%.*s", PRIVATE_KEY_DIR,
- filename.len, filename.ptr);
- }
-
- /* check for optional passphrase */
- if (eat_whitespace(&line))
- {
- ugh = extract_secret(&secret, &line);
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "line %d: malformed passphrase: %s", line_nr, ugh);
- goto error;
- }
- }
- if (secret.len == 7 && strneq(secret.ptr, "%prompt", 7))
- {
- if (prompt)
- {
- passphrase_cb_data_t data;
-
- data.prompt = prompt;
- data.file = path;
- key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
- key_type, BUILD_FROM_FILE, path,
- BUILD_PASSPHRASE_CALLBACK,
- passphrase_cb, &data, BUILD_END);
- }
- }
- else
- {
- key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, key_type,
- BUILD_FROM_FILE, path,
- BUILD_PASSPHRASE, secret, BUILD_END);
- }
- if (key)
+ if (!load_private(this, line, line_nr, prompt,
+ match("RSA", &token) ? KEY_RSA : KEY_ECDSA))
{
- DBG1(DBG_CFG, " loaded %N private key from '%s'",
- key_type_names, key->get_type(key), path);
- this->private->insert_last(this->private, key);
- }
- else
- {
- DBG1(DBG_CFG, " loading private key from '%s' failed", path);
+ break;
}
- chunk_clear(&secret);
}
else if (match("PIN", &token))
{
- chunk_t sc = chunk_empty, secret = chunk_empty;
- char smartcard[32], keyid[22], pin[32];
- private_key_t *key;
- u_int slot;
-
- err_t ugh = extract_value(&sc, &line);
-
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
- goto error;
- }
- if (sc.len == 0)
- {
- DBG1(DBG_CFG, "line %d: expected %%smartcard specifier", line_nr);
- goto error;
- }
- snprintf(smartcard, sizeof(smartcard), "%.*s", sc.len, sc.ptr);
- smartcard[sizeof(smartcard) - 1] = '\0';
-
- /* parse slot and key id. only two formats are supported.
- * first try %smartcard<slot>:<keyid> */
- if (sscanf(smartcard, "%%smartcard%u:%s", &slot, keyid) == 2)
- {
- snprintf(smartcard, sizeof(smartcard), "%u:%s", slot, keyid);
- }
- /* then try %smartcard:<keyid> */
- else if (sscanf(smartcard, "%%smartcard:%s", keyid) == 1)
- {
- snprintf(smartcard, sizeof(smartcard), "%s", keyid);
- }
- else
- {
- DBG1(DBG_CFG, "line %d: the given %%smartcard specifier is not"
- " supported or invalid", line_nr);
- goto error;
- }
-
- if (!eat_whitespace(&line))
- {
- DBG1(DBG_CFG, "line %d: expected PIN", line_nr);
- goto error;
- }
- ugh = extract_secret(&secret, &line);
- if (ugh != NULL)
+ if (!load_pin(this, line, line_nr, prompt))
{
- DBG1(DBG_CFG, "line %d: malformed PIN: %s", line_nr, ugh);
- goto error;
- }
- snprintf(pin, sizeof(pin), "%.*s", secret.len, secret.ptr);
- pin[sizeof(pin) - 1] = '\0';
-
- /* we assume an RSA key */
- key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
- BUILD_SMARTCARD_KEYID, smartcard,
- BUILD_SMARTCARD_PIN, pin, BUILD_END);
-
- if (key)
- {
- DBG1(DBG_CFG, " loaded private key from %.*s", sc.len, sc.ptr);
- this->private->insert_last(this->private, key);
+ break;
}
- memset(pin, 0, sizeof(pin));
- chunk_clear(&secret);
}
else if ((match("PSK", &token) && (type = SHARED_IKE)) ||
(match("EAP", &token) && (type = SHARED_EAP)) ||
(match("NTLM", &token) && (type = SHARED_NT_HASH)) ||
(match("XAUTH", &token) && (type = SHARED_EAP)))
{
- stroke_shared_key_t *shared_key;
- chunk_t secret = chunk_empty;
- bool any = TRUE;
-
- err_t ugh = extract_secret(&secret, &line);
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
- goto error;
- }
- shared_key = stroke_shared_key_create(type, secret);
- DBG1(DBG_CFG, " loaded %N secret for %s", shared_key_type_names, type,
- ids.len > 0 ? (char*)ids.ptr : "%any");
- DBG4(DBG_CFG, " secret: %#B", &secret);
-
- this->shared->insert_last(this->shared, shared_key);
- while (ids.len > 0)
+ if (!load_shared(this, line, line_nr, type, ids))
{
- chunk_t id;
- identification_t *peer_id;
-
- ugh = extract_value(&id, &ids);
- if (ugh != NULL)
- {
- DBG1(DBG_CFG, "line %d: %s", line_nr, ugh);
- goto error;
- }
- if (id.len == 0)
- {
- continue;
- }
-
- /* NULL terminate the ID string */
- *(id.ptr + id.len) = '\0';
- peer_id = identification_create_from_string(id.ptr);
- if (peer_id->get_type(peer_id) == ID_ANY)
- {
- peer_id->destroy(peer_id);
- continue;
- }
-
- shared_key->add_owner(shared_key, peer_id);
- any = FALSE;
- }
- if (any)
- {
- shared_key->add_owner(shared_key,
- identification_create_from_encoding(ID_ANY, chunk_empty));
+ break;
}
}
else
{
DBG1(DBG_CFG, "line %d: token must be either "
"RSA, ECDSA, PSK, EAP, XAUTH or PIN", line_nr);
- goto error;
+ break;
}
}
-error:
if (level == 0)
{
this->lock->unlock(this->lock);
}
- chunk_clear(&chunk);
+ munmap(addr, sb.st_size);
+ close(fd);
}
/**
diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c
index a6de35466..86deea490 100644
--- a/src/libcharon/plugins/stroke/stroke_list.c
+++ b/src/libcharon/plugins/stroke/stroke_list.c
@@ -21,6 +21,7 @@
#include <malloc.h>
#endif /* HAVE_MALLINFO */
+#include <hydra.h>
#include <daemon.h>
#include <utils/linked_list.h>
#include <credentials/certificates/x509.h>
@@ -422,12 +423,12 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
}
#endif /* HAVE_MALLINFO */
fprintf(out, " worker threads: %d idle of %d,",
- charon->processor->get_idle_threads(charon->processor),
- charon->processor->get_total_threads(charon->processor));
+ lib->processor->get_idle_threads(lib->processor),
+ lib->processor->get_total_threads(lib->processor));
fprintf(out, " job queue load: %d,",
- charon->processor->get_job_load(charon->processor));
+ lib->processor->get_job_load(lib->processor));
fprintf(out, " scheduled events: %d\n",
- charon->scheduler->get_job_load(charon->scheduler));
+ lib->scheduler->get_job_load(lib->scheduler));
fprintf(out, " loaded plugins: ");
enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
while (enumerator->enumerate(enumerator, &plugin))
@@ -454,8 +455,8 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
}
enumerator->destroy(enumerator);
- enumerator = charon->kernel_interface->create_address_enumerator(
- charon->kernel_interface, FALSE, FALSE);
+ enumerator = hydra->kernel_interface->create_address_enumerator(
+ hydra->kernel_interface, FALSE, FALSE);
fprintf(out, "Listening IP addresses:\n");
while (enumerator->enumerate(enumerator, (void**)&host))
{
@@ -638,7 +639,7 @@ static void list_public_key(public_key_t *public, FILE *out)
fprintf(out, " pubkey: %N %d bits%s\n",
key_type_names, public->get_type(public),
- public->get_keysize(public) * 8,
+ public->get_keysize(public),
private ? ", has private key" : "");
if (public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid))
{
@@ -1026,9 +1027,10 @@ static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out)
*/
static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out)
{
- bool first = TRUE;
+ bool first = TRUE, ok;
enumerator_t *enumerator = list->create_enumerator(list);
certificate_t *cert;
+ time_t produced, usable, now = time(NULL);
while (enumerator->enumerate(enumerator, (void**)&cert))
{
@@ -1039,8 +1041,20 @@ static void stroke_list_ocsp(linked_list_t* list, bool utc, FILE *out)
fprintf(out, "\n");
first = FALSE;
}
-
fprintf(out, " signer: \"%Y\"\n", cert->get_issuer(cert));
+
+ /* check validity */
+ ok = cert->get_validity(cert, &now, &produced, &usable);
+ fprintf(out, " validity: produced at %T\n", &produced, utc);
+ fprintf(out, " usable till %T, ", &usable, utc);
+ if (ok)
+ {
+ fprintf(out, "ok\n");
+ }
+ else
+ {
+ fprintf(out, "expired (%V ago)\n", &now, &usable);
+ }
}
enumerator->destroy(enumerator);
}
@@ -1073,6 +1087,13 @@ static void list_algs(FILE *out)
fprintf(out, "%N ", integrity_algorithm_names, integrity);
}
enumerator->destroy(enumerator);
+ fprintf(out, "\n aead: ");
+ enumerator = lib->crypto->create_aead_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &encryption))
+ {
+ fprintf(out, "%N ", encryption_algorithm_names, encryption);
+ }
+ enumerator->destroy(enumerator);
fprintf(out, "\n hasher: ");
enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
while (enumerator->enumerate(enumerator, &hash))
@@ -1184,7 +1205,7 @@ static void pool_leases(private_stroke_list_t *this, FILE *out, char *pool,
bool on;
int found = 0;
- fprintf(out, "Leases in pool '%s', usage: %lu/%lu, %lu online\n",
+ fprintf(out, "Leases in pool '%s', usage: %u/%u, %u online\n",
pool, online + offline, size, online);
enumerator = this->attribute->create_lease_enumerator(this->attribute, pool);
while (enumerator && enumerator->enumerate(enumerator, &id, &lease, &on))
diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c
index 18afa5af4..0a5110fd3 100644
--- a/src/libcharon/plugins/stroke/stroke_socket.c
+++ b/src/libcharon/plugins/stroke/stroke_socket.c
@@ -24,10 +24,10 @@
#include <unistd.h>
#include <errno.h>
-#include <processing/jobs/callback_job.h>
#include <hydra.h>
#include <daemon.h>
#include <threading/thread.h>
+#include <processing/jobs/callback_job.h>
#include "stroke_config.h"
#include "stroke_control.h"
@@ -180,11 +180,13 @@ static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg)
pop_end(msg, "left", &msg->add_conn.me);
pop_end(msg, "right", &msg->add_conn.other);
pop_string(msg, &msg->add_conn.eap_identity);
+ pop_string(msg, &msg->add_conn.aaa_identity);
pop_string(msg, &msg->add_conn.algorithms.ike);
pop_string(msg, &msg->add_conn.algorithms.esp);
pop_string(msg, &msg->add_conn.ikeme.mediated_by);
pop_string(msg, &msg->add_conn.ikeme.peerid);
DBG2(DBG_CFG, " eap_identity=%s", msg->add_conn.eap_identity);
+ DBG2(DBG_CFG, " aaa_identity=%s", msg->add_conn.aaa_identity);
DBG2(DBG_CFG, " ike=%s", msg->add_conn.algorithms.ike);
DBG2(DBG_CFG, " esp=%s", msg->add_conn.algorithms.esp);
DBG2(DBG_CFG, " mediation=%s", msg->add_conn.ikeme.mediation ? "yes" : "no");
@@ -353,6 +355,37 @@ static void stroke_purge(private_stroke_socket_t *this,
}
/**
+ * Export in-memory credentials
+ */
+static void stroke_export(private_stroke_socket_t *this,
+ stroke_msg_t *msg, FILE *out)
+{
+ pop_string(msg, &msg->export.selector);
+
+ if (msg->purge.flags & EXPORT_X509)
+ {
+ enumerator_t *enumerator;
+ identification_t *id;
+ certificate_t *cert;
+ chunk_t encoded;
+
+ id = identification_create_from_string(msg->export.selector);
+ enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
+ CERT_X509, KEY_ANY, id, FALSE);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ if (cert->get_encoding(cert, CERT_PEM, &encoded))
+ {
+ fprintf(out, "%.*s", encoded.len, encoded.ptr);
+ free(encoded.ptr);
+ }
+ }
+ enumerator->destroy(enumerator);
+ id->destroy(id);
+ }
+}
+
+/**
* list pool leases
*/
static void stroke_leases(private_stroke_socket_t *this,
@@ -364,21 +397,6 @@ static void stroke_leases(private_stroke_socket_t *this,
this->list->leases(this->list, msg, out);
}
-debug_t get_group_from_name(char *type)
-{
- if (strcaseeq(type, "any")) return DBG_ANY;
- else if (strcaseeq(type, "mgr")) return DBG_MGR;
- else if (strcaseeq(type, "ike")) return DBG_IKE;
- else if (strcaseeq(type, "chd")) return DBG_CHD;
- else if (strcaseeq(type, "job")) return DBG_JOB;
- else if (strcaseeq(type, "cfg")) return DBG_CFG;
- else if (strcaseeq(type, "knl")) return DBG_KNL;
- else if (strcaseeq(type, "net")) return DBG_NET;
- else if (strcaseeq(type, "enc")) return DBG_ENC;
- else if (strcaseeq(type, "lib")) return DBG_LIB;
- else return -1;
-}
-
/**
* set the verbosity debug output
*/
@@ -394,7 +412,7 @@ static void stroke_loglevel(private_stroke_socket_t *this,
DBG1(DBG_CFG, "received stroke: loglevel %d for %s",
msg->loglevel.level, msg->loglevel.type);
- group = get_group_from_name(msg->loglevel.type);
+ group = enum_from_name(debug_names, msg->loglevel.type);
if (group < 0)
{
fprintf(out, "invalid type (%s)!\n", msg->loglevel.type);
@@ -525,6 +543,9 @@ static job_requeue_t process(stroke_job_context_t *ctx)
case STR_PURGE:
stroke_purge(this, msg, out);
break;
+ case STR_EXPORT:
+ stroke_export(this, msg, out);
+ break;
case STR_LEASES:
stroke_leases(this, msg, out);
break;
@@ -565,7 +586,7 @@ static job_requeue_t receive(private_stroke_socket_t *this)
ctx->this = this;
job = callback_job_create((callback_job_cb_t)process,
ctx, (void*)stroke_job_context_destroy, this->job);
- charon->processor->queue_job(charon->processor, (job_t*)job);
+ lib->processor->queue_job(lib->processor, (job_t*)job);
return JOB_REQUEUE_FAIR;
}
@@ -663,7 +684,7 @@ stroke_socket_t *stroke_socket_create()
this->job = callback_job_create((callback_job_cb_t)receive,
this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
}
diff --git a/src/libcharon/plugins/tnc_imc/Makefile.am b/src/libcharon/plugins/tnc_imc/Makefile.am
new file mode 100644
index 000000000..ca8869460
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imc/Makefile.am
@@ -0,0 +1,19 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon `xml2-config --cflags`
+
+AM_CFLAGS = -rdynamic
+
+libstrongswan_tnc_imc_la_LIBADD = -ltnc
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-tnc-imc.la
+else
+plugin_LTLIBRARIES = libstrongswan-tnc-imc.la
+endif
+
+libstrongswan_tnc_imc_la_SOURCES = \
+ tnc_imc_plugin.h tnc_imc_plugin.c
+
+libstrongswan_tnc_imc_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libcharon/plugins/kernel_pfroute/Makefile.in b/src/libcharon/plugins/tnc_imc/Makefile.in
index f78a97013..9a8794e93 100644
--- a/src/libcharon/plugins/kernel_pfroute/Makefile.in
+++ b/src/libcharon/plugins/tnc_imc/Makefile.in
@@ -34,7 +34,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-subdir = src/libcharon/plugins/kernel_pfroute
+subdir = src/libcharon/plugins/tnc_imc
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -73,18 +74,16 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_kernel_pfroute_la_LIBADD =
-am_libstrongswan_kernel_pfroute_la_OBJECTS = kernel_pfroute_plugin.lo \
- kernel_pfroute_net.lo
-libstrongswan_kernel_pfroute_la_OBJECTS = \
- $(am_libstrongswan_kernel_pfroute_la_OBJECTS)
-libstrongswan_kernel_pfroute_la_LINK = $(LIBTOOL) --tag=CC \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
- $(AM_CFLAGS) $(CFLAGS) \
- $(libstrongswan_kernel_pfroute_la_LDFLAGS) $(LDFLAGS) -o $@
-@MONOLITHIC_FALSE@am_libstrongswan_kernel_pfroute_la_rpath = -rpath \
+libstrongswan_tnc_imc_la_DEPENDENCIES =
+am_libstrongswan_tnc_imc_la_OBJECTS = tnc_imc_plugin.lo
+libstrongswan_tnc_imc_la_OBJECTS = \
+ $(am_libstrongswan_tnc_imc_la_OBJECTS)
+libstrongswan_tnc_imc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_tnc_imc_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_tnc_imc_la_rpath = -rpath \
@MONOLITHIC_FALSE@ $(plugindir)
-@MONOLITHIC_TRUE@am_libstrongswan_kernel_pfroute_la_rpath =
+@MONOLITHIC_TRUE@am_libstrongswan_tnc_imc_la_rpath =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -98,8 +97,8 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libstrongswan_kernel_pfroute_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_kernel_pfroute_la_SOURCES)
+SOURCES = $(libstrongswan_tnc_imc_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_tnc_imc_la_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -168,6 +167,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +200,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +225,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +257,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
@@ -258,17 +272,17 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \
- -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon `xml2-config --cflags`
AM_CFLAGS = -rdynamic
-@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-pfroute.la
-@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-pfroute.la
-libstrongswan_kernel_pfroute_la_SOURCES = \
- kernel_pfroute_plugin.h kernel_pfroute_plugin.c \
- kernel_pfroute_net.h kernel_pfroute_net.c
+libstrongswan_tnc_imc_la_LIBADD = -ltnc
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imc.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imc.la
+libstrongswan_tnc_imc_la_SOURCES = \
+ tnc_imc_plugin.h tnc_imc_plugin.c
-libstrongswan_kernel_pfroute_la_LDFLAGS = -module -avoid-version
+libstrongswan_tnc_imc_la_LDFLAGS = -module -avoid-version
all: all-am
.SUFFIXES:
@@ -282,9 +296,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_pfroute/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_imc/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_pfroute/Makefile
+ $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_imc/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -343,8 +357,8 @@ clean-pluginLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libstrongswan-kernel-pfroute.la: $(libstrongswan_kernel_pfroute_la_OBJECTS) $(libstrongswan_kernel_pfroute_la_DEPENDENCIES)
- $(libstrongswan_kernel_pfroute_la_LINK) $(am_libstrongswan_kernel_pfroute_la_rpath) $(libstrongswan_kernel_pfroute_la_OBJECTS) $(libstrongswan_kernel_pfroute_la_LIBADD) $(LIBS)
+libstrongswan-tnc-imc.la: $(libstrongswan_tnc_imc_la_OBJECTS) $(libstrongswan_tnc_imc_la_DEPENDENCIES)
+ $(libstrongswan_tnc_imc_la_LINK) $(am_libstrongswan_tnc_imc_la_rpath) $(libstrongswan_tnc_imc_la_OBJECTS) $(libstrongswan_tnc_imc_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -352,8 +366,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfroute_net.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfroute_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imc_plugin.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
new file mode 100644
index 000000000..0ce930ba3
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "tnc_imc_plugin.h"
+
+#include <libtnctncc.h>
+
+#include <daemon.h>
+
+METHOD(plugin_t, destroy, void,
+ tnc_imc_plugin_t *this)
+{
+ libtnc_tncc_Terminate();
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *tnc_imc_plugin_create()
+{
+ char *tnc_config, *pref_lang;
+ tnc_imc_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .destroy = _destroy,
+ },
+ );
+
+ pref_lang = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-imc.preferred_language", "en");
+ tnc_config = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-imc.tnc_config", "/etc/tnc_config");
+
+ if (libtnc_tncc_Initialize(tnc_config) != TNC_RESULT_SUCCESS)
+ {
+ free(this);
+ DBG1(DBG_TNC, "TNC IMC initialization failed");
+ return NULL;
+ }
+
+ return &this->plugin;
+}
+
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.h b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.h
new file mode 100644
index 000000000..8c5521cb2
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tnc_imc tnc_imc
+ * @ingroup cplugins
+ *
+ * @defgroup tnc_imc_plugin tnc_imc_plugin
+ * @{ @ingroup tnc_imc
+ */
+
+#ifndef TNC_IMC_PLUGIN_H_
+#define TNC_IMC_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct tnc_imc_plugin_t tnc_imc_plugin_t;
+
+/**
+ * TNC IMC plugin
+ */
+struct tnc_imc_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** TNC_IMC_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_imv/Makefile.am b/src/libcharon/plugins/tnc_imv/Makefile.am
new file mode 100644
index 000000000..9c3b47364
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imv/Makefile.am
@@ -0,0 +1,19 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon `xml2-config --cflags`
+
+AM_CFLAGS = -rdynamic
+
+libstrongswan_tnc_imv_la_LIBADD = -ltnc
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-tnc-imv.la
+else
+plugin_LTLIBRARIES = libstrongswan-tnc-imv.la
+endif
+
+libstrongswan_tnc_imv_la_SOURCES = \
+ tnc_imv_plugin.h tnc_imv_plugin.c
+
+libstrongswan_tnc_imv_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libcharon/plugins/kernel_pfkey/Makefile.in b/src/libcharon/plugins/tnc_imv/Makefile.in
index 1dda6827b..f89b5e03b 100644
--- a/src/libcharon/plugins/kernel_pfkey/Makefile.in
+++ b/src/libcharon/plugins/tnc_imv/Makefile.in
@@ -34,7 +34,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-subdir = src/libcharon/plugins/kernel_pfkey
+subdir = src/libcharon/plugins/tnc_imv
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -73,18 +74,16 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_kernel_pfkey_la_LIBADD =
-am_libstrongswan_kernel_pfkey_la_OBJECTS = kernel_pfkey_plugin.lo \
- kernel_pfkey_ipsec.lo
-libstrongswan_kernel_pfkey_la_OBJECTS = \
- $(am_libstrongswan_kernel_pfkey_la_OBJECTS)
-libstrongswan_kernel_pfkey_la_LINK = $(LIBTOOL) --tag=CC \
- $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
- $(AM_CFLAGS) $(CFLAGS) \
- $(libstrongswan_kernel_pfkey_la_LDFLAGS) $(LDFLAGS) -o $@
-@MONOLITHIC_FALSE@am_libstrongswan_kernel_pfkey_la_rpath = -rpath \
+libstrongswan_tnc_imv_la_DEPENDENCIES =
+am_libstrongswan_tnc_imv_la_OBJECTS = tnc_imv_plugin.lo
+libstrongswan_tnc_imv_la_OBJECTS = \
+ $(am_libstrongswan_tnc_imv_la_OBJECTS)
+libstrongswan_tnc_imv_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_tnc_imv_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_tnc_imv_la_rpath = -rpath \
@MONOLITHIC_FALSE@ $(plugindir)
-@MONOLITHIC_TRUE@am_libstrongswan_kernel_pfkey_la_rpath =
+@MONOLITHIC_TRUE@am_libstrongswan_tnc_imv_la_rpath =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -98,8 +97,8 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libstrongswan_kernel_pfkey_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_kernel_pfkey_la_SOURCES)
+SOURCES = $(libstrongswan_tnc_imv_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_tnc_imv_la_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -168,6 +167,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -199,14 +200,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -221,24 +225,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -246,7 +257,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
@@ -258,17 +272,17 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \
- -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon `xml2-config --cflags`
AM_CFLAGS = -rdynamic
-@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-pfkey.la
-@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-pfkey.la
-libstrongswan_kernel_pfkey_la_SOURCES = \
- kernel_pfkey_plugin.h kernel_pfkey_plugin.c \
- kernel_pfkey_ipsec.h kernel_pfkey_ipsec.c
+libstrongswan_tnc_imv_la_LIBADD = -ltnc
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imv.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imv.la
+libstrongswan_tnc_imv_la_SOURCES = \
+ tnc_imv_plugin.h tnc_imv_plugin.c
-libstrongswan_kernel_pfkey_la_LDFLAGS = -module -avoid-version
+libstrongswan_tnc_imv_la_LDFLAGS = -module -avoid-version
all: all-am
.SUFFIXES:
@@ -282,9 +296,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_pfkey/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_imv/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_pfkey/Makefile
+ $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_imv/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -343,8 +357,8 @@ clean-pluginLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libstrongswan-kernel-pfkey.la: $(libstrongswan_kernel_pfkey_la_OBJECTS) $(libstrongswan_kernel_pfkey_la_DEPENDENCIES)
- $(libstrongswan_kernel_pfkey_la_LINK) $(am_libstrongswan_kernel_pfkey_la_rpath) $(libstrongswan_kernel_pfkey_la_OBJECTS) $(libstrongswan_kernel_pfkey_la_LIBADD) $(LIBS)
+libstrongswan-tnc-imv.la: $(libstrongswan_tnc_imv_la_OBJECTS) $(libstrongswan_tnc_imv_la_DEPENDENCIES)
+ $(libstrongswan_tnc_imv_la_LINK) $(am_libstrongswan_tnc_imv_la_rpath) $(libstrongswan_tnc_imv_la_OBJECTS) $(libstrongswan_tnc_imv_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -352,8 +366,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfkey_ipsec.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfkey_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_imv_plugin.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
new file mode 100644
index 000000000..5b3d3892d
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "tnc_imv_plugin.h"
+
+#include <libtnctncs.h>
+
+#include <daemon.h>
+
+METHOD(plugin_t, destroy, void,
+ tnc_imv_plugin_t *this)
+{
+ libtnc_tncs_Terminate();
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *tnc_imv_plugin_create()
+{
+ char *tnc_config;
+ tnc_imv_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .destroy = _destroy,
+ },
+ );
+
+ tnc_config = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-imv.tnc_config", "/etc/tnc_config");
+ if (libtnc_tncs_Initialize(tnc_config) != TNC_RESULT_SUCCESS)
+ {
+ free(this);
+ DBG1(DBG_TNC, "TNC IMV initialization failed");
+ return NULL;
+ }
+
+ return &this->plugin;
+}
+
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.h b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.h
new file mode 100644
index 000000000..afeee2ea2
--- /dev/null
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tnc_imv tnc_imv
+ * @ingroup cplugins
+ *
+ * @defgroup tnc_imv_plugin tnc_imv_plugin
+ * @{ @ingroup tnc_imv
+ */
+
+#ifndef TNC_IMV_PLUGIN_H_
+#define TNC_IMV_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct tnc_imv_plugin_t tnc_imv_plugin_t;
+
+/**
+ * TNC IMV plugin
+ */
+struct tnc_imv_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** TNC_IMV_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/Makefile.am b/src/libcharon/plugins/tnccs_11/Makefile.am
new file mode 100644
index 000000000..7ccd0dfee
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/Makefile.am
@@ -0,0 +1,21 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \
+ `xml2-config --cflags`
+
+AM_CFLAGS = -rdynamic
+
+libstrongswan_tnccs_11_la_LIBADD = -ltnc
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-tnccs-11.la
+else
+plugin_LTLIBRARIES = libstrongswan-tnccs-11.la
+libstrongswan_tnccs_11_la_LIBADD += $(top_builddir)/src/libtls/libtls.la
+endif
+
+libstrongswan_tnccs_11_la_SOURCES = \
+ tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c
+
+libstrongswan_tnccs_11_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libcharon/plugins/kernel_netlink/Makefile.in b/src/libcharon/plugins/tnccs_11/Makefile.in
index 49cc895bc..200ff7a0a 100644
--- a/src/libcharon/plugins/kernel_netlink/Makefile.in
+++ b/src/libcharon/plugins/tnccs_11/Makefile.in
@@ -34,7 +34,8 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-subdir = src/libcharon/plugins/kernel_netlink
+@MONOLITHIC_FALSE@am__append_1 = $(top_builddir)/src/libtls/libtls.la
+subdir = src/libcharon/plugins/tnccs_11
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
@@ -44,6 +45,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -73,19 +75,17 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_kernel_netlink_la_LIBADD =
-am_libstrongswan_kernel_netlink_la_OBJECTS = kernel_netlink_plugin.lo \
- kernel_netlink_ipsec.lo kernel_netlink_net.lo \
- kernel_netlink_shared.lo
-libstrongswan_kernel_netlink_la_OBJECTS = \
- $(am_libstrongswan_kernel_netlink_la_OBJECTS)
-libstrongswan_kernel_netlink_la_LINK = $(LIBTOOL) --tag=CC \
+libstrongswan_tnccs_11_la_DEPENDENCIES = $(am__append_1)
+am_libstrongswan_tnccs_11_la_OBJECTS = tnccs_11_plugin.lo tnccs_11.lo
+libstrongswan_tnccs_11_la_OBJECTS = \
+ $(am_libstrongswan_tnccs_11_la_OBJECTS)
+libstrongswan_tnccs_11_la_LINK = $(LIBTOOL) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
- $(AM_CFLAGS) $(CFLAGS) \
- $(libstrongswan_kernel_netlink_la_LDFLAGS) $(LDFLAGS) -o $@
-@MONOLITHIC_FALSE@am_libstrongswan_kernel_netlink_la_rpath = -rpath \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_tnccs_11_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_tnccs_11_la_rpath = -rpath \
@MONOLITHIC_FALSE@ $(plugindir)
-@MONOLITHIC_TRUE@am_libstrongswan_kernel_netlink_la_rpath =
+@MONOLITHIC_TRUE@am_libstrongswan_tnccs_11_la_rpath =
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -99,8 +99,8 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES)
-DIST_SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES)
+SOURCES = $(libstrongswan_tnccs_11_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_tnccs_11_la_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -169,6 +169,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -200,14 +202,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -222,24 +227,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -247,7 +259,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
@@ -259,21 +274,18 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \
- -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon
-
-AM_CFLAGS = -rdynamic \
--DROUTING_TABLE=${routing_table} \
--DROUTING_TABLE_PRIO=${routing_table_prio}
-
-@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-netlink.la
-@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-netlink.la
-libstrongswan_kernel_netlink_la_SOURCES = \
- kernel_netlink_plugin.h kernel_netlink_plugin.c \
- kernel_netlink_ipsec.h kernel_netlink_ipsec.c kernel_netlink_net.h kernel_netlink_net.c \
- kernel_netlink_shared.h kernel_netlink_shared.c
-
-libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \
+ `xml2-config --cflags`
+
+AM_CFLAGS = -rdynamic
+libstrongswan_tnccs_11_la_LIBADD = -ltnc $(am__append_1)
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-11.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-11.la
+libstrongswan_tnccs_11_la_SOURCES = \
+ tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c
+
+libstrongswan_tnccs_11_la_LDFLAGS = -module -avoid-version
all: all-am
.SUFFIXES:
@@ -287,9 +299,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_netlink/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/tnccs_11/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/libcharon/plugins/kernel_netlink/Makefile
+ $(AUTOMAKE) --gnu src/libcharon/plugins/tnccs_11/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
@@ -348,8 +360,8 @@ clean-pluginLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libstrongswan-kernel-netlink.la: $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_DEPENDENCIES)
- $(libstrongswan_kernel_netlink_la_LINK) $(am_libstrongswan_kernel_netlink_la_rpath) $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_LIBADD) $(LIBS)
+libstrongswan-tnccs-11.la: $(libstrongswan_tnccs_11_la_OBJECTS) $(libstrongswan_tnccs_11_la_DEPENDENCIES)
+ $(libstrongswan_tnccs_11_la_LINK) $(am_libstrongswan_tnccs_11_la_rpath) $(libstrongswan_tnccs_11_la_OBJECTS) $(libstrongswan_tnccs_11_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -357,10 +369,8 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_ipsec.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_net.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_plugin.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_shared.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_11.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_11_plugin.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11.c b/src/libcharon/plugins/tnccs_11/tnccs_11.c
new file mode 100644
index 000000000..704bf64ed
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/tnccs_11.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "tnccs_11.h"
+
+#include <libtnctncc.h>
+#include <libtnctncs.h>
+
+#include <daemon.h>
+#include <debug.h>
+
+#define TNC_SEND_BUFFER_SIZE 32
+
+static chunk_t tnc_send_buffer[TNC_SEND_BUFFER_SIZE];
+
+/**
+ * Buffers TNCCS batch to be sent (TODO make the buffer scalable)
+ */
+static TNC_Result buffer_batch(u_int32_t id, const char *data, size_t len)
+{
+ if (id >= TNC_SEND_BUFFER_SIZE)
+ {
+ DBG1(DBG_TNC, "TNCCS Batch for Connection ID %u cannot be stored in "
+ "send buffer with size %d", id, TNC_SEND_BUFFER_SIZE);
+ return TNC_RESULT_FATAL;
+ }
+ if (tnc_send_buffer[id].ptr)
+ {
+ DBG1(DBG_TNC, "send buffer slot for Connection ID %u is already "
+ "occupied", id);
+ return TNC_RESULT_FATAL;
+ }
+ tnc_send_buffer[id] = chunk_alloc(len);
+ memcpy(tnc_send_buffer[id].ptr, data, len);
+
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * Retrieves TNCCS batch to be sent
+ */
+static bool retrieve_batch(u_int32_t id, chunk_t *batch)
+{
+ if (id >= TNC_SEND_BUFFER_SIZE)
+ {
+ DBG1(DBG_TNC, "TNCCS Batch for Connection ID %u cannot be retrieved from "
+ "send buffer with size %d", id, TNC_SEND_BUFFER_SIZE);
+ return FALSE;
+ }
+
+ *batch = tnc_send_buffer[id];
+ return TRUE;
+}
+
+/**
+ * Frees TNCCS batch that was sent
+ */
+static void free_batch(u_int32_t id)
+{
+ if (id < TNC_SEND_BUFFER_SIZE)
+ {
+ chunk_free(&tnc_send_buffer[id]);
+ }
+}
+
+/**
+ * Define callback functions called by the libtnc library
+ */
+TNC_Result TNC_TNCC_SendBatch(libtnc_tncc_connection* conn,
+ const char* messageBuffer, size_t messageLength)
+{
+ return buffer_batch(conn->connectionID, messageBuffer, messageLength);
+}
+
+TNC_Result TNC_TNCS_SendBatch(libtnc_tncs_connection* conn,
+ const char* messageBuffer, size_t messageLength)
+{
+ return buffer_batch(conn->connectionID, messageBuffer, messageLength);
+}
+
+typedef struct private_tnccs_11_t private_tnccs_11_t;
+
+/**
+ * Private data of a tnccs_11_t object.
+ */
+struct private_tnccs_11_t {
+
+ /**
+ * Public tls_t interface.
+ */
+ tls_t public;
+
+ /**
+ * TNCC if TRUE, TNCS if FALSE
+ */
+ bool is_server;
+
+ /**
+ * TNCC Connection to IMCs
+ */
+ libtnc_tncc_connection* tncc_connection;
+
+ /**
+ * TNCS Connection to IMVs
+ */
+ libtnc_tncs_connection* tncs_connection;
+};
+
+METHOD(tls_t, process, status_t,
+ private_tnccs_11_t *this, void *buf, size_t buflen)
+{
+ u_int32_t conn_id;
+
+ if (this->is_server && !this->tncs_connection)
+ {
+ this->tncs_connection = libtnc_tncs_CreateConnection(NULL);
+ if (!this->tncs_connection)
+ {
+ DBG1(DBG_TNC, "TNCS CreateConnection failed");
+ return FAILED;
+ }
+ DBG1(DBG_TNC, "assigned TNCS Connection ID %u",
+ this->tncs_connection->connectionID);
+ if (libtnc_tncs_BeginSession(this->tncs_connection) != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "TNCS BeginSession failed");
+ return FAILED;
+ }
+ }
+ conn_id = this->is_server ? this->tncs_connection->connectionID
+ : this->tncc_connection->connectionID;
+
+ DBG1(DBG_TNC, "received TNCCS Batch (%u bytes) for Connection ID %u",
+ buflen, conn_id);
+ DBG3(DBG_TNC, "%.*s", buflen, buf);
+
+ if (this->is_server)
+ {
+ if (libtnc_tncs_ReceiveBatch(this->tncs_connection, buf, buflen) !=
+ TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "TNCS ReceiveBatch failed");
+ return FAILED;
+ }
+ }
+ else
+ {
+ if (libtnc_tncc_ReceiveBatch(this->tncc_connection, buf, buflen) !=
+ TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "TNCC ReceiveBatch failed");
+ return FAILED;
+ }
+ }
+ return NEED_MORE;
+}
+
+METHOD(tls_t, build, status_t,
+ private_tnccs_11_t *this, void *buf, size_t *buflen, size_t *msglen)
+{
+ chunk_t batch;
+ u_int32_t conn_id;
+ size_t len;
+
+ if (!this->is_server && !this->tncc_connection)
+ {
+ this->tncc_connection = libtnc_tncc_CreateConnection(NULL);
+ if (!this->tncc_connection)
+ {
+ DBG1(DBG_TNC, "TNCC CreateConnection failed");
+ return FAILED;
+ }
+ DBG1(DBG_TNC, "assigned TNCC Connection ID %u",
+ this->tncc_connection->connectionID);
+ if (libtnc_tncc_BeginSession(this->tncc_connection) != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "TNCC BeginSession failed");
+ return FAILED;
+ }
+ }
+ conn_id = this->is_server ? this->tncs_connection->connectionID
+ : this->tncc_connection->connectionID;
+
+ if (!retrieve_batch(conn_id, &batch))
+ {
+ return FAILED;
+ }
+ len = *buflen;
+ len = min(len, batch.len);
+ *buflen = len;
+ if (msglen)
+ {
+ *msglen = batch.len;
+ }
+
+ if (batch.len)
+ {
+ DBG1(DBG_TNC, "sending TNCCS Batch (%d bytes) for Connection ID %u",
+ batch.len, conn_id);
+ DBG3(DBG_TNC, "%.*s", batch.len, batch.ptr);
+ memcpy(buf, batch.ptr, len);
+ free_batch(conn_id);
+ return ALREADY_DONE;
+ }
+ else
+ {
+ return INVALID_STATE;
+ }
+}
+
+METHOD(tls_t, is_server, bool,
+ private_tnccs_11_t *this)
+{
+ return this->is_server;
+}
+
+METHOD(tls_t, get_purpose, tls_purpose_t,
+ private_tnccs_11_t *this)
+{
+ return TLS_PURPOSE_EAP_TNC;
+}
+
+METHOD(tls_t, is_complete, bool,
+ private_tnccs_11_t *this)
+{
+ TNC_IMV_Action_Recommendation rec;
+ TNC_IMV_Evaluation_Result eval;
+ char *group;
+ identification_t *id;
+ ike_sa_t *ike_sa;
+ auth_cfg_t *auth;
+
+ if (libtnc_tncs_HaveRecommendation(this->tncs_connection, &rec, &eval) ==
+ TNC_RESULT_SUCCESS)
+ {
+ switch (rec)
+ {
+ case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
+ DBG1(DBG_TNC, "TNC recommendation is allow");
+ group = "allow";
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+ DBG1(DBG_TNC, "TNC recommendation is isolate");
+ group = "isolate";
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
+ default:
+ DBG1(DBG_TNC, "TNC recommendation is none");
+ return FALSE;
+ }
+ ike_sa = charon->bus->get_sa(charon->bus);
+ if (ike_sa)
+ {
+ auth = ike_sa->get_auth_cfg(ike_sa, FALSE);
+ id = identification_create_from_string(group);
+ auth->add(auth, AUTH_RULE_GROUP, id);
+ DBG1(DBG_TNC, "added group membership '%s' based on TNC recommendation", group);
+ }
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+METHOD(tls_t, get_eap_msk, chunk_t,
+ private_tnccs_11_t *this)
+{
+ return chunk_empty;
+}
+
+METHOD(tls_t, destroy, void,
+ private_tnccs_11_t *this)
+{
+ if (this->is_server)
+ {
+ if (this->tncs_connection)
+ {
+ libtnc_tncs_DeleteConnection(this->tncs_connection);
+ }
+ }
+ else
+ {
+ if (this->tncc_connection)
+ {
+ libtnc_tncc_DeleteConnection(this->tncc_connection);
+ }
+ libtnc_tncc_Terminate();
+ }
+ free(this);
+}
+
+/**
+ * See header
+ */
+tls_t *tnccs_11_create(bool is_server)
+{
+ private_tnccs_11_t *this;
+
+ INIT(this,
+ .public = {
+ .process = _process,
+ .build = _build,
+ .is_server = _is_server,
+ .get_purpose = _get_purpose,
+ .is_complete = _is_complete,
+ .get_eap_msk = _get_eap_msk,
+ .destroy = _destroy,
+ },
+ .is_server = is_server,
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11.h b/src/libcharon/plugins/tnccs_11/tnccs_11.h
new file mode 100644
index 000000000..7331fc8cd
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/tnccs_11.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tnccs_11_h tnccs_11
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_11_H_
+#define TNCCS_11_H_
+
+#include <library.h>
+
+#include <tls.h>
+
+/**
+ * Create an instance of the TNC IF-TNCCS 1.1 protocol handler.
+ *
+ * @param is_server TRUE to act as TNC Server, FALSE for TNC Client
+ * @return TNC_IF_TNCCS 1.1 protocol stack
+ */
+tls_t *tnccs_11_create(bool is_server);
+
+#endif /** TNCCS_11_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c
new file mode 100644
index 000000000..03905ca37
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "tnccs_11_plugin.h"
+#include "tnccs_11.h"
+
+#include <daemon.h>
+
+METHOD(plugin_t, destroy, void,
+ tnccs_11_plugin_t *this)
+{
+ charon->tnccs->remove_method(charon->tnccs,
+ (tnccs_constructor_t)tnccs_11_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *tnccs_11_plugin_create()
+{
+ tnccs_11_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .destroy = _destroy,
+ },
+ );
+
+ charon->tnccs->add_method(charon->tnccs, TNCCS_1_1,
+ (tnccs_constructor_t)tnccs_11_create);
+
+ return &this->plugin;
+}
+
diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.h b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.h
new file mode 100644
index 000000000..619a073ad
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tnccs_11 tnccs_11
+ * @ingroup cplugins
+ *
+ * @defgroup tnccs_11_plugin tnccs_11_plugin
+ * @{ @ingroup tnccs_11
+ */
+
+#ifndef TNCCS_11_PLUGIN_H_
+#define TNCCS_11_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct tnccs_11_plugin_t tnccs_11_plugin_t;
+
+/**
+ * EAP-TNC plugin
+ */
+struct tnccs_11_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** TNCCS_11_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/Makefile.am b/src/libcharon/plugins/tnccs_20/Makefile.am
new file mode 100644
index 000000000..3018121e3
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/Makefile.am
@@ -0,0 +1,21 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \
+ `xml2-config --cflags`
+
+AM_CFLAGS = -rdynamic
+
+libstrongswan_tnccs_20_la_LIBADD = -ltnc
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-tnccs-20.la
+else
+plugin_LTLIBRARIES = libstrongswan-tnccs-20.la
+libstrongswan_tnccs_20_la_LIBADD += $(top_builddir)/src/libtls/libtls.la
+endif
+
+libstrongswan_tnccs_20_la_SOURCES = \
+ tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c
+
+libstrongswan_tnccs_20_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libcharon/plugins/tnccs_20/Makefile.in b/src/libcharon/plugins/tnccs_20/Makefile.in
new file mode 100644
index 000000000..6101f91df
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/Makefile.in
@@ -0,0 +1,607 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@MONOLITHIC_FALSE@am__append_1 = $(top_builddir)/src/libtls/libtls.la
+subdir = src/libcharon/plugins/tnccs_20
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
+ $(top_srcdir)/m4/config/ltoptions.m4 \
+ $(top_srcdir)/m4/config/ltsugar.m4 \
+ $(top_srcdir)/m4/config/ltversion.m4 \
+ $(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/with.m4 \
+ $(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(plugindir)"
+LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
+libstrongswan_tnccs_20_la_DEPENDENCIES = $(am__append_1)
+am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo
+libstrongswan_tnccs_20_la_OBJECTS = \
+ $(am_libstrongswan_tnccs_20_la_OBJECTS)
+libstrongswan_tnccs_20_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_tnccs_20_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_tnccs_20_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_tnccs_20_la_rpath =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libstrongswan_tnccs_20_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_tnccs_20_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BTLIB = @BTLIB@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLIB = @DLLIB@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MYSQLCFLAG = @MYSQLCFLAG@
+MYSQLCONFIG = @MYSQLCONFIG@
+MYSQLLIB = @MYSQLLIB@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREADLIB = @PTHREADLIB@
+RANLIB = @RANLIB@
+RTLIB = @RTLIB@
+RUBY = @RUBY@
+RUBYINCLUDE = @RUBYINCLUDE@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SOCKLIB = @SOCKLIB@
+STRIP = @STRIP@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+c_plugins = @c_plugins@
+datadir = @datadir@
+datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
+default_pkcs11 = @default_pkcs11@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gtk_CFLAGS = @gtk_CFLAGS@
+gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgid = @ipsecgid@
+ipsecgroup = @ipsecgroup@
+ipsecuid = @ipsecuid@
+ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
+libdir = @libdir@
+libexecdir = @libexecdir@
+linux_headers = @linux_headers@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
+mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
+mkdir_p = @mkdir_p@
+nm_CFLAGS = @nm_CFLAGS@
+nm_LIBS = @nm_LIBS@
+nm_ca_dir = @nm_ca_dir@
+oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
+pdfdir = @pdfdir@
+piddir = @piddir@
+pki_plugins = @pki_plugins@
+plugindir = @plugindir@
+pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+random_device = @random_device@
+resolv_conf = @resolv_conf@
+routing_table = @routing_table@
+routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
+sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+urandom_device = @urandom_device@
+xml_CFLAGS = @xml_CFLAGS@
+xml_LIBS = @xml_LIBS@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \
+ `xml2-config --cflags`
+
+AM_CFLAGS = -rdynamic
+libstrongswan_tnccs_20_la_LIBADD = -ltnc $(am__append_1)
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-20.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-20.la
+libstrongswan_tnccs_20_la_SOURCES = \
+ tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c
+
+libstrongswan_tnccs_20_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/tnccs_20/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/tnccs_20/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)"
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \
+ }
+
+uninstall-pluginLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \
+ done
+
+clean-pluginLTLIBRARIES:
+ -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
+ @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libstrongswan-tnccs-20.la: $(libstrongswan_tnccs_20_la_OBJECTS) $(libstrongswan_tnccs_20_la_DEPENDENCIES)
+ $(libstrongswan_tnccs_20_la_LINK) $(am_libstrongswan_tnccs_20_la_rpath) $(libstrongswan_tnccs_20_la_OBJECTS) $(libstrongswan_tnccs_20_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20_plugin.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(plugindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-pluginLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pluginLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-pluginLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
+ ctags distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pluginLTLIBRARIES install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-pluginLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20.c b/src/libcharon/plugins/tnccs_20/tnccs_20.c
new file mode 100644
index 000000000..2bd1bc476
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/tnccs_20.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "tnccs_20.h"
+
+#include <debug.h>
+
+static chunk_t tncc_output;
+
+typedef struct private_tnccs_20_t private_tnccs_20_t;
+
+/**
+ * Private data of a tnccs_20_t object.
+ */
+struct private_tnccs_20_t {
+
+ /**
+ * Public tls_t interface.
+ */
+ tls_t public;
+
+ /**
+ * TNCC if TRUE, TNCS if FALSE
+ */
+ bool is_server;
+};
+
+METHOD(tls_t, process, status_t,
+ private_tnccs_20_t *this, void *buf, size_t buflen)
+{
+ return NEED_MORE;
+}
+
+METHOD(tls_t, build, status_t,
+ private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen)
+{
+ return ALREADY_DONE;
+}
+
+METHOD(tls_t, is_server, bool,
+ private_tnccs_20_t *this)
+{
+ return this->is_server;
+}
+
+METHOD(tls_t, get_purpose, tls_purpose_t,
+ private_tnccs_20_t *this)
+{
+ return TLS_PURPOSE_EAP_TNC;
+}
+
+METHOD(tls_t, is_complete, bool,
+ private_tnccs_20_t *this)
+{
+ return FALSE;
+}
+
+METHOD(tls_t, get_eap_msk, chunk_t,
+ private_tnccs_20_t *this)
+{
+ return chunk_empty;
+}
+
+METHOD(tls_t, destroy, void,
+ private_tnccs_20_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+tls_t *tnccs_20_create(bool is_server)
+{
+ private_tnccs_20_t *this;
+
+ INIT(this,
+ .public = {
+ .process = _process,
+ .build = _build,
+ .is_server = _is_server,
+ .get_purpose = _get_purpose,
+ .is_complete = _is_complete,
+ .get_eap_msk = _get_eap_msk,
+ .destroy = _destroy,
+ },
+ .is_server = is_server,
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20.h b/src/libcharon/plugins/tnccs_20/tnccs_20.h
new file mode 100644
index 000000000..400d1dc12
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/tnccs_20.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tnccs_20_h tnccs_20
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef TNCCS_20_H_
+#define TNCCS_20_H_
+
+#include <library.h>
+
+#include <tls.h>
+
+/**
+ * Create an instance of the TNC IF-TNCCS 2.0 protocol handler.
+ *
+ * @param is_server TRUE to act as TNC Server, FALSE for TNC Client
+ * @return TNC_IF_TNCCS 2.0 protocol stack
+ */
+tls_t *tnccs_20_create(bool is_server);
+
+#endif /** TNCCS_20_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c
new file mode 100644
index 000000000..82c78f74c
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "tnccs_20_plugin.h"
+#include "tnccs_20.h"
+
+#include <daemon.h>
+
+METHOD(plugin_t, destroy, void,
+ tnccs_20_plugin_t *this)
+{
+ charon->tnccs->remove_method(charon->tnccs,
+ (tnccs_constructor_t)tnccs_20_create);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *tnccs_20_plugin_create()
+{
+ tnccs_20_plugin_t *this;
+
+ INIT(this,
+ .plugin = {
+ .destroy = _destroy,
+ },
+ );
+
+ charon->tnccs->add_method(charon->tnccs, TNCCS_2_0,
+ (tnccs_constructor_t)tnccs_20_create);
+
+ return &this->plugin;
+}
+
diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.h b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.h
new file mode 100644
index 000000000..1c4ecf4c9
--- /dev/null
+++ b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tnccs_20 tnccs_20
+ * @ingroup cplugins
+ *
+ * @defgroup tnccs_20_plugin tnccs_20_plugin
+ * @{ @ingroup tnccs_20
+ */
+
+#ifndef TNCCS_20_PLUGIN_H_
+#define TNCCS_20_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct tnccs_20_plugin_t tnccs_20_plugin_t;
+
+/**
+ * EAP-TNC plugin
+ */
+struct tnccs_20_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** TNCCS_20_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in
index 934ab6080..9cb5f794a 100644
--- a/src/libcharon/plugins/uci/Makefile.in
+++ b/src/libcharon/plugins/uci/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -165,6 +166,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -196,14 +199,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -218,24 +224,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -243,7 +256,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/uci/uci_control.c b/src/libcharon/plugins/uci/uci_control.c
index 3c4928be4..aee2505e3 100644
--- a/src/libcharon/plugins/uci/uci_control.c
+++ b/src/libcharon/plugins/uci/uci_control.c
@@ -294,7 +294,7 @@ uci_control_t *uci_control_create()
{
this->job = callback_job_create((callback_job_cb_t)receive,
this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
}
return &this->public;
}
diff --git a/src/libcharon/plugins/unit_tester/Makefile.in b/src/libcharon/plugins/unit_tester/Makefile.in
index 47850c1c5..47fff7e1d 100644
--- a/src/libcharon/plugins/unit_tester/Makefile.in
+++ b/src/libcharon/plugins/unit_tester/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -171,6 +172,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -202,14 +205,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -224,24 +230,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -249,7 +262,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/unit_tester/tests/test_cert.c b/src/libcharon/plugins/unit_tester/tests/test_cert.c
index 3b00421f8..342194a4c 100644
--- a/src/libcharon/plugins/unit_tester/tests/test_cert.c
+++ b/src/libcharon/plugins/unit_tester/tests/test_cert.c
@@ -51,7 +51,7 @@ bool test_cert_x509()
return FALSE;
}
- encoding = ca_cert->get_encoding(ca_cert);
+ ca_cert->get_encoding(ca_cert, CERT_ASN1_DER, &encoding);
parsed = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_BLOB_ASN1_DER, encoding,
BUILD_END);
@@ -81,7 +81,7 @@ bool test_cert_x509()
return FALSE;
}
- encoding = peer_cert->get_encoding(peer_cert);
+ peer_cert->get_encoding(peer_cert, CERT_ASN1_DER, &encoding);
parsed = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
BUILD_BLOB_ASN1_DER, encoding,
BUILD_END);
diff --git a/src/libcharon/plugins/unit_tester/tests/test_rsa_gen.c b/src/libcharon/plugins/unit_tester/tests/test_rsa_gen.c
index 59da15644..6ba5769b5 100644
--- a/src/libcharon/plugins/unit_tester/tests/test_rsa_gen.c
+++ b/src/libcharon/plugins/unit_tester/tests/test_rsa_gen.c
@@ -59,12 +59,12 @@ bool test_rsa_gen()
return FALSE;
}
free(sig.ptr);
- if (!public->encrypt(public, data, &crypt))
+ if (!public->encrypt(public, ENCRYPT_RSA_PKCS1, data, &crypt))
{
DBG1(DBG_CFG, "encrypting data with RSA failed");
return FALSE;
}
- if (!private->decrypt(private, crypt, &plain))
+ if (!private->decrypt(private, ENCRYPT_RSA_PKCS1, crypt, &plain))
{
DBG1(DBG_CFG, "decrypting data with RSA failed");
return FALSE;
@@ -110,7 +110,7 @@ bool test_rsa_load_any()
public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
BUILD_BLOB_ASN1_DER, chunk,
BUILD_END);
- if (!public || public->get_keysize(public) != 256)
+ if (!public || public->get_keysize(public) != 2048)
{
return FALSE;
}
diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in
index ce233ad04..e93955d71 100644
--- a/src/libcharon/plugins/updown/Makefile.in
+++ b/src/libcharon/plugins/updown/Makefile.in
@@ -44,6 +44,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
+ $(top_srcdir)/m4/macros/add-plugin.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -167,6 +168,8 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PTHREADLIB = @PTHREADLIB@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
@@ -198,14 +201,17 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
+c_plugins = @c_plugins@
datadir = @datadir@
datarootdir = @datarootdir@
+dbusservicedir = @dbusservicedir@
default_pkcs11 = @default_pkcs11@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
gtk_CFLAGS = @gtk_CFLAGS@
gtk_LIBS = @gtk_LIBS@
+h_plugins = @h_plugins@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -220,24 +226,31 @@ ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
+libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
-libhydra_plugins = @libhydra_plugins@
-libstrongswan_plugins = @libstrongswan_plugins@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
+maemo_CFLAGS = @maemo_CFLAGS@
+maemo_LIBS = @maemo_LIBS@
+manager_plugins = @manager_plugins@
mandir = @mandir@
+medsrv_plugins = @medsrv_plugins@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
oldincludedir = @oldincludedir@
+openac_plugins = @openac_plugins@
+p_plugins = @p_plugins@
pdfdir = @pdfdir@
piddir = @piddir@
+pki_plugins = @pki_plugins@
plugindir = @plugindir@
pluto_plugins = @pluto_plugins@
+pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
@@ -245,7 +258,10 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
+s_plugins = @s_plugins@
sbindir = @sbindir@
+scepclient_plugins = @scepclient_plugins@
+scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c
index ea4a792c2..8e58b1a9b 100644
--- a/src/libcharon/plugins/updown/updown_listener.c
+++ b/src/libcharon/plugins/updown/updown_listener.c
@@ -18,6 +18,7 @@
#include "updown_listener.h"
+#include <hydra.h>
#include <daemon.h>
#include <config/child_cfg.h>
@@ -218,8 +219,8 @@ METHOD(listener_t, child_updown, bool,
if (up)
{
- iface = charon->kernel_interface->get_interface(
- charon->kernel_interface, me);
+ iface = hydra->kernel_interface->get_interface(
+ hydra->kernel_interface, me);
if (iface)
{
cache_iface(this, child_sa->get_reqid(child_sa), iface);
diff --git a/src/libcharon/processing/jobs/acquire_job.h b/src/libcharon/processing/jobs/acquire_job.h
index eff79a9b0..2b5bf4805 100644
--- a/src/libcharon/processing/jobs/acquire_job.h
+++ b/src/libcharon/processing/jobs/acquire_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup acquire_job acquire_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef ACQUIRE_JOB_H_
diff --git a/src/libcharon/processing/jobs/callback_job.c b/src/libcharon/processing/jobs/callback_job.c
deleted file mode 100644
index 45e49112e..000000000
--- a/src/libcharon/processing/jobs/callback_job.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2009 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "callback_job.h"
-
-#include <semaphore.h>
-
-#include <daemon.h>
-#include <threading/thread.h>
-#include <threading/condvar.h>
-#include <threading/mutex.h>
-
-typedef struct private_callback_job_t private_callback_job_t;
-
-/**
- * Private data of an callback_job_t Object.
- */
-struct private_callback_job_t {
- /**
- * Public callback_job_t interface.
- */
- callback_job_t public;
-
- /**
- * Callback to call on execution
- */
- callback_job_cb_t callback;
-
- /**
- * parameter to supply to callback
- */
- void *data;
-
- /**
- * cleanup function for data
- */
- callback_job_cleanup_t cleanup;
-
- /**
- * thread of the job, if running
- */
- thread_t *thread;
-
- /**
- * mutex to access jobs interna
- */
- mutex_t *mutex;
-
- /**
- * list of asociated child jobs
- */
- linked_list_t *children;
-
- /**
- * parent of this job, or NULL
- */
- private_callback_job_t *parent;
-
- /**
- * TRUE if the job got cancelled
- */
- bool cancelled;
-
- /**
- * condvar to synchronize the cancellation/destruction of the job
- */
- condvar_t *destroyable;
-
- /**
- * semaphore to synchronize the termination of the assigned thread.
- *
- * separately allocated during cancellation, so that we can wait on it
- * without risking that it gets freed too early during destruction.
- */
- sem_t *terminated;
-};
-
-/**
- * unregister a child from its parent, if any.
- * note: this->mutex has to be locked
- */
-static void unregister(private_callback_job_t *this)
-{
- if (this->parent)
- {
- this->parent->mutex->lock(this->parent->mutex);
- if (this->parent->cancelled && !this->cancelled)
- {
- /* if the parent has been cancelled but we have not yet, we do not
- * unregister until we got cancelled by the parent. */
- this->parent->mutex->unlock(this->parent->mutex);
- this->destroyable->wait(this->destroyable, this->mutex);
- this->parent->mutex->lock(this->parent->mutex);
- }
- this->parent->children->remove(this->parent->children, this, NULL);
- this->parent->mutex->unlock(this->parent->mutex);
- this->parent = NULL;
- }
-}
-
-/**
- * Implements job_t.destroy.
- */
-static void destroy(private_callback_job_t *this)
-{
- this->mutex->lock(this->mutex);
- unregister(this);
- if (this->cleanup)
- {
- this->cleanup(this->data);
- }
- if (this->terminated)
- {
- sem_post(this->terminated);
- }
- this->children->destroy(this->children);
- this->destroyable->destroy(this->destroyable);
- this->mutex->unlock(this->mutex);
- this->mutex->destroy(this->mutex);
- free(this);
-}
-
-/**
- * Implementation of callback_job_t.cancel.
- */
-static void cancel(private_callback_job_t *this)
-{
- callback_job_t *child;
- sem_t *terminated = NULL;
-
- this->mutex->lock(this->mutex);
- this->cancelled = TRUE;
- /* terminate children */
- while (this->children->get_first(this->children, (void**)&child) == SUCCESS)
- {
- this->mutex->unlock(this->mutex);
- child->cancel(child);
- this->mutex->lock(this->mutex);
- }
- if (this->thread)
- {
- /* terminate the thread, if there is currently one executing the job.
- * we wait for its termination using a semaphore */
- this->thread->cancel(this->thread);
- terminated = this->terminated = malloc_thing(sem_t);
- sem_init(terminated, 0, 0);
- }
- else
- {
- /* if the job is currently queued, it gets terminated later.
- * we can't wait, because it might not get executed at all.
- * we also unregister the queued job manually from its parent (the
- * others get unregistered during destruction) */
- unregister(this);
- }
- this->destroyable->signal(this->destroyable);
- this->mutex->unlock(this->mutex);
-
- if (terminated)
- {
- sem_wait(terminated);
- sem_destroy(terminated);
- free(terminated);
- }
-}
-
-/**
- * Implementation of job_t.execute.
- */
-static void execute(private_callback_job_t *this)
-{
- bool cleanup = FALSE, requeue = FALSE;
-
- thread_cleanup_push((thread_cleanup_t)destroy, this);
-
- this->mutex->lock(this->mutex);
- this->thread = thread_current();
- this->mutex->unlock(this->mutex);
-
- while (TRUE)
- {
- this->mutex->lock(this->mutex);
- if (this->cancelled)
- {
- this->mutex->unlock(this->mutex);
- cleanup = TRUE;
- break;
- }
- this->mutex->unlock(this->mutex);
- switch (this->callback(this->data))
- {
- case JOB_REQUEUE_DIRECT:
- continue;
- case JOB_REQUEUE_FAIR:
- {
- requeue = TRUE;
- break;
- }
- case JOB_REQUEUE_NONE:
- default:
- {
- cleanup = TRUE;
- break;
- }
- }
- break;
- }
- this->mutex->lock(this->mutex);
- this->thread = NULL;
- this->mutex->unlock(this->mutex);
- /* manually create a cancellation point to avoid that a cancelled thread
- * goes back into the thread pool */
- thread_cancellation_point();
- if (requeue)
- {
- charon->processor->queue_job(charon->processor,
- &this->public.job_interface);
- }
- thread_cleanup_pop(cleanup);
-}
-
-/*
- * Described in header.
- */
-callback_job_t *callback_job_create(callback_job_cb_t cb, void *data,
- callback_job_cleanup_t cleanup,
- callback_job_t *parent)
-{
- private_callback_job_t *this = malloc_thing(private_callback_job_t);
-
- /* interface functions */
- this->public.job_interface.execute = (void (*) (job_t *)) execute;
- this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
- this->public.cancel = (void(*)(callback_job_t*))cancel;
-
- /* private variables */
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
- this->callback = cb;
- this->data = data;
- this->cleanup = cleanup;
- this->thread = 0;
- this->children = linked_list_create();
- this->parent = (private_callback_job_t*)parent;
- this->cancelled = FALSE;
- this->destroyable = condvar_create(CONDVAR_TYPE_DEFAULT);
- this->terminated = NULL;
-
- /* register us at parent */
- if (parent)
- {
- this->parent->mutex->lock(this->parent->mutex);
- this->parent->children->insert_last(this->parent->children, this);
- this->parent->mutex->unlock(this->parent->mutex);
- }
-
- return &this->public;
-}
-
diff --git a/src/libcharon/processing/jobs/callback_job.h b/src/libcharon/processing/jobs/callback_job.h
deleted file mode 100644
index 62da1edd1..000000000
--- a/src/libcharon/processing/jobs/callback_job.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup callback_job callback_job
- * @{ @ingroup jobs
- */
-
-#ifndef CALLBACK_JOB_H_
-#define CALLBACK_JOB_H_
-
-typedef struct callback_job_t callback_job_t;
-
-#include <library.h>
-#include <processing/jobs/job.h>
-
-
-typedef enum job_requeue_t job_requeue_t;
-
-/**
- * Job requeueing policy
- *
- * The job requeueing policy defines how a job is handled when the callback
- * function returns.
- */
-enum job_requeue_t {
-
- /**
- * Do not requeue job, destroy it
- */
- JOB_REQUEUE_NONE,
-
- /**
- * Reque the job fairly, meaning it has to requeue as any other job
- */
- JOB_REQUEUE_FAIR,
-
- /**
- * Reexecute the job directly, without the need of requeueing it
- */
- JOB_REQUEUE_DIRECT,
-};
-
-/**
- * The callback function to use for the callback job.
- *
- * This is the function to use as callback for a callback job. It receives
- * a parameter supplied to the callback jobs constructor.
- *
- * @param data param supplied to job
- * @return requeing policy how to requeue the job
- */
-typedef job_requeue_t (*callback_job_cb_t)(void *data);
-
-/**
- * Cleanup function to use for data cleanup.
- *
- * The callback has an optional user argument which receives data. However,
- * this data may be cleaned up if it is allocated. This is the function
- * to supply to the constructor.
- *
- * @param data param supplied to job
- * @return requeing policy how to requeue the job
- */
-typedef void (*callback_job_cleanup_t)(void *data);
-
-/**
- * Class representing an callback Job.
- *
- * This is a special job which allows a simple callback function to
- * be executed by a thread of the thread pool. This allows simple execution
- * of asynchronous methods, without to manage threads.
- */
-struct callback_job_t {
- /**
- * The job_t interface.
- */
- job_t job_interface;
-
- /**
- * Cancel the job's thread and wait for its termination. This only works
- * reliably for jobs that always use JOB_REQUEUE_FAIR or JOB_REQUEUE_DIRECT,
- * otherwise the job may already be destroyed when cancel is called. */
- void (*cancel)(callback_job_t *this);
-};
-
-/**
- * Creates a callback job.
- *
- * The cleanup function is called when the job gets destroyed to destroy
- * the associated data.
- * If parent is not NULL, the specified job gets an association. Whenever
- * the parent gets cancelled (or runs out), all of its children are cancelled,
- * too.
- *
- * @param cb callback to call from the processor
- * @param data user data to supply to callback
- * @param cleanup destructor for data on destruction, or NULL
- * @param parent parent of this job
- * @return callback_job_t object
- */
-callback_job_t *callback_job_create(callback_job_cb_t cb, void *data,
- callback_job_cleanup_t cleanup,
- callback_job_t *parent);
-
-#endif /** CALLBACK_JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.h b/src/libcharon/processing/jobs/delete_child_sa_job.h
index 662a7b7c7..fc0e2b518 100644
--- a/src/libcharon/processing/jobs/delete_child_sa_job.h
+++ b/src/libcharon/processing/jobs/delete_child_sa_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup delete_child_sa_job delete_child_sa_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef DELETE_CHILD_SA_JOB_H_
diff --git a/src/libcharon/processing/jobs/delete_ike_sa_job.h b/src/libcharon/processing/jobs/delete_ike_sa_job.h
index f641deea3..ae06b9cfc 100644
--- a/src/libcharon/processing/jobs/delete_ike_sa_job.h
+++ b/src/libcharon/processing/jobs/delete_ike_sa_job.h
@@ -16,7 +16,7 @@
/**
* @defgroup delete_child_sa_job delete_child_sa_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef DELETE_IKE_SA_JOB_H_
diff --git a/src/libcharon/processing/jobs/inactivity_job.c b/src/libcharon/processing/jobs/inactivity_job.c
index 13fc5e3d0..1371000eb 100644
--- a/src/libcharon/processing/jobs/inactivity_job.c
+++ b/src/libcharon/processing/jobs/inactivity_job.c
@@ -87,7 +87,7 @@ METHOD(job_t, execute, void,
}
else
{
- charon->scheduler->schedule_job(charon->scheduler,
+ lib->scheduler->schedule_job(lib->scheduler,
&this->public.job_interface, this->timeout - diff);
rescheduled = TRUE;
}
@@ -136,9 +136,11 @@ inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout,
private_inactivity_job_t *this;
INIT(this,
- .public.job_interface = {
- .execute = _execute,
- .destroy = _destroy,
+ .public = {
+ .job_interface = {
+ .execute = _execute,
+ .destroy = _destroy,
+ },
},
.reqid = reqid,
.timeout = timeout,
diff --git a/src/libcharon/processing/jobs/inactivity_job.h b/src/libcharon/processing/jobs/inactivity_job.h
index 9c9daced8..890f7704b 100644
--- a/src/libcharon/processing/jobs/inactivity_job.h
+++ b/src/libcharon/processing/jobs/inactivity_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup inactivity_job inactivity_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef INACTIVITY_JOB_H_
diff --git a/src/libcharon/processing/jobs/initiate_mediation_job.h b/src/libcharon/processing/jobs/initiate_mediation_job.h
index fddb1dd7b..d105de2b9 100644
--- a/src/libcharon/processing/jobs/initiate_mediation_job.h
+++ b/src/libcharon/processing/jobs/initiate_mediation_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup initiate_mediation_job initiate_mediation_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef INITIATE_MEDIATION_JOB_H_
diff --git a/src/libcharon/processing/jobs/job.h b/src/libcharon/processing/jobs/job.h
deleted file mode 100644
index 0f1c16ebe..000000000
--- a/src/libcharon/processing/jobs/job.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup job job
- * @{ @ingroup jobs
- */
-
-#ifndef JOB_H_
-#define JOB_H_
-
-typedef struct job_t job_t;
-
-#include <library.h>
-
-/**
- * Job-Interface as it is stored in the job queue.
- */
-struct job_t {
-
- /**
- * Execute a job.
- *
- * The processing facility executes a job using this method. Jobs are
- * one-shot, they destroy themself after execution, so don't use a job
- * once it has been executed.
- */
- void (*execute) (job_t *this);
-
- /**
- * Destroy a job.
- *
- * Is only called whenever a job was not executed (e.g. due daemon shutdown).
- * After execution, jobs destroy themself.
- */
- void (*destroy) (job_t *job);
-};
-
-#endif /** JOB_H_ @}*/
diff --git a/src/libcharon/processing/jobs/mediation_job.h b/src/libcharon/processing/jobs/mediation_job.h
index 0574c65eb..41485cbc6 100644
--- a/src/libcharon/processing/jobs/mediation_job.h
+++ b/src/libcharon/processing/jobs/mediation_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup mediation_job mediation_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef MEDIATION_JOB_H_
diff --git a/src/libcharon/processing/jobs/migrate_job.h b/src/libcharon/processing/jobs/migrate_job.h
index de313d517..09679c734 100644
--- a/src/libcharon/processing/jobs/migrate_job.h
+++ b/src/libcharon/processing/jobs/migrate_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup migrate_job migrate_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef MIGRATE_JOB_H_
diff --git a/src/libcharon/processing/jobs/process_message_job.h b/src/libcharon/processing/jobs/process_message_job.h
index 5e3f44d1f..2c42aa577 100644
--- a/src/libcharon/processing/jobs/process_message_job.h
+++ b/src/libcharon/processing/jobs/process_message_job.h
@@ -16,7 +16,7 @@
/**
* @defgroup process_message_job process_message_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef PROCESS_MESSAGE_JOB_H_
diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.h b/src/libcharon/processing/jobs/rekey_child_sa_job.h
index 62887d6b9..fcbe65a06 100644
--- a/src/libcharon/processing/jobs/rekey_child_sa_job.h
+++ b/src/libcharon/processing/jobs/rekey_child_sa_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup rekey_child_sa_job rekey_child_sa_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef REKEY_CHILD_SA_JOB_H_
diff --git a/src/libcharon/processing/jobs/rekey_ike_sa_job.h b/src/libcharon/processing/jobs/rekey_ike_sa_job.h
index a5c1028aa..3e3e13d00 100644
--- a/src/libcharon/processing/jobs/rekey_ike_sa_job.h
+++ b/src/libcharon/processing/jobs/rekey_ike_sa_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup rekey_ike_sa_job rekey_ike_sa_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef REKEY_IKE_SA_JOB_H_
diff --git a/src/libcharon/processing/jobs/retransmit_job.h b/src/libcharon/processing/jobs/retransmit_job.h
index c8c13479b..c4545534b 100644
--- a/src/libcharon/processing/jobs/retransmit_job.h
+++ b/src/libcharon/processing/jobs/retransmit_job.h
@@ -16,7 +16,7 @@
/**
* @defgroup retransmit_job retransmit_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef RETRANSMIT_JOB_H_
diff --git a/src/libcharon/processing/jobs/roam_job.h b/src/libcharon/processing/jobs/roam_job.h
index 55bdf2b28..acfb8bed8 100644
--- a/src/libcharon/processing/jobs/roam_job.h
+++ b/src/libcharon/processing/jobs/roam_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup roam_job roam_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef ROAM_JOB_H_
diff --git a/src/libcharon/processing/jobs/send_dpd_job.h b/src/libcharon/processing/jobs/send_dpd_job.h
index 8078a38bc..bd2728b9a 100644
--- a/src/libcharon/processing/jobs/send_dpd_job.h
+++ b/src/libcharon/processing/jobs/send_dpd_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup send_dpd_job send_dpd_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef SEND_DPD_JOB_H_
diff --git a/src/libcharon/processing/jobs/send_keepalive_job.h b/src/libcharon/processing/jobs/send_keepalive_job.h
index cda83cd7e..acf6d11aa 100644
--- a/src/libcharon/processing/jobs/send_keepalive_job.h
+++ b/src/libcharon/processing/jobs/send_keepalive_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup send_keepalive_job send_keepalive_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef SEND_KEEPALIVE_JOB_H_
diff --git a/src/libcharon/processing/jobs/update_sa_job.h b/src/libcharon/processing/jobs/update_sa_job.h
index 11d1ac9b6..e2344fcc4 100644
--- a/src/libcharon/processing/jobs/update_sa_job.h
+++ b/src/libcharon/processing/jobs/update_sa_job.h
@@ -15,7 +15,7 @@
/**
* @defgroup update_sa_job update_sa_job
- * @{ @ingroup jobs
+ * @{ @ingroup cjobs
*/
#ifndef UPDATE_SA_JOB_H_
diff --git a/src/libcharon/processing/processor.c b/src/libcharon/processing/processor.c
deleted file mode 100644
index d5774af26..000000000
--- a/src/libcharon/processing/processor.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2005-2007 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#include "processor.h"
-
-#include <daemon.h>
-#include <threading/thread.h>
-#include <threading/condvar.h>
-#include <threading/mutex.h>
-#include <utils/linked_list.h>
-
-
-typedef struct private_processor_t private_processor_t;
-
-/**
- * Private data of processor_t class.
- */
-struct private_processor_t {
- /**
- * Public processor_t interface.
- */
- processor_t public;
-
- /**
- * Number of running threads
- */
- u_int total_threads;
-
- /**
- * Desired number of threads
- */
- u_int desired_threads;
-
- /**
- * Number of threads waiting for work
- */
- u_int idle_threads;
-
- /**
- * All threads managed in the pool (including threads that have been
- * cancelled, this allows to join them during destruction)
- */
- linked_list_t *threads;
-
- /**
- * The jobs are stored in a linked list
- */
- linked_list_t *list;
-
- /**
- * access to linked_list is locked through this mutex
- */
- mutex_t *mutex;
-
- /**
- * Condvar to wait for new jobs
- */
- condvar_t *job_added;
-
- /**
- * Condvar to wait for terminated threads
- */
- condvar_t *thread_terminated;
-};
-
-static void process_jobs(private_processor_t *this);
-
-/**
- * restart a terminated thread
- */
-static void restart(private_processor_t *this)
-{
- thread_t *thread;
-
- DBG2(DBG_JOB, "terminated worker thread, ID: %u", thread_current_id());
-
- /* respawn thread if required */
- this->mutex->lock(this->mutex);
- if (this->desired_threads < this->total_threads ||
- (thread = thread_create((thread_main_t)process_jobs, this)) == NULL)
- {
- this->total_threads--;
- this->thread_terminated->signal(this->thread_terminated);
- }
- else
- {
- this->threads->insert_last(this->threads, thread);
- }
- this->mutex->unlock(this->mutex);
-}
-
-/**
- * Process queued jobs, called by the worker threads
- */
-static void process_jobs(private_processor_t *this)
-{
- /* worker threads are not cancellable by default */
- thread_cancelability(FALSE);
-
- DBG2(DBG_JOB, "started worker thread, ID: %u", thread_current_id());
-
- this->mutex->lock(this->mutex);
- while (this->desired_threads >= this->total_threads)
- {
- job_t *job;
-
- if (this->list->get_count(this->list) == 0)
- {
- this->idle_threads++;
- this->job_added->wait(this->job_added, this->mutex);
- this->idle_threads--;
- continue;
- }
- this->list->remove_first(this->list, (void**)&job);
- this->mutex->unlock(this->mutex);
- /* terminated threads are restarted, so we have a constant pool */
- thread_cleanup_push((thread_cleanup_t)restart, this);
- job->execute(job);
- thread_cleanup_pop(FALSE);
- this->mutex->lock(this->mutex);
- }
- this->mutex->unlock(this->mutex);
- restart(this);
-}
-
-/**
- * Implementation of processor_t.get_total_threads.
- */
-static u_int get_total_threads(private_processor_t *this)
-{
- u_int count;
- this->mutex->lock(this->mutex);
- count = this->total_threads;
- this->mutex->unlock(this->mutex);
- return count;
-}
-
-/**
- * Implementation of processor_t.get_idle_threads.
- */
-static u_int get_idle_threads(private_processor_t *this)
-{
- u_int count;
- this->mutex->lock(this->mutex);
- count = this->idle_threads;
- this->mutex->unlock(this->mutex);
- return count;
-}
-
-/**
- * implements processor_t.get_job_load
- */
-static u_int get_job_load(private_processor_t *this)
-{
- u_int load;
- this->mutex->lock(this->mutex);
- load = this->list->get_count(this->list);
- this->mutex->unlock(this->mutex);
- return load;
-}
-
-/**
- * implements function processor_t.queue_job
- */
-static void queue_job(private_processor_t *this, job_t *job)
-{
- this->mutex->lock(this->mutex);
- this->list->insert_last(this->list, job);
- this->job_added->signal(this->job_added);
- this->mutex->unlock(this->mutex);
-}
-
-/**
- * Implementation of processor_t.set_threads.
- */
-static void set_threads(private_processor_t *this, u_int count)
-{
- this->mutex->lock(this->mutex);
- if (count > this->total_threads)
- { /* increase thread count */
- int i;
- thread_t *current;
-
- this->desired_threads = count;
- DBG1(DBG_JOB, "spawning %d worker threads", count - this->total_threads);
- for (i = this->total_threads; i < count; i++)
- {
- current = thread_create((thread_main_t)process_jobs, this);
- if (current)
- {
- this->threads->insert_last(this->threads, current);
- this->total_threads++;
- }
- }
- }
- else if (count < this->total_threads)
- { /* decrease thread count */
- this->desired_threads = count;
- }
- this->job_added->broadcast(this->job_added);
- this->mutex->unlock(this->mutex);
-}
-
-/**
- * Implementation of processor_t.destroy.
- */
-static void destroy(private_processor_t *this)
-{
- thread_t *current;
- set_threads(this, 0);
- this->mutex->lock(this->mutex);
- while (this->total_threads > 0)
- {
- this->job_added->broadcast(this->job_added);
- this->thread_terminated->wait(this->thread_terminated, this->mutex);
- }
- while (this->threads->remove_first(this->threads,
- (void**)&current) == SUCCESS)
- {
- current->join(current);
- }
- this->mutex->unlock(this->mutex);
- this->thread_terminated->destroy(this->thread_terminated);
- this->job_added->destroy(this->job_added);
- this->mutex->destroy(this->mutex);
- this->list->destroy_offset(this->list, offsetof(job_t, destroy));
- this->threads->destroy(this->threads);
- free(this);
-}
-
-/*
- * Described in header.
- */
-processor_t *processor_create(size_t pool_size)
-{
- private_processor_t *this = malloc_thing(private_processor_t);
-
- this->public.get_total_threads = (u_int(*)(processor_t*))get_total_threads;
- this->public.get_idle_threads = (u_int(*)(processor_t*))get_idle_threads;
- this->public.get_job_load = (u_int(*)(processor_t*))get_job_load;
- this->public.queue_job = (void(*)(processor_t*, job_t*))queue_job;
- this->public.set_threads = (void(*)(processor_t*, u_int))set_threads;
- this->public.destroy = (void(*)(processor_t*))destroy;
-
- this->list = linked_list_create();
- this->threads = linked_list_create();
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
- this->job_added = condvar_create(CONDVAR_TYPE_DEFAULT);
- this->thread_terminated = condvar_create(CONDVAR_TYPE_DEFAULT);
- this->total_threads = 0;
- this->desired_threads = 0;
- this->idle_threads = 0;
-
- return &this->public;
-}
-
diff --git a/src/libcharon/processing/processor.h b/src/libcharon/processing/processor.h
deleted file mode 100644
index 5bf8cf573..000000000
--- a/src/libcharon/processing/processor.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2005-2007 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup processor processor
- * @{ @ingroup processing
- */
-
-#ifndef PROCESSOR_H_
-#define PROCESSOR_H_
-
-typedef struct processor_t processor_t;
-
-#include <stdlib.h>
-
-#include <library.h>
-#include <processing/jobs/job.h>
-
-/**
- * The processor uses threads to process queued jobs.
- */
-struct processor_t {
-
- /**
- * Get the total number of threads used by the processor.
- *
- * @return size of thread pool
- */
- u_int (*get_total_threads) (processor_t *this);
-
- /**
- * Get the number of threads currently waiting.
- *
- * @return number of idle threads
- */
- u_int (*get_idle_threads) (processor_t *this);
-
- /**
- * Get the number of queued jobs.
- *
- * @returns number of items in queue
- */
- u_int (*get_job_load) (processor_t *this);
-
- /**
- * Adds a job to the queue.
- *
- * This function is non blocking and adds a job_t to the queue.
- *
- * @param job job to add to the queue
- */
- void (*queue_job) (processor_t *this, job_t *job);
-
- /**
- * Set the number of threads to use in the processor.
- *
- * If the number of threads is smaller than number of currently running
- * threads, thread count is decreased. Use 0 to disable the processor.
- * This call blocks if it decreases thread count until threads have
- * terminated, so make sure there are not too many blocking jobs.
- *
- * @param count number of threads to allocate
- */
- void (*set_threads)(processor_t *this, u_int count);
-
- /**
- * Destroy a processor object.
- */
- void (*destroy) (processor_t *processor);
-};
-
-/**
- * Create the thread pool without any threads.
- *
- * Use the set_threads method to start processing jobs.
- *
- * @return processor_t object
- */
-processor_t *processor_create();
-
-#endif /** PROCESSOR_H_ @}*/
diff --git a/src/libcharon/processing/scheduler.c b/src/libcharon/processing/scheduler.c
deleted file mode 100644
index 345af502a..000000000
--- a/src/libcharon/processing/scheduler.c
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <stdlib.h>
-
-#include "scheduler.h"
-
-#include <daemon.h>
-#include <processing/processor.h>
-#include <processing/jobs/callback_job.h>
-#include <threading/thread.h>
-#include <threading/condvar.h>
-#include <threading/mutex.h>
-
-/* the initial size of the heap */
-#define HEAP_SIZE_DEFAULT 64
-
-typedef struct event_t event_t;
-
-/**
- * Event containing a job and a schedule time
- */
-struct event_t {
- /**
- * Time to fire the event.
- */
- timeval_t time;
-
- /**
- * Every event has its assigned job.
- */
- job_t *job;
-};
-
-/**
- * destroy an event and its job
- */
-static void event_destroy(event_t *event)
-{
- event->job->destroy(event->job);
- free(event);
-}
-
-typedef struct private_scheduler_t private_scheduler_t;
-
-/**
- * Private data of a scheduler_t object.
- */
-struct private_scheduler_t {
-
- /**
- * Public part of a scheduler_t object.
- */
- scheduler_t public;
-
- /**
- * Job which queues scheduled jobs to the processor.
- */
- callback_job_t *job;
-
- /**
- * The heap in which the events are stored.
- */
- event_t **heap;
-
- /**
- * The size of the heap.
- */
- u_int heap_size;
-
- /**
- * The number of scheduled events.
- */
- u_int event_count;
-
- /**
- * Exclusive access to list
- */
- mutex_t *mutex;
-
- /**
- * Condvar to wait for next job.
- */
- condvar_t *condvar;
-};
-
-/**
- * Comparse two timevals, return >0 if a > b, <0 if a < b and =0 if equal
- */
-static int timeval_cmp(timeval_t *a, timeval_t *b)
-{
- if (a->tv_sec > b->tv_sec)
- {
- return 1;
- }
- if (a->tv_sec < b->tv_sec)
- {
- return -1;
- }
- if (a->tv_usec > b->tv_usec)
- {
- return 1;
- }
- if (a->tv_usec < b->tv_usec)
- {
- return -1;
- }
- return 0;
-}
-
-/**
- * Returns the top event without removing it. Returns NULL if the heap is empty.
- */
-static event_t *peek_event(private_scheduler_t *this)
-{
- return this->event_count > 0 ? this->heap[1] : NULL;
-}
-
-/**
- * Removes the top event from the heap and returns it. Returns NULL if the heap
- * is empty.
- */
-static event_t *remove_event(private_scheduler_t *this)
-{
- event_t *event, *top;
- if (!this->event_count)
- {
- return NULL;
- }
-
- /* store the value to return */
- event = this->heap[1];
- /* move the bottom event to the top */
- top = this->heap[1] = this->heap[this->event_count];
-
- if (--this->event_count > 1)
- {
- /* seep down the top event */
- u_int position = 1;
- while ((position << 1) <= this->event_count)
- {
- u_int child = position << 1;
-
- if ((child + 1) <= this->event_count &&
- timeval_cmp(&this->heap[child + 1]->time,
- &this->heap[child]->time) < 0)
- {
- /* the "right" child is smaller */
- child++;
- }
-
- if (timeval_cmp(&top->time, &this->heap[child]->time) <= 0)
- {
- /* the top event fires before the smaller of the two children,
- * stop */
- break;
- }
-
- /* swap with the smaller child */
- this->heap[position] = this->heap[child];
- position = child;
- }
- this->heap[position] = top;
- }
- return event;
-}
-
-/**
- * Get events from the queue and pass it to the processor
- */
-static job_requeue_t schedule(private_scheduler_t * this)
-{
- timeval_t now;
- event_t *event;
- bool timed = FALSE, oldstate;
-
- this->mutex->lock(this->mutex);
-
- time_monotonic(&now);
-
- if ((event = peek_event(this)) != NULL)
- {
- if (timeval_cmp(&now, &event->time) >= 0)
- {
- remove_event(this);
- this->mutex->unlock(this->mutex);
- DBG2(DBG_JOB, "got event, queuing job for execution");
- charon->processor->queue_job(charon->processor, event->job);
- free(event);
- return JOB_REQUEUE_DIRECT;
- }
- timersub(&event->time, &now, &now);
- if (now.tv_sec)
- {
- DBG2(DBG_JOB, "next event in %ds %dms, waiting",
- now.tv_sec, now.tv_usec/1000);
- }
- else
- {
- DBG2(DBG_JOB, "next event in %dms, waiting", now.tv_usec/1000);
- }
- timed = TRUE;
- }
- thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
- oldstate = thread_cancelability(TRUE);
-
- if (timed)
- {
- this->condvar->timed_wait_abs(this->condvar, this->mutex, event->time);
- }
- else
- {
- DBG2(DBG_JOB, "no events, waiting");
- this->condvar->wait(this->condvar, this->mutex);
- }
- thread_cancelability(oldstate);
- thread_cleanup_pop(TRUE);
- return JOB_REQUEUE_DIRECT;
-}
-
-/**
- * Implements scheduler_t.get_job_load
- */
-static u_int get_job_load(private_scheduler_t *this)
-{
- int count;
- this->mutex->lock(this->mutex);
- count = this->event_count;
- this->mutex->unlock(this->mutex);
- return count;
-}
-
-/**
- * Implements scheduler_t.schedule_job_tv.
- */
-static void schedule_job_tv(private_scheduler_t *this, job_t *job, timeval_t tv)
-{
- event_t *event;
- u_int position;
-
- event = malloc_thing(event_t);
- event->job = job;
- event->time = tv;
-
- this->mutex->lock(this->mutex);
-
- this->event_count++;
- if (this->event_count > this->heap_size)
- {
- /* double the size of the heap */
- this->heap_size <<= 1;
- this->heap = (event_t**)realloc(this->heap,
- (this->heap_size + 1) * sizeof(event_t*));
- }
- /* "put" the event to the bottom */
- position = this->event_count;
-
- /* then bubble it up */
- while (position > 1 && timeval_cmp(&this->heap[position >> 1]->time,
- &event->time) > 0)
- {
- /* parent has to be fired after the new event, move up */
- this->heap[position] = this->heap[position >> 1];
- position >>= 1;
- }
- this->heap[position] = event;
-
- this->condvar->signal(this->condvar);
- this->mutex->unlock(this->mutex);
-}
-
-/**
- * Implements scheduler_t.schedule_job.
- */
-static void schedule_job(private_scheduler_t *this, job_t *job, u_int32_t s)
-{
- timeval_t tv;
-
- time_monotonic(&tv);
- tv.tv_sec += s;
-
- schedule_job_tv(this, job, tv);
-}
-
-/**
- * Implements scheduler_t.schedule_job_ms.
- */
-static void schedule_job_ms(private_scheduler_t *this, job_t *job, u_int32_t ms)
-{
- timeval_t tv, add;
-
- time_monotonic(&tv);
- add.tv_sec = ms / 1000;
- add.tv_usec = (ms % 1000) * 1000;
-
- timeradd(&tv, &add, &tv);
-
- schedule_job_tv(this, job, tv);
-}
-
-/**
- * Implementation of scheduler_t.destroy.
- */
-static void destroy(private_scheduler_t *this)
-{
- event_t *event;
- this->job->cancel(this->job);
- this->condvar->destroy(this->condvar);
- this->mutex->destroy(this->mutex);
- while ((event = remove_event(this)) != NULL)
- {
- event_destroy(event);
- }
- free(this->heap);
- free(this);
-}
-
-/*
- * Described in header.
- */
-scheduler_t * scheduler_create()
-{
- private_scheduler_t *this = malloc_thing(private_scheduler_t);
-
- this->public.get_job_load = (u_int (*) (scheduler_t *this)) get_job_load;
- this->public.schedule_job = (void (*) (scheduler_t *this, job_t *job, u_int32_t s)) schedule_job;
- this->public.schedule_job_ms = (void (*) (scheduler_t *this, job_t *job, u_int32_t ms)) schedule_job_ms;
- this->public.schedule_job_tv = (void (*) (scheduler_t *this, job_t *job, timeval_t tv)) schedule_job_tv;
- this->public.destroy = (void(*)(scheduler_t*)) destroy;
-
- /* Note: the root of the heap is at index 1 */
- this->event_count = 0;
- this->heap_size = HEAP_SIZE_DEFAULT;
- this->heap = (event_t**)calloc(this->heap_size + 1, sizeof(event_t*));
-
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
- this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT);
-
- this->job = callback_job_create((callback_job_cb_t)schedule, this, NULL, NULL);
- charon->processor->queue_job(charon->processor, (job_t*)this->job);
-
- return &this->public;
-}
-
diff --git a/src/libcharon/processing/scheduler.h b/src/libcharon/processing/scheduler.h
deleted file mode 100644
index 5f5d2a563..000000000
--- a/src/libcharon/processing/scheduler.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2009 Tobias Brunner
- * Copyright (C) 2005-2007 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup scheduler scheduler
- * @{ @ingroup processing
- */
-
-#ifndef SCHEDULER_H_
-#define SCHEDULER_H_
-
-typedef struct scheduler_t scheduler_t;
-
-#include <library.h>
-#include <processing/jobs/job.h>
-
-/**
- * The scheduler queues timed events which are then passed to the processor.
- *
- * The scheduler is implemented as a heap. A heap is a special kind of tree-
- * based data structure that satisfies the following property: if B is a child
- * node of A, then key(A) >= (or <=) key(B). So either the element with the
- * greatest (max-heap) or the smallest (min-heap) key is the root of the heap.
- * We use a min-heap whith the key being the absolute unix time at which an
- * event is scheduled. So the root is always the event that will fire next.
- *
- * An earlier implementation of the scheduler used a sorted linked list to store
- * the events. That had the advantage that removing the next event was extremely
- * fast, also, adding an event scheduled before or after all other events was
- * equally fast (all in O(1)). The problem was, though, that adding an event
- * in-between got slower, as the number of events grew larger (O(n)).
- * For each connection there could be several events: IKE-rekey, NAT-keepalive,
- * retransmissions, expire (half-open), and others. So a gateway that probably
- * has to handle thousands of concurrent connnections has to be able to queue a
- * large number of events as fast as possible. Locking makes this even worse, to
- * provide thread-safety, no events can be processed, while an event is queued,
- * so making the insertion fast is even more important.
- *
- * That's the advantage of the heap. Adding an element to the heap can be
- * achieved in O(log n) - on the other hand, removing the root node also
- * requires O(log n) operations. Consider 10000 queued events. Inserting a new
- * event in the list implementation required up to 10000 comparisons. In the
- * heap implementation, the worst case is about 13.3 comparisons. That's a
- * drastic improvement.
- *
- * The implementation itself uses a binary tree mapped to a one-based array to
- * store the elements. This reduces storage overhead and simplifies navigation:
- * the children of the node at position n are at position 2n and 2n+1 (likewise
- * the parent node of the node at position n is at position [n/2]). Thus,
- * navigating up and down the tree is reduced to simple index computations.
- *
- * Adding an element to the heap works as follows: The heap is always filled
- * from left to right, until a row is full, then the next row is filled. Mapped
- * to an array this gets as simple as putting the new element to the first free
- * position. In a one-based array that position equals the number of elements
- * currently stored in the heap. Then the heap property has to be restored, i.e.
- * the new element has to be "bubbled up" the tree until the parent node's key
- * is smaller or the element got the new root of the tree.
- *
- * Removing the next event from the heap works similarly. The event itself is
- * the root node and stored at position 1 of the array. After removing it, the
- * root has to be replaced and the heap property has to be restored. This is
- * done by moving the bottom element (last row, rightmost element) to the root
- * and then "seep it down" by swapping it with child nodes until none of the
- * children has a smaller key or it is again a leaf node.
- */
-struct scheduler_t {
-
- /**
- * Adds a event to the queue, using a relative time offset in s.
- *
- * @param job job to schedule
- * @param time relative time to schedule job, in s
- */
- void (*schedule_job) (scheduler_t *this, job_t *job, u_int32_t s);
-
- /**
- * Adds a event to the queue, using a relative time offset in ms.
- *
- * @param job job to schedule
- * @param time relative time to schedule job, in ms
- */
- void (*schedule_job_ms) (scheduler_t *this, job_t *job, u_int32_t ms);
-
- /**
- * Adds a event to the queue, using an absolut time.
- *
- * The passed timeval should be calculated based on the time_monotonic()
- * function.
- *
- * @param job job to schedule
- * @param time absolut time to schedule job
- */
- void (*schedule_job_tv) (scheduler_t *this, job_t *job, timeval_t tv);
-
- /**
- * Returns number of jobs scheduled.
- *
- * @return number of scheduled jobs
- */
- u_int (*get_job_load) (scheduler_t *this);
-
- /**
- * Destroys a scheduler object.
- */
- void (*destroy) (scheduler_t *this);
-};
-
-/**
- * Create a scheduler.
- *
- * @return scheduler_t object
- */
-scheduler_t *scheduler_create(void);
-
-#endif /** SCHEDULER_H_ @}*/
diff --git a/src/libcharon/sa/authenticators/eap/eap_manager.c b/src/libcharon/sa/authenticators/eap/eap_manager.c
index f795183f0..bc2c4a617 100644
--- a/src/libcharon/sa/authenticators/eap/eap_manager.c
+++ b/src/libcharon/sa/authenticators/eap/eap_manager.c
@@ -68,12 +68,9 @@ struct private_eap_manager_t {
rwlock_t *lock;
};
-/**
- * Implementation of eap_manager_t.add_method.
- */
-static void add_method(private_eap_manager_t *this, eap_type_t type,
- u_int32_t vendor, eap_role_t role,
- eap_constructor_t constructor)
+METHOD(eap_manager_t, add_method, void,
+ private_eap_manager_t *this, eap_type_t type, u_int32_t vendor,
+ eap_role_t role, eap_constructor_t constructor)
{
eap_entry_t *entry = malloc_thing(eap_entry_t);
@@ -87,10 +84,8 @@ static void add_method(private_eap_manager_t *this, eap_type_t type,
this->lock->unlock(this->lock);
}
-/**
- * Implementation of eap_manager_t.remove_method.
- */
-static void remove_method(private_eap_manager_t *this, eap_constructor_t constructor)
+METHOD(eap_manager_t, remove_method, void,
+ private_eap_manager_t *this, eap_constructor_t constructor)
{
enumerator_t *enumerator;
eap_entry_t *entry;
@@ -109,13 +104,9 @@ static void remove_method(private_eap_manager_t *this, eap_constructor_t constru
this->lock->unlock(this->lock);
}
-/**
- * Implementation of eap_manager_t.create_instance.
- */
-static eap_method_t* create_instance(private_eap_manager_t *this,
- eap_type_t type, u_int32_t vendor,
- eap_role_t role, identification_t *server,
- identification_t *peer)
+METHOD(eap_manager_t, create_instance, eap_method_t*,
+ private_eap_manager_t *this, eap_type_t type, u_int32_t vendor,
+ eap_role_t role, identification_t *server, identification_t *peer)
{
enumerator_t *enumerator;
eap_entry_t *entry;
@@ -140,10 +131,8 @@ static eap_method_t* create_instance(private_eap_manager_t *this,
return method;
}
-/**
- * Implementation of 2008_t.destroy
- */
-static void destroy(private_eap_manager_t *this)
+METHOD(eap_manager_t, destroy, void,
+ private_eap_manager_t *this)
{
this->methods->destroy_function(this->methods, free);
this->lock->destroy(this->lock);
@@ -151,19 +140,22 @@ static void destroy(private_eap_manager_t *this)
}
/*
- * see header file
+ * See header
*/
eap_manager_t *eap_manager_create()
{
- private_eap_manager_t *this = malloc_thing(private_eap_manager_t);
-
- this->public.add_method = (void(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, eap_constructor_t constructor))add_method;
- this->public.remove_method = (void(*)(eap_manager_t*, eap_constructor_t constructor))remove_method;
- this->public.create_instance = (eap_method_t*(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, identification_t*,identification_t*))create_instance;
- this->public.destroy = (void(*)(eap_manager_t*))destroy;
-
- this->methods = linked_list_create();
- this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
+ private_eap_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .add_method = _add_method,
+ .remove_method = _remove_method,
+ .create_instance = _create_instance,
+ .destroy = _destroy,
+ },
+ .methods = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
return &this->public;
}
diff --git a/src/libcharon/sa/authenticators/eap/eap_method.c b/src/libcharon/sa/authenticators/eap/eap_method.c
index ad7b92cfa..0fa4a00c5 100644
--- a/src/libcharon/sa/authenticators/eap/eap_method.c
+++ b/src/libcharon/sa/authenticators/eap/eap_method.c
@@ -15,55 +15,8 @@
#include "eap_method.h"
-/*
- * See header
- */
-eap_type_t eap_type_from_string(char *name)
-{
- int i;
- static struct {
- char *name;
- eap_type_t type;
- } types[] = {
- {"identity", EAP_IDENTITY},
- {"md5", EAP_MD5},
- {"otp", EAP_OTP},
- {"gtc", EAP_GTC},
- {"sim", EAP_SIM},
- {"aka", EAP_AKA},
- {"mschapv2", EAP_MSCHAPV2},
- {"radius", EAP_RADIUS},
- };
-
- for (i = 0; i < countof(types); i++)
- {
- if (strcaseeq(name, types[i].name))
- {
- return types[i].type;
- }
- }
- return 0;
-}
-
-ENUM(eap_code_names, EAP_REQUEST, EAP_FAILURE,
- "EAP_REQUEST",
- "EAP_RESPONSE",
- "EAP_SUCCESS",
- "EAP_FAILURE",
-);
-
-ENUM(eap_code_short_names, EAP_REQUEST, EAP_FAILURE,
- "REQ",
- "RES",
- "SUCC",
- "FAIL",
-);
-
ENUM(eap_role_names, EAP_SERVER, EAP_PEER,
"EAP_SERVER",
"EAP_PEER",
);
-
-
-
diff --git a/src/libcharon/sa/authenticators/eap/eap_method.h b/src/libcharon/sa/authenticators/eap/eap_method.h
index df354edb4..9961039ff 100644
--- a/src/libcharon/sa/authenticators/eap/eap_method.h
+++ b/src/libcharon/sa/authenticators/eap/eap_method.h
@@ -23,10 +23,10 @@
typedef struct eap_method_t eap_method_t;
typedef enum eap_role_t eap_role_t;
-typedef enum eap_code_t eap_code_t;
#include <library.h>
#include <utils/identification.h>
+#include <eap/eap.h>
#include <encoding/payloads/eap_payload.h>
/**
@@ -42,34 +42,6 @@ enum eap_role_t {
extern enum_name_t *eap_role_names;
/**
- * Lookup the EAP method type from a string.
- *
- * @param name EAP method name (such as "md5", "aka")
- * @return method type, 0 if unkown
- */
-eap_type_t eap_type_from_string(char *name);
-
-/**
- * EAP code, type of an EAP message
- */
-enum eap_code_t {
- EAP_REQUEST = 1,
- EAP_RESPONSE = 2,
- EAP_SUCCESS = 3,
- EAP_FAILURE = 4,
-};
-
-/**
- * enum names for eap_code_t.
- */
-extern enum_name_t *eap_code_names;
-
-/**
- * short string enum names for eap_code_t.
- */
-extern enum_name_t *eap_code_short_names;
-
-/**
* Interface of an EAP method for server and client side.
*
* An EAP method initiates an EAP exchange and processes requests and
diff --git a/src/libcharon/sa/authenticators/eap_authenticator.c b/src/libcharon/sa/authenticators/eap_authenticator.c
index 3c0f3c358..8b22fd1d7 100644
--- a/src/libcharon/sa/authenticators/eap_authenticator.c
+++ b/src/libcharon/sa/authenticators/eap_authenticator.c
@@ -99,22 +99,30 @@ struct private_eap_authenticator_t {
static eap_method_t *load_method(private_eap_authenticator_t *this,
eap_type_t type, u_int32_t vendor, eap_role_t role)
{
- identification_t *server, *peer;
+ identification_t *server, *peer, *aaa;
+ auth_cfg_t *auth;
if (role == EAP_SERVER)
{
server = this->ike_sa->get_my_id(this->ike_sa);
peer = this->ike_sa->get_other_id(this->ike_sa);
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
}
else
{
server = this->ike_sa->get_other_id(this->ike_sa);
peer = this->ike_sa->get_my_id(this->ike_sa);
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
}
if (this->eap_identity)
{
peer = this->eap_identity;
}
+ aaa = auth->get(auth, AUTH_RULE_AAA_IDENTITY);
+ if (aaa)
+ {
+ server = aaa;
+ }
return charon->eap->create_instance(charon->eap, type, vendor,
role, server, peer);
}
@@ -458,11 +466,8 @@ static void build_auth(private_eap_authenticator_t *this, message_t *message,
chunk_free(&auth_data);
}
-/**
- * Implementation of authenticator_t.process for a server
- */
-static status_t process_server(private_eap_authenticator_t *this,
- message_t *message)
+METHOD(authenticator_t, process_server, status_t,
+ private_eap_authenticator_t *this, message_t *message)
{
eap_payload_t *eap_payload;
@@ -492,11 +497,8 @@ static status_t process_server(private_eap_authenticator_t *this,
return NEED_MORE;
}
-/**
- * Implementation of authenticator_t.build for a server
- */
-static status_t build_server(private_eap_authenticator_t *this,
- message_t *message)
+METHOD(authenticator_t, build_server, status_t,
+ private_eap_authenticator_t *this, message_t *message)
{
if (this->eap_payload)
{
@@ -519,11 +521,8 @@ static status_t build_server(private_eap_authenticator_t *this,
return FAILED;
}
-/**
- * Implementation of authenticator_t.process for a client
- */
-static status_t process_client(private_eap_authenticator_t *this,
- message_t *message)
+METHOD(authenticator_t, process_client, status_t,
+ private_eap_authenticator_t *this, message_t *message)
{
eap_payload_t *eap_payload;
@@ -603,11 +602,8 @@ static status_t process_client(private_eap_authenticator_t *this,
return FAILED;
}
-/**
- * Implementation of authenticator_t.build for a client
- */
-static status_t build_client(private_eap_authenticator_t *this,
- message_t *message)
+METHOD(authenticator_t, build_client, status_t,
+ private_eap_authenticator_t *this, message_t *message)
{
if (this->eap_payload)
{
@@ -623,20 +619,16 @@ static status_t build_client(private_eap_authenticator_t *this,
return NEED_MORE;
}
-/**
- * Implementation of authenticator_t.is_mutual.
- */
-static bool is_mutual(private_eap_authenticator_t *this)
+METHOD(authenticator_t, is_mutual, bool,
+ private_eap_authenticator_t *this)
{
/* we don't know yet, but insist on it after EAP is complete */
this->require_mutual = TRUE;
return TRUE;
}
-/**
- * Implementation of authenticator_t.destroy.
- */
-static void destroy(private_eap_authenticator_t *this)
+METHOD(authenticator_t, destroy, void,
+ private_eap_authenticator_t *this)
{
DESTROY_IF(this->method);
DESTROY_IF(this->eap_payload);
@@ -652,25 +644,23 @@ eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa,
chunk_t received_nonce, chunk_t sent_nonce,
chunk_t received_init, chunk_t sent_init)
{
- private_eap_authenticator_t *this = malloc_thing(private_eap_authenticator_t);
-
- this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))build_client;
- this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process_client;
- this->public.authenticator.is_mutual = (bool(*)(authenticator_t*))is_mutual;
- this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
-
- this->ike_sa = ike_sa;
- this->received_init = received_init;
- this->received_nonce = received_nonce;
- this->sent_init = sent_init;
- this->sent_nonce = sent_nonce;
- this->msk = chunk_empty;
- this->method = NULL;
- this->eap_payload = NULL;
- this->eap_complete = FALSE;
- this->auth_complete = FALSE;
- this->eap_identity = NULL;
- this->require_mutual = FALSE;
+ private_eap_authenticator_t *this;
+
+ INIT(this,
+ .public = {
+ .authenticator = {
+ .build = _build_client,
+ .process = _process_client,
+ .is_mutual = _is_mutual,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa = ike_sa,
+ .received_init = received_init,
+ .received_nonce = received_nonce,
+ .sent_init = sent_init,
+ .sent_nonce = sent_nonce,
+ );
return &this->public;
}
@@ -682,25 +672,23 @@ eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa,
chunk_t received_nonce, chunk_t sent_nonce,
chunk_t received_init, chunk_t sent_init)
{
- private_eap_authenticator_t *this = malloc_thing(private_eap_authenticator_t);
-
- this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *messageh))build_server;
- this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process_server;
- this->public.authenticator.is_mutual = (bool(*)(authenticator_t*))is_mutual;
- this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
-
- this->ike_sa = ike_sa;
- this->received_init = received_init;
- this->received_nonce = received_nonce;
- this->sent_init = sent_init;
- this->sent_nonce = sent_nonce;
- this->msk = chunk_empty;
- this->method = NULL;
- this->eap_payload = NULL;
- this->eap_complete = FALSE;
- this->auth_complete = FALSE;
- this->eap_identity = NULL;
- this->require_mutual = FALSE;
+ private_eap_authenticator_t *this;
+
+ INIT(this,
+ .public = {
+ .authenticator = {
+ .build = _build_server,
+ .process = _process_server,
+ .is_mutual = _is_mutual,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa = ike_sa,
+ .received_init = received_init,
+ .received_nonce = received_nonce,
+ .sent_init = sent_init,
+ .sent_nonce = sent_nonce,
+ );
return &this->public;
}
diff --git a/src/libcharon/sa/authenticators/pubkey_authenticator.c b/src/libcharon/sa/authenticators/pubkey_authenticator.c
index 3c67f6db6..54b4338bb 100644
--- a/src/libcharon/sa/authenticators/pubkey_authenticator.c
+++ b/src/libcharon/sa/authenticators/pubkey_authenticator.c
@@ -84,15 +84,15 @@ static status_t build(private_pubkey_authenticator_t *this, message_t *message)
/* we try to deduct the signature scheme from the keysize */
switch (private->get_keysize(private))
{
- case 32:
+ case 256:
scheme = SIGN_ECDSA_256;
auth_method = AUTH_ECDSA_256;
break;
- case 48:
+ case 384:
scheme = SIGN_ECDSA_384;
auth_method = AUTH_ECDSA_384;
break;
- case 66:
+ case 521:
scheme = SIGN_ECDSA_521;
auth_method = AUTH_ECDSA_521;
break;
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c
index bd41cba56..b6ef31da0 100644
--- a/src/libcharon/sa/child_sa.c
+++ b/src/libcharon/sa/child_sa.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2009 Tobias Brunner
+ * Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
@@ -23,6 +23,7 @@
#include <string.h>
#include <time.h>
+#include <hydra.h>
#include <daemon.h>
ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
@@ -179,170 +180,144 @@ struct private_child_sa_t {
};
/**
- * Implementation of child_sa_t.get_name
+ * convert an IKEv2 specific protocol identifier to the IP protocol identifier.
*/
-static char *get_name(private_child_sa_t *this)
+static inline u_int8_t proto_ike2ip(protocol_id_t protocol)
+{
+ switch (protocol)
+ {
+ case PROTO_ESP:
+ return IPPROTO_ESP;
+ case PROTO_AH:
+ return IPPROTO_AH;
+ default:
+ return protocol;
+ }
+}
+
+METHOD(child_sa_t, get_name, char*,
+ private_child_sa_t *this)
{
return this->config->get_name(this->config);
}
-/**
- * Implements child_sa_t.get_reqid
- */
-static u_int32_t get_reqid(private_child_sa_t *this)
+METHOD(child_sa_t, get_reqid, u_int32_t,
+ private_child_sa_t *this)
{
return this->reqid;
}
-/**
- * Implements child_sa_t.get_config
- */
-static child_cfg_t* get_config(private_child_sa_t *this)
+METHOD(child_sa_t, get_config, child_cfg_t*,
+ private_child_sa_t *this)
{
return this->config;
}
-/**
- * Implements child_sa_t.set_state
- */
-static void set_state(private_child_sa_t *this, child_sa_state_t state)
+METHOD(child_sa_t, set_state, void,
+ private_child_sa_t *this, child_sa_state_t state)
{
charon->bus->child_state_change(charon->bus, &this->public, state);
this->state = state;
}
-/**
- * Implements child_sa_t.get_state
- */
-static child_sa_state_t get_state(private_child_sa_t *this)
+METHOD(child_sa_t, get_state, child_sa_state_t,
+ private_child_sa_t *this)
{
return this->state;
}
-/**
- * Implements child_sa_t.get_spi
- */
-u_int32_t get_spi(private_child_sa_t *this, bool inbound)
+METHOD(child_sa_t, get_spi, u_int32_t,
+ private_child_sa_t *this, bool inbound)
{
return inbound ? this->my_spi : this->other_spi;
}
-/**
- * Implements child_sa_t.get_cpi
- */
-u_int16_t get_cpi(private_child_sa_t *this, bool inbound)
+METHOD(child_sa_t, get_cpi, u_int16_t,
+ private_child_sa_t *this, bool inbound)
{
return inbound ? this->my_cpi : this->other_cpi;
}
-/**
- * Implements child_sa_t.get_protocol
- */
-protocol_id_t get_protocol(private_child_sa_t *this)
+METHOD(child_sa_t, get_protocol, protocol_id_t,
+ private_child_sa_t *this)
{
return this->protocol;
}
-/**
- * Implementation of child_sa_t.set_protocol
- */
-static void set_protocol(private_child_sa_t *this, protocol_id_t protocol)
+METHOD(child_sa_t, set_protocol, void,
+ private_child_sa_t *this, protocol_id_t protocol)
{
this->protocol = protocol;
}
-/**
- * Implementation of child_sa_t.get_mode
- */
-static ipsec_mode_t get_mode(private_child_sa_t *this)
+METHOD(child_sa_t, get_mode, ipsec_mode_t,
+ private_child_sa_t *this)
{
return this->mode;
}
-/**
- * Implementation of child_sa_t.set_mode
- */
-static void set_mode(private_child_sa_t *this, ipsec_mode_t mode)
+METHOD(child_sa_t, set_mode, void,
+ private_child_sa_t *this, ipsec_mode_t mode)
{
this->mode = mode;
}
-/**
- * Implementation of child_sa_t.has_encap
- */
-static bool has_encap(private_child_sa_t *this)
+METHOD(child_sa_t, has_encap, bool,
+ private_child_sa_t *this)
{
return this->encap;
}
-/**
- * Implementation of child_sa_t.get_ipcomp
- */
-static ipcomp_transform_t get_ipcomp(private_child_sa_t *this)
+METHOD(child_sa_t, get_ipcomp, ipcomp_transform_t,
+ private_child_sa_t *this)
{
return this->ipcomp;
}
-/**
- * Implementation of child_sa_t.set_ipcomp.
- */
-static void set_ipcomp(private_child_sa_t *this, ipcomp_transform_t ipcomp)
+METHOD(child_sa_t, set_ipcomp, void,
+ private_child_sa_t *this, ipcomp_transform_t ipcomp)
{
this->ipcomp = ipcomp;
}
-/**
- * Implementation of child_sa_t.set_close_action.
- */
-static void set_close_action(private_child_sa_t *this, action_t action)
+METHOD(child_sa_t, set_close_action, void,
+ private_child_sa_t *this, action_t action)
{
this->close_action = action;
}
-/**
- * Implementation of child_sa_t.get_close_action.
- */
-static action_t get_close_action(private_child_sa_t *this)
+METHOD(child_sa_t, get_close_action, action_t,
+ private_child_sa_t *this)
{
return this->close_action;
}
-/**
- * Implementation of child_sa_t.set_dpd_action.
- */
-static void set_dpd_action(private_child_sa_t *this, action_t action)
+METHOD(child_sa_t, set_dpd_action, void,
+ private_child_sa_t *this, action_t action)
{
this->dpd_action = action;
}
-/**
- * Implementation of child_sa_t.get_dpd_action.
- */
-static action_t get_dpd_action(private_child_sa_t *this)
+METHOD(child_sa_t, get_dpd_action, action_t,
+ private_child_sa_t *this)
{
return this->dpd_action;
}
-/**
- * Implementation of child_sa_t.get_proposal
- */
-static proposal_t* get_proposal(private_child_sa_t *this)
+METHOD(child_sa_t, get_proposal, proposal_t*,
+ private_child_sa_t *this)
{
return this->proposal;
}
-/**
- * Implementation of child_sa_t.set_proposal
- */
-static void set_proposal(private_child_sa_t *this, proposal_t *proposal)
+METHOD(child_sa_t, set_proposal, void,
+ private_child_sa_t *this, proposal_t *proposal)
{
this->proposal = proposal->clone(proposal);
}
-/**
- * Implementation of child_sa_t.get_traffic_selectors.
- */
-static linked_list_t *get_traffic_selectors(private_child_sa_t *this, bool local)
+METHOD(child_sa_t, get_traffic_selectors, linked_list_t*,
+ private_child_sa_t *this, bool local)
{
return local ? this->my_ts : this->other_ts;
}
@@ -365,11 +340,9 @@ struct policy_enumerator_t {
traffic_selector_t *ts;
};
-/**
- * enumerator function of create_policy_enumerator()
- */
-static bool policy_enumerate(policy_enumerator_t *this,
- traffic_selector_t **my_out, traffic_selector_t **other_out)
+METHOD(enumerator_t, policy_enumerate, bool,
+ policy_enumerator_t *this, traffic_selector_t **my_out,
+ traffic_selector_t **other_out)
{
traffic_selector_t *other_ts;
@@ -399,29 +372,29 @@ static bool policy_enumerate(policy_enumerator_t *this,
return FALSE;
}
-/**
- * destroy function of create_policy_enumerator()
- */
-static void policy_destroy(policy_enumerator_t *this)
+METHOD(enumerator_t, policy_destroy, void,
+ policy_enumerator_t *this)
{
this->mine->destroy(this->mine);
this->other->destroy(this->other);
free(this);
}
-/**
- * Implementation of child_sa_t.create_policy_enumerator
- */
-static enumerator_t* create_policy_enumerator(private_child_sa_t *this)
+METHOD(child_sa_t, create_policy_enumerator, enumerator_t*,
+ private_child_sa_t *this)
{
- policy_enumerator_t *e = malloc_thing(policy_enumerator_t);
-
- e->public.enumerate = (void*)policy_enumerate;
- e->public.destroy = (void*)policy_destroy;
- e->mine = this->my_ts->create_enumerator(this->my_ts);
- e->other = this->other_ts->create_enumerator(this->other_ts);
- e->list = this->other_ts;
- e->ts = NULL;
+ policy_enumerator_t *e;
+
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_policy_enumerate,
+ .destroy = _policy_destroy,
+ },
+ .mine = this->my_ts->create_enumerator(this->my_ts),
+ .other = this->other_ts->create_enumerator(this->other_ts),
+ .list = this->other_ts,
+ .ts = NULL,
+ );
return &e->public;
}
@@ -441,10 +414,10 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
{
if (this->my_spi)
{
- status = charon->kernel_interface->query_sa(charon->kernel_interface,
- this->other_addr, this->my_addr,
- this->my_spi, this->protocol,
- this->mark_in, &bytes);
+ status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
+ this->other_addr, this->my_addr, this->my_spi,
+ proto_ike2ip(this->protocol), this->mark_in,
+ &bytes);
if (status == SUCCESS)
{
if (bytes > this->my_usebytes)
@@ -460,10 +433,10 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
{
if (this->other_spi)
{
- status = charon->kernel_interface->query_sa(charon->kernel_interface,
- this->my_addr, this->other_addr,
- this->other_spi, this->protocol,
- this->mark_out, &bytes);
+ status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
+ this->my_addr, this->other_addr, this->other_spi,
+ proto_ike2ip(this->protocol), this->mark_out,
+ &bytes);
if (status == SUCCESS)
{
if (bytes > this->other_usebytes)
@@ -494,14 +467,14 @@ static void update_usetime(private_child_sa_t *this, bool inbound)
if (inbound)
{
- if (charon->kernel_interface->query_policy(charon->kernel_interface,
+ if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
other_ts, my_ts, POLICY_IN, this->mark_in, &in) == SUCCESS)
{
last_use = max(last_use, in);
}
if (this->mode != MODE_TRANSPORT)
{
- if (charon->kernel_interface->query_policy(charon->kernel_interface,
+ if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
other_ts, my_ts, POLICY_FWD, this->mark_in, &fwd) == SUCCESS)
{
last_use = max(last_use, fwd);
@@ -510,7 +483,7 @@ static void update_usetime(private_child_sa_t *this, bool inbound)
}
else
{
- if (charon->kernel_interface->query_policy(charon->kernel_interface,
+ if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
my_ts, other_ts, POLICY_OUT, this->mark_out, &out) == SUCCESS)
{
last_use = max(last_use, out);
@@ -533,11 +506,8 @@ static void update_usetime(private_child_sa_t *this, bool inbound)
}
}
-/**
- * Implementation of child_sa_t.get_usestats
- */
-static void get_usestats(private_child_sa_t *this, bool inbound,
- time_t *time, u_int64_t *bytes)
+METHOD(child_sa_t, get_usestats, void,
+ private_child_sa_t *this, bool inbound, time_t *time, u_int64_t *bytes)
{
if (update_usebytes(this, inbound) != FAILED)
{
@@ -556,48 +526,41 @@ static void get_usestats(private_child_sa_t *this, bool inbound,
}
}
-/**
- * Implementation of child_sa_t.get_lifetime
- */
-static time_t get_lifetime(private_child_sa_t *this, bool hard)
+METHOD(child_sa_t, get_lifetime, time_t,
+ private_child_sa_t *this, bool hard)
{
return hard ? this->expire_time : this->rekey_time;
}
-/**
- * Implementation of child_sa_t.alloc_spi
- */
-static u_int32_t alloc_spi(private_child_sa_t *this, protocol_id_t protocol)
+METHOD(child_sa_t, alloc_spi, u_int32_t,
+ private_child_sa_t *this, protocol_id_t protocol)
{
- if (charon->kernel_interface->get_spi(charon->kernel_interface,
- this->other_addr, this->my_addr, protocol,
- this->reqid, &this->my_spi) == SUCCESS)
+ if (hydra->kernel_interface->get_spi(hydra->kernel_interface,
+ this->other_addr, this->my_addr,
+ proto_ike2ip(protocol), this->reqid,
+ &this->my_spi) == SUCCESS)
{
return this->my_spi;
}
return 0;
}
-/**
- * Implementation of child_sa_t.alloc_cpi
- */
-static u_int16_t alloc_cpi(private_child_sa_t *this)
+METHOD(child_sa_t, alloc_cpi, u_int16_t,
+ private_child_sa_t *this)
{
- if (charon->kernel_interface->get_cpi(charon->kernel_interface,
- this->other_addr, this->my_addr, this->reqid,
- &this->my_cpi) == SUCCESS)
+ if (hydra->kernel_interface->get_cpi(hydra->kernel_interface,
+ this->other_addr, this->my_addr,
+ this->reqid, &this->my_cpi) == SUCCESS)
{
return this->my_cpi;
}
return 0;
}
-/**
- * Implementation of child_sa_t.install
- */
-static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
- u_int32_t spi, u_int16_t cpi, bool inbound,
- linked_list_t *my_ts, linked_list_t *other_ts)
+METHOD(child_sa_t, install, status_t,
+ private_child_sa_t *this, chunk_t encr, chunk_t integ, u_int32_t spi,
+ u_int16_t cpi, bool inbound, linked_list_t *my_ts,
+ linked_list_t *other_ts)
{
u_int16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size;
traffic_selector_t *src_ts = NULL, *dst_ts = NULL;
@@ -674,8 +637,8 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
}
}
- status = charon->kernel_interface->add_sa(charon->kernel_interface,
- src, dst, spi, this->protocol, this->reqid,
+ status = hydra->kernel_interface->add_sa(hydra->kernel_interface,
+ src, dst, spi, proto_ike2ip(this->protocol), this->reqid,
inbound ? this->mark_in : this->mark_out,
lifetime, enc_alg, encr, int_alg, integ, this->mode,
this->ipcomp, cpi, this->encap, update, src_ts, dst_ts);
@@ -685,11 +648,9 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
return status;
}
-/**
- * Implementation of child_sa_t.add_policies
- */
-static status_t add_policies(private_child_sa_t *this,
- linked_list_t *my_ts_list, linked_list_t *other_ts_list)
+METHOD(child_sa_t, add_policies, status_t,
+ private_child_sa_t *this, linked_list_t *my_ts_list,
+ linked_list_t *other_ts_list)
{
enumerator_t *enumerator;
traffic_selector_t *my_ts, *other_ts;
@@ -712,26 +673,55 @@ static status_t add_policies(private_child_sa_t *this,
if (this->config->install_policy(this->config))
{
+ ipsec_sa_cfg_t my_sa = {
+ .mode = this->mode,
+ .reqid = this->reqid,
+ .ipcomp = {
+ .transform = this->ipcomp,
+ },
+ }, other_sa = my_sa;
+
+ my_sa.ipcomp.cpi = this->my_cpi;
+ other_sa.ipcomp.cpi = this->other_cpi;
+
+ if (this->protocol == PROTO_ESP)
+ {
+ my_sa.esp.use = TRUE;
+ my_sa.esp.spi = this->my_spi;
+ other_sa.esp.use = TRUE;
+ other_sa.esp.spi = this->other_spi;
+ }
+ else
+ {
+ my_sa.ah.use = TRUE;
+ my_sa.ah.spi = this->my_spi;
+ other_sa.ah.use = TRUE;
+ other_sa.ah.spi = this->other_spi;
+ }
+
/* enumerate pairs of traffic selectors */
enumerator = create_policy_enumerator(this);
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
{
/* install 3 policies: out, in and forward */
- status |= charon->kernel_interface->add_policy(charon->kernel_interface,
- this->my_addr, this->other_addr, my_ts, other_ts, POLICY_OUT,
- this->other_spi, this->protocol, this->reqid, this->mark_out,
- this->mode, this->ipcomp, this->other_cpi, routed);
-
- status |= charon->kernel_interface->add_policy(charon->kernel_interface,
- this->other_addr, this->my_addr, other_ts, my_ts, POLICY_IN,
- this->my_spi, this->protocol, this->reqid, this->mark_in,
- this->mode, this->ipcomp, this->my_cpi, routed);
+ status |= hydra->kernel_interface->add_policy(
+ hydra->kernel_interface,
+ this->my_addr, this->other_addr, my_ts, other_ts,
+ POLICY_OUT, POLICY_IPSEC, &other_sa,
+ this->mark_out, routed);
+
+ status |= hydra->kernel_interface->add_policy(
+ hydra->kernel_interface,
+ this->other_addr, this->my_addr, other_ts, my_ts,
+ POLICY_IN, POLICY_IPSEC, &my_sa,
+ this->mark_in, routed);
if (this->mode != MODE_TRANSPORT)
{
- status |= charon->kernel_interface->add_policy(charon->kernel_interface,
- this->other_addr, this->my_addr, other_ts, my_ts, POLICY_FWD,
- this->my_spi, this->protocol, this->reqid, this->mark_in,
- this->mode, this->ipcomp, this->my_cpi, routed);
+ status |= hydra->kernel_interface->add_policy(
+ hydra->kernel_interface,
+ this->other_addr, this->my_addr, other_ts, my_ts,
+ POLICY_FWD, POLICY_IPSEC, &my_sa,
+ this->mark_in, routed);
}
if (status != SUCCESS)
@@ -749,11 +739,9 @@ static status_t add_policies(private_child_sa_t *this,
return status;
}
-/**
- * Implementation of child_sa_t.update.
- */
-static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
- host_t *vip, bool encap)
+METHOD(child_sa_t, update, status_t,
+ private_child_sa_t *this, host_t *me, host_t *other, host_t *vip,
+ bool encap)
{
child_sa_state_t old;
bool transport_proxy_mode;
@@ -775,8 +763,8 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
/* update our (initator) SA */
if (this->my_spi)
{
- if (charon->kernel_interface->update_sa(charon->kernel_interface,
- this->my_spi, this->protocol,
+ if (hydra->kernel_interface->update_sa(hydra->kernel_interface,
+ this->my_spi, proto_ike2ip(this->protocol),
this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
this->other_addr, this->my_addr, other, me,
this->encap, encap, this->mark_in) == NOT_SUPPORTED)
@@ -788,8 +776,8 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
/* update his (responder) SA */
if (this->other_spi)
{
- if (charon->kernel_interface->update_sa(charon->kernel_interface,
- this->other_spi, this->protocol,
+ if (hydra->kernel_interface->update_sa(hydra->kernel_interface,
+ this->other_spi, proto_ike2ip(this->protocol),
this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
this->my_addr, this->other_addr, me, other,
this->encap, encap, this->mark_out) == NOT_SUPPORTED)
@@ -801,6 +789,32 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
if (this->config->install_policy(this->config))
{
+ ipsec_sa_cfg_t my_sa = {
+ .mode = this->mode,
+ .reqid = this->reqid,
+ .ipcomp = {
+ .transform = this->ipcomp,
+ },
+ }, other_sa = my_sa;
+
+ my_sa.ipcomp.cpi = this->my_cpi;
+ other_sa.ipcomp.cpi = this->other_cpi;
+
+ if (this->protocol == PROTO_ESP)
+ {
+ my_sa.esp.use = TRUE;
+ my_sa.esp.spi = this->my_spi;
+ other_sa.esp.use = TRUE;
+ other_sa.esp.spi = this->other_spi;
+ }
+ else
+ {
+ my_sa.ah.use = TRUE;
+ my_sa.ah.spi = this->my_spi;
+ other_sa.ah.use = TRUE;
+ other_sa.ah.spi = this->other_spi;
+ }
+
/* update policies */
if (!me->ip_equals(me, this->my_addr) ||
!other->ip_equals(other, this->other_addr))
@@ -813,13 +827,13 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
{
/* remove old policies first */
- charon->kernel_interface->del_policy(charon->kernel_interface,
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
my_ts, other_ts, POLICY_OUT, this->mark_out, FALSE);
- charon->kernel_interface->del_policy(charon->kernel_interface,
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
other_ts, my_ts, POLICY_IN, this->mark_in, FALSE);
if (this->mode != MODE_TRANSPORT)
{
- charon->kernel_interface->del_policy(charon->kernel_interface,
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
other_ts, my_ts, POLICY_FWD, this->mark_in, FALSE);
}
@@ -839,25 +853,22 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
* correctly */
if (vip)
{
- charon->kernel_interface->del_ip(charon->kernel_interface, vip);
- charon->kernel_interface->add_ip(charon->kernel_interface, vip, me);
+ hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
+ hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, me);
}
/* reinstall updated policies */
- charon->kernel_interface->add_policy(charon->kernel_interface,
- me, other, my_ts, other_ts, POLICY_OUT, this->other_spi,
- this->protocol, this->reqid, this->mark_out, this->mode,
- this->ipcomp, this->other_cpi, FALSE);
- charon->kernel_interface->add_policy(charon->kernel_interface,
- other, me, other_ts, my_ts, POLICY_IN, this->my_spi,
- this->protocol, this->reqid, this->mark_in, this->mode,
- this->ipcomp, this->my_cpi, FALSE);
+ hydra->kernel_interface->add_policy(hydra->kernel_interface,
+ me, other, my_ts, other_ts, POLICY_OUT, POLICY_IPSEC,
+ &other_sa, this->mark_out, FALSE);
+ hydra->kernel_interface->add_policy(hydra->kernel_interface,
+ other, me, other_ts, my_ts, POLICY_IN, POLICY_IPSEC,
+ &my_sa, this->mark_in, FALSE);
if (this->mode != MODE_TRANSPORT)
{
- charon->kernel_interface->add_policy(charon->kernel_interface,
- other, me, other_ts, my_ts, POLICY_FWD, this->my_spi,
- this->protocol, this->reqid, this->mark_in, this->mode,
- this->ipcomp, this->my_cpi, FALSE);
+ hydra->kernel_interface->add_policy(hydra->kernel_interface,
+ other, me, other_ts, my_ts, POLICY_FWD, POLICY_IPSEC,
+ &my_sa, this->mark_in, FALSE);
}
}
enumerator->destroy(enumerator);
@@ -885,10 +896,8 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
return SUCCESS;
}
-/**
- * Implementation of child_sa_t.destroy.
- */
-static void destroy(private_child_sa_t *this)
+METHOD(child_sa_t, destroy, void,
+ private_child_sa_t *this)
{
enumerator_t *enumerator;
traffic_selector_t *my_ts, *other_ts;
@@ -905,15 +914,17 @@ static void destroy(private_child_sa_t *this)
{
this->protocol = PROTO_ESP;
}
- charon->kernel_interface->del_sa(charon->kernel_interface,
+ hydra->kernel_interface->del_sa(hydra->kernel_interface,
this->other_addr, this->my_addr, this->my_spi,
- this->protocol, this->my_cpi, this->mark_in);
+ proto_ike2ip(this->protocol), this->my_cpi,
+ this->mark_in);
}
if (this->other_spi)
{
- charon->kernel_interface->del_sa(charon->kernel_interface,
+ hydra->kernel_interface->del_sa(hydra->kernel_interface,
this->my_addr, this->other_addr, this->other_spi,
- this->protocol, this->other_cpi, this->mark_out);
+ proto_ike2ip(this->protocol), this->other_cpi,
+ this->mark_out);
}
if (this->config->install_policy(this->config))
@@ -922,14 +933,14 @@ static void destroy(private_child_sa_t *this)
enumerator = create_policy_enumerator(this);
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
{
- charon->kernel_interface->del_policy(charon->kernel_interface,
- my_ts, other_ts, POLICY_OUT, this->mark_out, unrouted);
- charon->kernel_interface->del_policy(charon->kernel_interface,
- other_ts, my_ts, POLICY_IN, this->mark_in, unrouted);
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
+ my_ts, other_ts, POLICY_OUT, this->mark_out, unrouted);
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
+ other_ts, my_ts, POLICY_IN, this->mark_in, unrouted);
if (this->mode != MODE_TRANSPORT)
{
- charon->kernel_interface->del_policy(charon->kernel_interface,
- other_ts, my_ts, POLICY_FWD, this->mark_in, unrouted);
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
+ other_ts, my_ts, POLICY_FWD, this->mark_in, unrouted);
}
}
enumerator->destroy(enumerator);
@@ -944,75 +955,66 @@ static void destroy(private_child_sa_t *this)
free(this);
}
-/*
+/**
* Described in header.
*/
child_sa_t * child_sa_create(host_t *me, host_t* other,
child_cfg_t *config, u_int32_t rekey, bool encap)
{
static u_int32_t reqid = 0;
- private_child_sa_t *this = malloc_thing(private_child_sa_t);
-
- /* public functions */
- this->public.get_name = (char*(*)(child_sa_t*))get_name;
- this->public.get_reqid = (u_int32_t(*)(child_sa_t*))get_reqid;
- this->public.get_config = (child_cfg_t*(*)(child_sa_t*))get_config;
- this->public.get_state = (child_sa_state_t(*)(child_sa_t*))get_state;
- this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state;
- this->public.get_spi = (u_int32_t(*)(child_sa_t*, bool))get_spi;
- this->public.get_cpi = (u_int16_t(*)(child_sa_t*, bool))get_cpi;
- this->public.get_protocol = (protocol_id_t(*)(child_sa_t*))get_protocol;
- this->public.set_protocol = (void(*)(child_sa_t*, protocol_id_t protocol))set_protocol;
- this->public.get_mode = (ipsec_mode_t(*)(child_sa_t*))get_mode;
- this->public.set_mode = (void(*)(child_sa_t*, ipsec_mode_t mode))set_mode;
- this->public.get_proposal = (proposal_t*(*)(child_sa_t*))get_proposal;
- this->public.set_proposal = (void(*)(child_sa_t*, proposal_t *proposal))set_proposal;
- this->public.get_lifetime = (time_t(*)(child_sa_t*, bool))get_lifetime;
- this->public.get_usestats = (void(*)(child_sa_t*,bool,time_t*,u_int64_t*))get_usestats;
- this->public.has_encap = (bool(*)(child_sa_t*))has_encap;
- this->public.get_ipcomp = (ipcomp_transform_t(*)(child_sa_t*))get_ipcomp;
- this->public.set_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t))set_ipcomp;
- this->public.get_close_action = (action_t(*)(child_sa_t*))get_close_action;
- this->public.set_close_action = (void(*)(child_sa_t*,action_t))set_close_action;
- this->public.get_dpd_action = (action_t(*)(child_sa_t*))get_dpd_action;
- this->public.set_dpd_action = (void(*)(child_sa_t*,action_t))set_dpd_action;
- this->public.alloc_spi = (u_int32_t(*)(child_sa_t*, protocol_id_t protocol))alloc_spi;
- this->public.alloc_cpi = (u_int16_t(*)(child_sa_t*))alloc_cpi;
- this->public.install = (status_t(*)(child_sa_t*, chunk_t encr, chunk_t integ, u_int32_t spi, u_int16_t cpi, bool inbound, linked_list_t *my_ts_list, linked_list_t *other_ts_list))install;
- this->public.update = (status_t (*)(child_sa_t*,host_t*,host_t*,host_t*,bool))update;
- this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*))add_policies;
- this->public.get_traffic_selectors = (linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors;
- this->public.create_policy_enumerator = (enumerator_t*(*)(child_sa_t*))create_policy_enumerator;
- this->public.destroy = (void(*)(child_sa_t*))destroy;
-
- /* private data */
- this->my_addr = me->clone(me);
- this->other_addr = other->clone(other);
- this->my_spi = 0;
- this->other_spi = 0;
- this->my_cpi = 0;
- this->other_cpi = 0;
- this->encap = encap;
- this->ipcomp = IPCOMP_NONE;
- this->state = CHILD_CREATED;
- this->my_usetime = 0;
- this->other_usetime = 0;
- this->my_usebytes = 0;
- this->other_usebytes = 0;
- this->my_ts = linked_list_create();
- this->other_ts = linked_list_create();
- this->protocol = PROTO_NONE;
- this->mode = MODE_TUNNEL;
- this->close_action = config->get_close_action(config);
- this->dpd_action = config->get_dpd_action(config);
- this->proposal = NULL;
- this->rekey_time = 0;
- this->expire_time = 0;
+ private_child_sa_t *this;
+
+ INIT(this,
+ .public = {
+ .get_name = _get_name,
+ .get_reqid = _get_reqid,
+ .get_config = _get_config,
+ .get_state = _get_state,
+ .set_state = _set_state,
+ .get_spi = _get_spi,
+ .get_cpi = _get_cpi,
+ .get_protocol = _get_protocol,
+ .set_protocol = _set_protocol,
+ .get_mode = _get_mode,
+ .set_mode = _set_mode,
+ .get_proposal = _get_proposal,
+ .set_proposal = _set_proposal,
+ .get_lifetime = _get_lifetime,
+ .get_usestats = _get_usestats,
+ .has_encap = _has_encap,
+ .get_ipcomp = _get_ipcomp,
+ .set_ipcomp = _set_ipcomp,
+ .get_close_action = _get_close_action,
+ .set_close_action = _set_close_action,
+ .get_dpd_action = _get_dpd_action,
+ .set_dpd_action = _set_dpd_action,
+ .alloc_spi = _alloc_spi,
+ .alloc_cpi = _alloc_cpi,
+ .install = _install,
+ .update = _update,
+ .add_policies = _add_policies,
+ .get_traffic_selectors = _get_traffic_selectors,
+ .create_policy_enumerator = _create_policy_enumerator,
+ .destroy = _destroy,
+ },
+ .my_addr = me->clone(me),
+ .other_addr = other->clone(other),
+ .encap = encap,
+ .ipcomp = IPCOMP_NONE,
+ .state = CHILD_CREATED,
+ .my_ts = linked_list_create(),
+ .other_ts = linked_list_create(),
+ .protocol = PROTO_NONE,
+ .mode = MODE_TUNNEL,
+ .close_action = config->get_close_action(config),
+ .dpd_action = config->get_dpd_action(config),
+ .reqid = config->get_reqid(config),
+ .mark_in = config->get_mark(config, TRUE),
+ .mark_out = config->get_mark(config, FALSE),
+ );
+
this->config = config;
config->get_ref(config);
- this->reqid = config->get_reqid(config);
- this->mark_in = config->get_mark(config, TRUE);
- this->mark_out = config->get_mark(config, FALSE);
if (!this->reqid)
{
diff --git a/src/libcharon/sa/connect_manager.c b/src/libcharon/sa/connect_manager.c
index b78ba070d..1fb286863 100644
--- a/src/libcharon/sa/connect_manager.c
+++ b/src/libcharon/sa/connect_manager.c
@@ -932,7 +932,7 @@ static void update_checklist_state(private_connect_manager_t *this,
callback_data_t *data = callback_data_create(this, checklist->connect_id);
job_t *job = (job_t*)callback_job_create((callback_job_cb_t)initiator_finish, data, (callback_job_cleanup_t)callback_data_destroy, NULL);
- charon->scheduler->schedule_job_ms(charon->scheduler, job, ME_WAIT_TO_FINISH);
+ lib->scheduler->schedule_job_ms(lib->scheduler, job, ME_WAIT_TO_FINISH);
checklist->is_finishing = TRUE;
}
@@ -1031,7 +1031,7 @@ static void queue_retransmission(private_connect_manager_t *this, check_list_t *
DBG2(DBG_IKE, "scheduling retransmission %d of pair '%d' in %dms",
retransmission, pair->id, rto);
- charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*)job, rto);
+ lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)job, rto);
}
/**
@@ -1064,7 +1064,7 @@ static void send_check(private_connect_manager_t *this, check_list_t *checklist,
DBG2(DBG_IKE, "send ME_CONNECTAUTH %#B", &check->auth);
packet_t *packet;
- if (message->generate(message, NULL, NULL, &packet) == SUCCESS)
+ if (message->generate(message, NULL, &packet) == SUCCESS)
{
charon->sender->send(charon->sender, packet->clone(packet));
@@ -1170,7 +1170,7 @@ static void schedule_checks(private_connect_manager_t *this, check_list_t *check
{
callback_data_t *data = callback_data_create(this, checklist->connect_id);
checklist->sender = (job_t*)callback_job_create((callback_job_cb_t)sender, data, (callback_job_cleanup_t)callback_data_destroy, NULL);
- charon->scheduler->schedule_job_ms(charon->scheduler, checklist->sender, time);
+ lib->scheduler->schedule_job_ms(lib->scheduler, checklist->sender, time);
}
/**
@@ -1222,7 +1222,7 @@ static void finish_checks(private_connect_manager_t *this, check_list_t *checkli
initiate_data_t *data = initiate_data_create(checklist, initiated);
job_t *job = (job_t*)callback_job_create((callback_job_cb_t)initiate_mediated, data, (callback_job_cleanup_t)initiate_data_destroy, NULL);
- charon->processor->queue_job(charon->processor, job);
+ lib->processor->queue_job(lib->processor, job);
return;
}
else
@@ -1357,7 +1357,7 @@ static void process_request(private_connect_manager_t *this, check_t *check,
*/
static void process_check(private_connect_manager_t *this, message_t *message)
{
- if (message->parse_body(message, NULL, NULL) != SUCCESS)
+ if (message->parse_body(message, NULL) != SUCCESS)
{
DBG1(DBG_IKE, "%N %s with message ID %d processing failed",
exchange_type_names, message->get_exchange_type(message),
@@ -1477,7 +1477,7 @@ static void check_and_initiate(private_connect_manager_t *this,
{
job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa,
waiting_sa);
- charon->processor->queue_job(charon->processor, job);
+ lib->processor->queue_job(lib->processor, job);
}
iterator->destroy(iterator);
diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c
index 7536662ca..a4e4028ab 100644
--- a/src/libcharon/sa/ike_sa.c
+++ b/src/libcharon/sa/ike_sa.c
@@ -24,8 +24,8 @@
#include "ike_sa.h"
#include <library.h>
-#include <daemon.h>
#include <hydra.h>
+#include <daemon.h>
#include <utils/linked_list.h>
#include <utils/lexparser.h>
#include <sa/task_manager.h>
@@ -470,8 +470,8 @@ METHOD(ike_sa_t, send_keepalive, void,
diff = 0;
}
job = send_keepalive_job_create(this->ike_sa_id);
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)job,
- this->keepalive_interval - diff);
+ lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
+ this->keepalive_interval - diff);
}
METHOD(ike_sa_t, get_ike_cfg, ike_cfg_t*,
@@ -605,7 +605,7 @@ METHOD(ike_sa_t, send_dpd, status_t,
}
/* recheck in "interval" seconds */
job = (job_t*)send_dpd_job_create(this->ike_sa_id);
- charon->scheduler->schedule_job(charon->scheduler, job, delay - diff);
+ lib->scheduler->schedule_job(lib->scheduler, job, delay - diff);
return SUCCESS;
}
@@ -644,7 +644,7 @@ METHOD(ike_sa_t, set_state, void,
{
this->stats[STAT_REKEY] = t + this->stats[STAT_ESTABLISHED];
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, FALSE);
- charon->scheduler->schedule_job(charon->scheduler, job, t);
+ lib->scheduler->schedule_job(lib->scheduler, job, t);
DBG1(DBG_IKE, "scheduling rekeying in %ds", t);
}
t = this->peer_cfg->get_reauth_time(this->peer_cfg);
@@ -653,7 +653,7 @@ METHOD(ike_sa_t, set_state, void,
{
this->stats[STAT_REAUTH] = t + this->stats[STAT_ESTABLISHED];
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE);
- charon->scheduler->schedule_job(charon->scheduler, job, t);
+ lib->scheduler->schedule_job(lib->scheduler, job, t);
DBG1(DBG_IKE, "scheduling reauthentication in %ds", t);
}
t = this->peer_cfg->get_over_time(this->peer_cfg);
@@ -675,7 +675,7 @@ METHOD(ike_sa_t, set_state, void,
this->stats[STAT_DELETE] += t;
t = this->stats[STAT_DELETE] - this->stats[STAT_ESTABLISHED];
job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
- charon->scheduler->schedule_job(charon->scheduler, job, t);
+ lib->scheduler->schedule_job(lib->scheduler, job, t);
DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t);
}
@@ -688,8 +688,8 @@ METHOD(ike_sa_t, set_state, void,
{
/* delete may fail if a packet gets lost, so set a timeout */
job_t *job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
- charon->scheduler->schedule_job(charon->scheduler, job,
- HALF_OPEN_IKE_SA_TIMEOUT);
+ lib->scheduler->schedule_job(lib->scheduler, job,
+ HALF_OPEN_IKE_SA_TIMEOUT);
break;
}
default:
@@ -730,14 +730,14 @@ METHOD(ike_sa_t, set_virtual_ip, void,
if (local)
{
DBG1(DBG_IKE, "installing new virtual IP %H", ip);
- if (charon->kernel_interface->add_ip(charon->kernel_interface, ip,
- this->my_host) == SUCCESS)
+ if (hydra->kernel_interface->add_ip(hydra->kernel_interface, ip,
+ this->my_host) == SUCCESS)
{
if (this->my_virtual_ip)
{
DBG1(DBG_IKE, "removing old virtual IP %H", this->my_virtual_ip);
- charon->kernel_interface->del_ip(charon->kernel_interface,
- this->my_virtual_ip);
+ hydra->kernel_interface->del_ip(hydra->kernel_interface,
+ this->my_virtual_ip);
}
DESTROY_IF(this->my_virtual_ip);
this->my_virtual_ip = ip->clone(ip);
@@ -810,6 +810,20 @@ METHOD(ike_sa_t, get_pending_updates, u_int32_t,
return this->pending_updates;
}
+METHOD(ike_sa_t, float_ports, void,
+ private_ike_sa_t *this)
+{
+ /* do not switch if we have a custom port from MOBIKE/NAT */
+ if (this->my_host->get_port(this->my_host) == IKEV2_UDP_PORT)
+ {
+ this->my_host->set_port(this->my_host, IKEV2_NATT_PORT);
+ }
+ if (this->other_host->get_port(this->other_host) == IKEV2_UDP_PORT)
+ {
+ this->other_host->set_port(this->other_host, IKEV2_NATT_PORT);
+ }
+}
+
METHOD(ike_sa_t, update_hosts, void,
private_ike_sa_t *this, host_t *me, host_t *other)
{
@@ -843,10 +857,8 @@ METHOD(ike_sa_t, update_hosts, void,
if (!other->equals(other, this->other_host))
{
- /* update others adress if we are NOT NATed,
- * and allow port changes if we are NATed */
- if (!has_condition(this, COND_NAT_HERE) ||
- other->ip_equals(other, this->other_host))
+ /* update others adress if we are NOT NATed */
+ if (!has_condition(this, COND_NAT_HERE))
{
set_other_host(this, other->clone(other));
update = TRUE;
@@ -882,8 +894,7 @@ METHOD(ike_sa_t, generate_message, status_t,
this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
message->set_ike_sa_id(message, this->ike_sa_id);
return message->generate(message,
- this->keymat->get_crypter(this->keymat, FALSE),
- this->keymat->get_signer(this->keymat, FALSE), packet);
+ this->keymat->get_aead(this->keymat, FALSE), packet);
}
/**
@@ -1049,8 +1060,8 @@ static void resolve_hosts(private_ike_sa_t *this)
!this->other_host->is_anyaddr(this->other_host))
{
host->destroy(host);
- host = charon->kernel_interface->get_source_addr(
- charon->kernel_interface, this->other_host, NULL);
+ host = hydra->kernel_interface->get_source_addr(
+ hydra->kernel_interface, this->other_host, NULL);
if (host)
{
host->set_port(host, this->ike_cfg->get_my_port(this->ike_cfg));
@@ -1150,7 +1161,7 @@ METHOD(ike_sa_t, initiate, status_t,
{
/* mediated connection, initiate mediation process */
job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id);
- charon->processor->queue_job(charon->processor, job);
+ lib->processor->queue_job(lib->processor, job);
return SUCCESS;
}
#endif /* ME */
@@ -1173,8 +1184,7 @@ METHOD(ike_sa_t, process_message, status_t,
is_request = message->get_request(message);
status = message->parse_body(message,
- this->keymat->get_crypter(this->keymat, TRUE),
- this->keymat->get_signer(this->keymat, TRUE));
+ this->keymat->get_aead(this->keymat, TRUE));
if (status != SUCCESS)
{
@@ -1229,15 +1239,12 @@ METHOD(ike_sa_t, process_message, status_t,
}
else
{
- host_t *me, *other;
-
- me = message->get_destination(message);
- other = message->get_source(message);
-
/* if this IKE_SA is virgin, we check for a config */
if (this->ike_cfg == NULL)
{
job_t *job;
+ host_t *me = message->get_destination(message),
+ *other = message->get_source(message);
this->ike_cfg = charon->backends->get_ike_cfg(charon->backends,
me, other);
if (this->ike_cfg == NULL)
@@ -1250,20 +1257,12 @@ METHOD(ike_sa_t, process_message, status_t,
}
/* add a timeout if peer does not establish it completely */
job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, FALSE);
- charon->scheduler->schedule_job(charon->scheduler, job,
- HALF_OPEN_IKE_SA_TIMEOUT);
+ lib->scheduler->schedule_job(lib->scheduler, job,
+ HALF_OPEN_IKE_SA_TIMEOUT);
}
this->stats[STAT_INBOUND] = time_monotonic(NULL);
- /* check if message is trustworthy, and update host information */
- if (this->state == IKE_CREATED || this->state == IKE_CONNECTING ||
- message->get_exchange_type(message) != IKE_SA_INIT)
- {
- if (!supports_extension(this, EXT_MOBIKE))
- { /* with MOBIKE, we do no implicit updates */
- update_hosts(this, me, other);
- }
- }
- status = this->task_manager->process_message(this->task_manager, message);
+ status = this->task_manager->process_message(this->task_manager,
+ message);
if (message->get_exchange_type(message) == IKE_AUTH &&
this->state == IKE_ESTABLISHED &&
lib->settings->get_bool(lib->settings,
@@ -1697,7 +1696,7 @@ METHOD(ike_sa_t, set_auth_lifetime, void,
{
DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, starting reauthentication",
lifetime);
- charon->processor->queue_job(charon->processor,
+ lib->processor->queue_job(lib->processor,
(job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE));
}
else if (this->stats[STAT_REAUTH] == 0 ||
@@ -1706,7 +1705,7 @@ METHOD(ike_sa_t, set_auth_lifetime, void,
this->stats[STAT_REAUTH] = reauth_time;
DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling reauthentication"
" in %ds", lifetime, lifetime - reduction);
- charon->scheduler->schedule_job(charon->scheduler,
+ lib->scheduler->schedule_job(lib->scheduler,
(job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE),
lifetime - reduction);
}
@@ -1718,10 +1717,65 @@ METHOD(ike_sa_t, set_auth_lifetime, void,
}
}
+/**
+ * Check if the current combination of source and destination address is still
+ * valid.
+ */
+static bool is_current_path_valid(private_ike_sa_t *this)
+{
+ bool valid = FALSE;
+ host_t *src;
+ src = hydra->kernel_interface->get_source_addr(hydra->kernel_interface,
+ this->other_host, this->my_host);
+ if (src)
+ {
+ if (src->ip_equals(src, this->my_host))
+ {
+ valid = TRUE;
+ }
+ src->destroy(src);
+ }
+ return valid;
+}
+
+/**
+ * Check if we have any path avialable for this IKE SA.
+ */
+static bool is_any_path_valid(private_ike_sa_t *this)
+{
+ bool valid = FALSE;
+ enumerator_t *enumerator;
+ host_t *src, *addr;
+ DBG1(DBG_IKE, "old path is not available anymore, try to find another");
+ src = hydra->kernel_interface->get_source_addr(hydra->kernel_interface,
+ this->other_host, NULL);
+ if (!src)
+ {
+ enumerator = this->additional_addresses->create_enumerator(
+ this->additional_addresses);
+ while (enumerator->enumerate(enumerator, &addr))
+ {
+ DBG1(DBG_IKE, "looking for a route to %H ...", addr);
+ src = hydra->kernel_interface->get_source_addr(
+ hydra->kernel_interface, addr, NULL);
+ if (src)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ if (src)
+ {
+ valid = TRUE;
+ src->destroy(src);
+ }
+ return valid;
+}
+
METHOD(ike_sa_t, roam, status_t,
private_ike_sa_t *this, bool address)
{
- host_t *src;
ike_mobike_t *mobike;
switch (this->state)
@@ -1734,81 +1788,61 @@ METHOD(ike_sa_t, roam, status_t,
default:
break;
}
- /* responder just updates the peer about changed address config */
- if (!this->ike_sa_id->is_initiator(this->ike_sa_id))
+
+ /* keep existing path if possible */
+ if (is_current_path_valid(this))
{
+ DBG2(DBG_IKE, "keeping connection path %H - %H",
+ this->my_host, this->other_host);
+ set_condition(this, COND_STALE, FALSE);
+
if (supports_extension(this, EXT_MOBIKE) && address)
- {
+ { /* if any addresses changed, send an updated list */
DBG1(DBG_IKE, "sending address list update using MOBIKE");
mobike = ike_mobike_create(&this->public, TRUE);
- this->task_manager->queue_task(this->task_manager, (task_t*)mobike);
+ mobike->addresses(mobike);
+ this->task_manager->queue_task(this->task_manager,
+ (task_t*)mobike);
return this->task_manager->initiate(this->task_manager);
}
return SUCCESS;
}
- /* keep existing path if possible */
- src = charon->kernel_interface->get_source_addr(charon->kernel_interface,
- this->other_host, this->my_host);
- if (src)
+ if (!is_any_path_valid(this))
{
- if (src->ip_equals(src, this->my_host))
- {
- DBG2(DBG_IKE, "keeping connection path %H - %H",
- src, this->other_host);
- src->destroy(src);
- set_condition(this, COND_STALE, FALSE);
- return SUCCESS;
- }
- src->destroy(src);
-
- }
- else
- {
- /* check if we find a route at all */
- enumerator_t *enumerator;
- host_t *addr;
-
- src = charon->kernel_interface->get_source_addr(charon->kernel_interface,
- this->other_host, NULL);
- if (!src)
- {
- enumerator = this->additional_addresses->create_enumerator(
- this->additional_addresses);
- while (enumerator->enumerate(enumerator, &addr))
- {
- DBG1(DBG_IKE, "looking for a route to %H ...", addr);
- src = charon->kernel_interface->get_source_addr(
- charon->kernel_interface, addr, NULL);
- if (src)
- {
- break;
- }
- }
- enumerator->destroy(enumerator);
- }
- if (!src)
- {
- DBG1(DBG_IKE, "no route found to reach %H, MOBIKE update deferred",
- this->other_host);
- set_condition(this, COND_STALE, TRUE);
- return SUCCESS;
- }
- src->destroy(src);
+ DBG1(DBG_IKE, "no route found to reach %H, MOBIKE update deferred",
+ this->other_host);
+ set_condition(this, COND_STALE, TRUE);
+ return SUCCESS;
}
set_condition(this, COND_STALE, FALSE);
/* update addresses with mobike, if supported ... */
if (supports_extension(this, EXT_MOBIKE))
{
- DBG1(DBG_IKE, "requesting address change using MOBIKE");
+ if (!has_condition(this, COND_ORIGINAL_INITIATOR))
+ { /* responder updates the peer about changed address config */
+ DBG1(DBG_IKE, "sending address list update using MOBIKE, "
+ "implicitly requesting an address change");
+ address = TRUE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "requesting address change using MOBIKE");
+ }
mobike = ike_mobike_create(&this->public, TRUE);
mobike->roam(mobike, address);
this->task_manager->queue_task(this->task_manager, (task_t*)mobike);
return this->task_manager->initiate(this->task_manager);
}
- DBG1(DBG_IKE, "reauthenticating IKE_SA due to address change");
+
/* ... reauth if not */
+ if (!has_condition(this, COND_ORIGINAL_INITIATOR))
+ { /* responder does not reauthenticate */
+ set_condition(this, COND_STALE, TRUE);
+ return SUCCESS;
+ }
+ DBG1(DBG_IKE, "reauthenticating IKE_SA due to address change");
return reauth(this);
}
@@ -1907,9 +1941,9 @@ METHOD(ike_sa_t, inherit, status_t,
this->stats[STAT_DELETE] = this->stats[STAT_REAUTH] + delete;
DBG1(DBG_IKE, "rescheduling reauthentication in %ds after rekeying, "
"lifetime reduced to %ds", reauth, delete);
- charon->scheduler->schedule_job(charon->scheduler,
+ lib->scheduler->schedule_job(lib->scheduler,
(job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), reauth);
- charon->scheduler->schedule_job(charon->scheduler,
+ lib->scheduler->schedule_job(lib->scheduler,
(job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE), delete);
}
/* we have to initate here, there may be new tasks to handle */
@@ -1946,8 +1980,8 @@ METHOD(ike_sa_t, destroy, void,
if (this->my_virtual_ip)
{
- charon->kernel_interface->del_ip(charon->kernel_interface,
- this->my_virtual_ip);
+ hydra->kernel_interface->del_ip(hydra->kernel_interface,
+ this->my_virtual_ip);
this->my_virtual_ip->destroy(this->my_virtual_ip);
}
if (this->other_virtual_ip)
@@ -2025,6 +2059,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
.get_other_host = _get_other_host,
.set_other_host = _set_other_host,
.set_message_id = _set_message_id,
+ .float_ports = _float_ports,
.update_hosts = _update_hosts,
.get_my_id = _get_my_id,
.set_my_id = _set_my_id,
diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h
index 34842a573..c0007e27d 100644
--- a/src/libcharon/sa/ike_sa.h
+++ b/src/libcharon/sa/ike_sa.h
@@ -329,6 +329,14 @@ struct ike_sa_t {
void (*set_other_host) (ike_sa_t *this, host_t *other);
/**
+ * Float to port 4500 (e.g. if a NAT is detected).
+ *
+ * The port of either endpoint is changed only if it is currently
+ * set to the default value of 500.
+ */
+ void (*float_ports)(ike_sa_t *this);
+
+ /**
* Update the IKE_SAs host.
*
* Hosts may be NULL to use current host.
diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index c71c3b297..fa94bb86d 100644
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -1613,6 +1613,9 @@ static void flush(private_ike_sa_manager_t *this)
enumerator->destroy(enumerator);
charon->bus->set_sa(charon->bus, NULL);
unlock_all_segments(this);
+
+ this->rng->destroy(this->rng);
+ this->hasher->destroy(this->hasher);
}
/**
@@ -1652,8 +1655,6 @@ static void destroy(private_ike_sa_manager_t *this)
free(this->half_open_segments);
free(this->connected_peers_segments);
- this->rng->destroy(this->rng);
- this->hasher->destroy(this->hasher);
free(this);
}
diff --git a/src/libcharon/sa/ike_sa_manager.h b/src/libcharon/sa/ike_sa_manager.h
index 38f5454e1..f4eabf808 100644
--- a/src/libcharon/sa/ike_sa_manager.h
+++ b/src/libcharon/sa/ike_sa_manager.h
@@ -199,6 +199,8 @@ struct ike_sa_manager_t {
* Delete all existing IKE_SAs and destroy them immediately.
*
* Threads will be driven out, so all SAs can be deleted cleanly.
+ * To a flush(), an immediate call to destroy() is mandatory; no other
+ * method may be used.
*/
void (*flush)(ike_sa_manager_t *this);
diff --git a/src/libcharon/sa/keymat.c b/src/libcharon/sa/keymat.c
index 837cbe428..878ad124f 100644
--- a/src/libcharon/sa/keymat.c
+++ b/src/libcharon/sa/keymat.c
@@ -36,24 +36,14 @@ struct private_keymat_t {
bool initiator;
/**
- * inbound signer (verify)
+ * inbound AEAD
*/
- signer_t *signer_in;
+ aead_t *aead_in;
/**
- * outbound signer (sign)
+ * outbound AEAD
*/
- signer_t *signer_out;
-
- /**
- * inbound crypter (decrypt)
- */
- crypter_t *crypter_in;
-
- /**
- * outbound crypter (encrypt)
- */
- crypter_t *crypter_out;
+ aead_t *aead_out;
/**
* General purpose PRF
@@ -134,30 +124,135 @@ static int lookup_keylen(keylen_entry_t *list, int algo)
return 0;
}
+METHOD(keymat_t, create_dh, diffie_hellman_t*,
+ private_keymat_t *this, diffie_hellman_group_t group)
+{
+ return lib->crypto->create_dh(lib->crypto, group);;
+}
+
/**
- * Implementation of keymat_t.create_dh
+ * Derive IKE keys for a combined AEAD algorithm
*/
-static diffie_hellman_t* create_dh(private_keymat_t *this,
- diffie_hellman_group_t group)
+static bool derive_ike_aead(private_keymat_t *this, u_int16_t alg,
+ u_int16_t key_size, prf_plus_t *prf_plus)
{
- return lib->crypto->create_dh(lib->crypto, group);;
+ aead_t *aead_i, *aead_r;
+ chunk_t key;
+
+ /* SK_ei/SK_er used for encryption */
+ aead_i = lib->crypto->create_aead(lib->crypto, alg, key_size / 8);
+ aead_r = lib->crypto->create_aead(lib->crypto, alg, key_size / 8);
+ if (aead_i == NULL || aead_r == NULL)
+ {
+ DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
+ transform_type_names, ENCRYPTION_ALGORITHM,
+ encryption_algorithm_names, alg, key_size);
+ return FALSE;
+ }
+ key_size = aead_i->get_key_size(aead_i);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_ei secret %B", &key);
+ aead_i->set_key(aead_i, key);
+ chunk_clear(&key);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_er secret %B", &key);
+ aead_r->set_key(aead_r, key);
+ chunk_clear(&key);
+
+ if (this->initiator)
+ {
+ this->aead_in = aead_r;
+ this->aead_out = aead_i;
+ }
+ else
+ {
+ this->aead_in = aead_i;
+ this->aead_out = aead_r;
+ }
+ return TRUE;
}
/**
- * Implementation of keymat_t.derive_keys
+ * Derive IKE keys for traditional encryption and MAC algorithms
*/
-static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal,
- diffie_hellman_t *dh, chunk_t nonce_i,
- chunk_t nonce_r, ike_sa_id_t *id,
- pseudo_random_function_t rekey_function,
- chunk_t rekey_skd)
+static bool derive_ike_traditional(private_keymat_t *this, u_int16_t enc_alg,
+ u_int16_t enc_size, u_int16_t int_alg, prf_plus_t *prf_plus)
{
- chunk_t skeyseed, key, secret, full_nonce, fixed_nonce, prf_plus_seed;
- chunk_t spi_i, spi_r;
crypter_t *crypter_i, *crypter_r;
signer_t *signer_i, *signer_r;
+ size_t key_size;
+ chunk_t key;
+
+ /* SK_ai/SK_ar used for integrity protection */
+ signer_i = lib->crypto->create_signer(lib->crypto, int_alg);
+ signer_r = lib->crypto->create_signer(lib->crypto, int_alg);
+ if (signer_i == NULL || signer_r == NULL)
+ {
+ DBG1(DBG_IKE, "%N %N not supported!",
+ transform_type_names, INTEGRITY_ALGORITHM,
+ integrity_algorithm_names, int_alg);
+ return FALSE;
+ }
+ key_size = signer_i->get_key_size(signer_i);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_ai secret %B", &key);
+ signer_i->set_key(signer_i, key);
+ chunk_clear(&key);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_ar secret %B", &key);
+ signer_r->set_key(signer_r, key);
+ chunk_clear(&key);
+
+ /* SK_ei/SK_er used for encryption */
+ crypter_i = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8);
+ crypter_r = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8);
+ if (crypter_i == NULL || crypter_r == NULL)
+ {
+ DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
+ transform_type_names, ENCRYPTION_ALGORITHM,
+ encryption_algorithm_names, enc_alg, key_size);
+ signer_i->destroy(signer_i);
+ signer_r->destroy(signer_r);
+ return FALSE;
+ }
+ key_size = crypter_i->get_key_size(crypter_i);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_ei secret %B", &key);
+ crypter_i->set_key(crypter_i, key);
+ chunk_clear(&key);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_er secret %B", &key);
+ crypter_r->set_key(crypter_r, key);
+ chunk_clear(&key);
+
+ if (this->initiator)
+ {
+ this->aead_in = aead_create(crypter_r, signer_r);
+ this->aead_out = aead_create(crypter_i, signer_i);
+ }
+ else
+ {
+ this->aead_in = aead_create(crypter_i, signer_i);
+ this->aead_out = aead_create(crypter_r, signer_r);
+ }
+ return TRUE;
+}
+
+METHOD(keymat_t, derive_ike_keys, bool,
+ private_keymat_t *this, proposal_t *proposal, diffie_hellman_t *dh,
+ chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
+ pseudo_random_function_t rekey_function, chunk_t rekey_skd)
+{
+ chunk_t skeyseed, key, secret, full_nonce, fixed_nonce, prf_plus_seed;
+ chunk_t spi_i, spi_r;
prf_plus_t *prf_plus;
- u_int16_t alg, key_size;
+ u_int16_t alg, key_size, int_alg;
prf_t *rekey_prf = NULL;
spi_i = chunk_alloca(sizeof(u_int64_t));
@@ -195,6 +290,9 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal,
/* while rfc4434 defines variable keys for AES-XCBC, rfc3664 does
* not and therefore fixed key semantics apply to XCBC for key
* derivation. */
+ case PRF_CAMELLIA128_XCBC:
+ /* draft-kanno-ipsecme-camellia-xcbc refers to rfc 4434, we
+ * assume fixed key length. */
key_size = this->prf->get_key_size(this->prf)/2;
nonce_i.len = min(nonce_i.len, key_size);
nonce_r.len = min(nonce_r.len, key_size);
@@ -255,50 +353,6 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal,
prf_plus->allocate_bytes(prf_plus, key_size, &this->skd);
DBG4(DBG_IKE, "Sk_d secret %B", &this->skd);
- /* SK_ai/SK_ar used for integrity protection => signer_in/signer_out */
- if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL))
- {
- DBG1(DBG_IKE, "no %N selected",
- transform_type_names, INTEGRITY_ALGORITHM);
- prf_plus->destroy(prf_plus);
- DESTROY_IF(rekey_prf);
- return FALSE;
- }
- signer_i = lib->crypto->create_signer(lib->crypto, alg);
- signer_r = lib->crypto->create_signer(lib->crypto, alg);
- if (signer_i == NULL || signer_r == NULL)
- {
- DBG1(DBG_IKE, "%N %N not supported!",
- transform_type_names, INTEGRITY_ALGORITHM,
- integrity_algorithm_names ,alg);
- prf_plus->destroy(prf_plus);
- DESTROY_IF(rekey_prf);
- return FALSE;
- }
- key_size = signer_i->get_key_size(signer_i);
-
- prf_plus->allocate_bytes(prf_plus, key_size, &key);
- DBG4(DBG_IKE, "Sk_ai secret %B", &key);
- signer_i->set_key(signer_i, key);
- chunk_clear(&key);
-
- prf_plus->allocate_bytes(prf_plus, key_size, &key);
- DBG4(DBG_IKE, "Sk_ar secret %B", &key);
- signer_r->set_key(signer_r, key);
- chunk_clear(&key);
-
- if (this->initiator)
- {
- this->signer_in = signer_r;
- this->signer_out = signer_i;
- }
- else
- {
- this->signer_in = signer_i;
- this->signer_out = signer_r;
- }
-
- /* SK_ei/SK_er used for encryption => crypter_in/crypter_out */
if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &key_size))
{
DBG1(DBG_IKE, "no %N selected",
@@ -307,38 +361,33 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal,
DESTROY_IF(rekey_prf);
return FALSE;
}
- crypter_i = lib->crypto->create_crypter(lib->crypto, alg, key_size / 8);
- crypter_r = lib->crypto->create_crypter(lib->crypto, alg, key_size / 8);
- if (crypter_i == NULL || crypter_r == NULL)
- {
- DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
- transform_type_names, ENCRYPTION_ALGORITHM,
- encryption_algorithm_names, alg, key_size);
- prf_plus->destroy(prf_plus);
- DESTROY_IF(rekey_prf);
- return FALSE;
- }
- key_size = crypter_i->get_key_size(crypter_i);
- prf_plus->allocate_bytes(prf_plus, key_size, &key);
- DBG4(DBG_IKE, "Sk_ei secret %B", &key);
- crypter_i->set_key(crypter_i, key);
- chunk_clear(&key);
-
- prf_plus->allocate_bytes(prf_plus, key_size, &key);
- DBG4(DBG_IKE, "Sk_er secret %B", &key);
- crypter_r->set_key(crypter_r, key);
- chunk_clear(&key);
-
- if (this->initiator)
+ if (encryption_algorithm_is_aead(alg))
{
- this->crypter_in = crypter_r;
- this->crypter_out = crypter_i;
+ if (!derive_ike_aead(this, alg, key_size, prf_plus))
+ {
+ prf_plus->destroy(prf_plus);
+ DESTROY_IF(rekey_prf);
+ return FALSE;
+ }
}
else
{
- this->crypter_in = crypter_i;
- this->crypter_out = crypter_r;
+ if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
+ &int_alg, NULL))
+ {
+ DBG1(DBG_IKE, "no %N selected",
+ transform_type_names, INTEGRITY_ALGORITHM);
+ prf_plus->destroy(prf_plus);
+ DESTROY_IF(rekey_prf);
+ return FALSE;
+ }
+ if (!derive_ike_traditional(this, alg, key_size, int_alg, prf_plus))
+ {
+ prf_plus->destroy(prf_plus);
+ DESTROY_IF(rekey_prf);
+ return FALSE;
+ }
}
/* SK_pi/SK_pr used for authentication => stored for later */
@@ -371,14 +420,10 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal,
return TRUE;
}
-/**
- * Implementation of keymat_t.derive_child_keys
- */
-static bool derive_child_keys(private_keymat_t *this,
- proposal_t *proposal, diffie_hellman_t *dh,
- chunk_t nonce_i, chunk_t nonce_r,
- chunk_t *encr_i, chunk_t *integ_i,
- chunk_t *encr_r, chunk_t *integ_r)
+METHOD(keymat_t, derive_child_keys, bool,
+ private_keymat_t *this, proposal_t *proposal, diffie_hellman_t *dh,
+ chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i,
+ chunk_t *encr_r, chunk_t *integ_r)
{
u_int16_t enc_alg, int_alg, enc_size = 0, int_size = 0;
chunk_t seed, secret = chunk_empty;
@@ -480,37 +525,22 @@ static bool derive_child_keys(private_keymat_t *this,
return TRUE;
}
-/**
- * Implementation of keymat_t.get_skd
- */
-static pseudo_random_function_t get_skd(private_keymat_t *this, chunk_t *skd)
+METHOD(keymat_t, get_skd, pseudo_random_function_t,
+ private_keymat_t *this, chunk_t *skd)
{
*skd = this->skd;
return this->prf_alg;
}
-/**
- * Implementation of keymat_t.get_signer
- */
-static signer_t* get_signer(private_keymat_t *this, bool in)
-{
- return in ? this->signer_in : this->signer_out;
-}
-
-/**
- * Implementation of keymat_t.get_crypter
- */
-static crypter_t* get_crypter(private_keymat_t *this, bool in)
+METHOD(keymat_t, get_aead, aead_t*,
+ private_keymat_t *this, bool in)
{
- return in ? this->crypter_in : this->crypter_out;
+ return in ? this->aead_in : this->aead_out;
}
-/**
- * Implementation of keymat_t.get_auth_octets
- */
-static chunk_t get_auth_octets(private_keymat_t *this, bool verify,
- chunk_t ike_sa_init, chunk_t nonce,
- identification_t *id)
+METHOD(keymat_t, get_auth_octets, chunk_t,
+ private_keymat_t *this, bool verify, chunk_t ike_sa_init,
+ chunk_t nonce, identification_t *id)
{
chunk_t chunk, idx, octets;
chunk_t skp;
@@ -538,12 +568,9 @@ static chunk_t get_auth_octets(private_keymat_t *this, bool verify,
#define IKEV2_KEY_PAD "Key Pad for IKEv2"
#define IKEV2_KEY_PAD_LENGTH 17
-/**
- * Implementation of keymat_t.get_psk_sig
- */
-static chunk_t get_psk_sig(private_keymat_t *this, bool verify,
- chunk_t ike_sa_init, chunk_t nonce, chunk_t secret,
- identification_t *id)
+METHOD(keymat_t, get_psk_sig, chunk_t,
+ private_keymat_t *this, bool verify, chunk_t ike_sa_init,
+ chunk_t nonce, chunk_t secret, identification_t *id)
{
chunk_t key_pad, key, sig, octets;
@@ -567,15 +594,11 @@ static chunk_t get_psk_sig(private_keymat_t *this, bool verify,
return sig;
}
-/**
- * Implementation of keymat_t.destroy.
- */
-static void destroy(private_keymat_t *this)
+METHOD(keymat_t, destroy, void,
+ private_keymat_t *this)
{
- DESTROY_IF(this->signer_in);
- DESTROY_IF(this->signer_out);
- DESTROY_IF(this->crypter_in);
- DESTROY_IF(this->crypter_out);
+ DESTROY_IF(this->aead_in);
+ DESTROY_IF(this->aead_out);
DESTROY_IF(this->prf);
chunk_clear(&this->skd);
chunk_clear(&this->skp_verify);
@@ -588,29 +611,22 @@ static void destroy(private_keymat_t *this)
*/
keymat_t *keymat_create(bool initiator)
{
- private_keymat_t *this = malloc_thing(private_keymat_t);
-
- this->public.create_dh = (diffie_hellman_t*(*)(keymat_t*, diffie_hellman_group_t group))create_dh;
- this->public.derive_ike_keys = (bool(*)(keymat_t*, proposal_t *proposal, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id, pseudo_random_function_t,chunk_t))derive_ike_keys;
- this->public.derive_child_keys = (bool(*)(keymat_t*, proposal_t *proposal, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r))derive_child_keys;
- this->public.get_skd = (pseudo_random_function_t(*)(keymat_t*, chunk_t *skd))get_skd;
- this->public.get_signer = (signer_t*(*)(keymat_t*, bool in))get_signer;
- this->public.get_crypter = (crypter_t*(*)(keymat_t*, bool in))get_crypter;
- this->public.get_auth_octets = (chunk_t(*)(keymat_t *, bool verify, chunk_t ike_sa_init, chunk_t nonce, identification_t *id))get_auth_octets;
- this->public.get_psk_sig = (chunk_t(*)(keymat_t*, bool verify, chunk_t ike_sa_init, chunk_t nonce, chunk_t secret, identification_t *id))get_psk_sig;
- this->public.destroy = (void(*)(keymat_t*))destroy;
-
- this->initiator = initiator;
-
- this->signer_in = NULL;
- this->signer_out = NULL;
- this->crypter_in = NULL;
- this->crypter_out = NULL;
- this->prf = NULL;
- this->prf_alg = PRF_UNDEFINED;
- this->skd = chunk_empty;
- this->skp_verify = chunk_empty;
- this->skp_build = chunk_empty;
+ private_keymat_t *this;
+
+ INIT(this,
+ .public = {
+ .create_dh = _create_dh,
+ .derive_ike_keys = _derive_ike_keys,
+ .derive_child_keys = _derive_child_keys,
+ .get_skd = _get_skd,
+ .get_aead = _get_aead,
+ .get_auth_octets = _get_auth_octets,
+ .get_psk_sig = _get_psk_sig,
+ .destroy = _destroy,
+ },
+ .initiator = initiator,
+ .prf_alg = PRF_UNDEFINED,
+ );
return &this->public;
}
diff --git a/src/libcharon/sa/keymat.h b/src/libcharon/sa/keymat.h
index e51709e8d..4f01aa411 100644
--- a/src/libcharon/sa/keymat.h
+++ b/src/libcharon/sa/keymat.h
@@ -24,8 +24,7 @@
#include <library.h>
#include <utils/identification.h>
#include <crypto/prfs/prf.h>
-#include <crypto/crypters/crypter.h>
-#include <crypto/signers/signer.h>
+#include <crypto/aead.h>
#include <config/proposal.h>
#include <sa/ike_sa_id.h>
@@ -99,21 +98,13 @@ struct keymat_t {
*/
pseudo_random_function_t (*get_skd)(keymat_t *this, chunk_t *skd);
- /**
- * Get a signer to sign/verify IKE messages.
- *
- * @param in TRUE for inbound (verify), FALSE for outbound (sign)
- * @return signer
- */
- signer_t* (*get_signer)(keymat_t *this, bool in);
-
/*
- * Get a crypter to en-/decrypt IKE messages.
+ * Get a AEAD transform to en-/decrypt and sign/verify IKE messages.
*
* @param in TRUE for inbound (decrypt), FALSE for outbound (encrypt)
* @return crypter
*/
- crypter_t* (*get_crypter)(keymat_t *this, bool in);
+ aead_t* (*get_aead)(keymat_t *this, bool in);
/**
* Generate octets to use for authentication procedure (RFC4306 2.15).
diff --git a/src/libcharon/sa/mediation_manager.c b/src/libcharon/sa/mediation_manager.c
index 035f49053..2fbab7c7c 100644
--- a/src/libcharon/sa/mediation_manager.c
+++ b/src/libcharon/sa/mediation_manager.c
@@ -241,7 +241,7 @@ static void update_sa_id(private_mediation_manager_t *this, identification_t *pe
(void**)&requester) == SUCCESS)
{
job_t *job = (job_t*)mediation_callback_job_create(requester, peer_id);
- charon->processor->queue_job(charon->processor, job);
+ lib->processor->queue_job(lib->processor, job);
requester->destroy(requester);
}
diff --git a/src/libcharon/sa/task_manager.c b/src/libcharon/sa/task_manager.c
index a68826440..18703ce36 100644
--- a/src/libcharon/sa/task_manager.c
+++ b/src/libcharon/sa/task_manager.c
@@ -274,7 +274,7 @@ METHOD(task_manager_t, retransmit, status_t,
this->initiating.retransmitted++;
job = (job_t*)retransmit_job_create(this->initiating.mid,
this->ike_sa->get_id(this->ike_sa));
- charon->scheduler->schedule_job_ms(charon->scheduler, job, timeout);
+ lib->scheduler->schedule_job_ms(lib->scheduler, job, timeout);
}
return SUCCESS;
}
@@ -883,11 +883,21 @@ METHOD(task_manager_t, process_message, status_t,
private_task_manager_t *this, message_t *msg)
{
u_int32_t mid = msg->get_message_id(msg);
+ host_t *me = msg->get_destination(msg), *other = msg->get_source(msg);
if (msg->get_request(msg))
{
if (mid == this->responding.mid)
{
+ if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
+ this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
+ msg->get_exchange_type(msg) != IKE_SA_INIT)
+ { /* only do host updates based on verified messages */
+ if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
+ { /* with MOBIKE, we do no implicit updates */
+ this->ike_sa->update_hosts(this->ike_sa, me, other);
+ }
+ }
charon->bus->message(charon->bus, msg, TRUE);
if (process_request(this, msg) != SUCCESS)
{
@@ -920,6 +930,15 @@ METHOD(task_manager_t, process_message, status_t,
{
if (mid == this->initiating.mid)
{
+ if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
+ this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
+ msg->get_exchange_type(msg) != IKE_SA_INIT)
+ { /* only do host updates based on verified messages */
+ if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
+ { /* with MOBIKE, we do no implicit updates */
+ this->ike_sa->update_hosts(this->ike_sa, me, other);
+ }
+ }
charon->bus->message(charon->bus, msg, TRUE);
if (process_response(this, msg) != SUCCESS)
{
diff --git a/src/libcharon/sa/tasks/child_create.c b/src/libcharon/sa/tasks/child_create.c
index 3de27ee3f..57beedba9 100644
--- a/src/libcharon/sa/tasks/child_create.c
+++ b/src/libcharon/sa/tasks/child_create.c
@@ -261,7 +261,7 @@ static void schedule_inactivity_timeout(private_child_create_t *this)
{
close_ike = lib->settings->get_bool(lib->settings,
"charon.inactivity_close_ike", FALSE);
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)
+ lib->scheduler->schedule_job(lib->scheduler, (job_t*)
inactivity_job_create(this->child_sa->get_reqid(this->child_sa),
timeout, close_ike), timeout);
}
@@ -871,7 +871,7 @@ static void handle_child_sa_failure(private_child_create_t *this,
/* we delay the delete for 100ms, as the IKE_AUTH response must arrive
* first */
DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure");
- charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*)
+ lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)
delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE),
100);
}
diff --git a/src/libcharon/sa/tasks/child_delete.c b/src/libcharon/sa/tasks/child_delete.c
index b0cd30e1e..45e97e4cd 100644
--- a/src/libcharon/sa/tasks/child_delete.c
+++ b/src/libcharon/sa/tasks/child_delete.c
@@ -117,11 +117,10 @@ static void build_payloads(private_child_delete_t *this, message_t *message)
*/
static void process_payloads(private_child_delete_t *this, message_t *message)
{
- enumerator_t *payloads;
- iterator_t *spis;
+ enumerator_t *payloads, *spis;
payload_t *payload;
delete_payload_t *delete_payload;
- u_int32_t *spi;
+ u_int32_t spi;
protocol_id_t protocol;
child_sa_t *child_sa;
@@ -136,19 +135,19 @@ static void process_payloads(private_child_delete_t *this, message_t *message)
{
continue;
}
- spis = delete_payload->create_spi_iterator(delete_payload);
- while (spis->iterate(spis, (void**)&spi))
+ spis = delete_payload->create_spi_enumerator(delete_payload);
+ while (spis->enumerate(spis, &spi))
{
child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol,
- *spi, FALSE);
+ spi, FALSE);
if (child_sa == NULL)
{
DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x, "
- "but no such SA", protocol_id_names, protocol, ntohl(*spi));
+ "but no such SA", protocol_id_names, protocol, ntohl(spi));
continue;
}
DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x",
- protocol_id_names, protocol, ntohl(*spi));
+ protocol_id_names, protocol, ntohl(spi));
switch (child_sa->get_state(child_sa))
{
@@ -161,7 +160,7 @@ static void process_payloads(private_child_delete_t *this, message_t *message)
if (!this->initiator)
{
this->ike_sa->destroy_child_sa(this->ike_sa,
- protocol, *spi);
+ protocol, spi);
continue;
}
case CHILD_INSTALLED:
diff --git a/src/libcharon/sa/tasks/child_rekey.c b/src/libcharon/sa/tasks/child_rekey.c
index fb3452efd..fdaaea4b8 100644
--- a/src/libcharon/sa/tasks/child_rekey.c
+++ b/src/libcharon/sa/tasks/child_rekey.c
@@ -75,6 +75,15 @@ struct private_child_rekey_t {
* colliding task, may be delete or rekey
*/
task_t *collision;
+
+ /**
+ * Indicate that peer destroyed the redundant child from collision.
+ * This happens if a peer's delete notification for the redundant
+ * child gets processed before the rekey job. If so, we must not
+ * touch the child created in the collision since it points to
+ * memory already freed.
+ */
+ bool other_child_destroyed;
};
/**
@@ -239,9 +248,13 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
DBG1(DBG_IKE, "CHILD_SA rekey collision won, "
"deleting rekeyed child");
to_delete = this->child_sa;
- /* disable close action for the redundand child */
- child_sa = other->child_create->get_child(other->child_create);
- child_sa->set_close_action(child_sa, ACTION_NONE);
+ /* don't touch child other created, it has already been deleted */
+ if (!this->other_child_destroyed)
+ {
+ /* disable close action for the redundand child */
+ child_sa = other->child_create->get_child(other->child_create);
+ child_sa->set_close_action(child_sa, ACTION_NONE);
+ }
}
else
{
@@ -286,7 +299,7 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
DBG1(DBG_IKE, "peer seems to not support CHILD_SA rekeying, "
"starting reauthentication");
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
- charon->processor->queue_job(charon->processor,
+ lib->processor->queue_job(lib->processor,
(job_t*)rekey_ike_sa_job_create(
this->ike_sa->get_id(this->ike_sa), TRUE));
return SUCCESS;
@@ -316,7 +329,7 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
DBG1(DBG_IKE, "CHILD_SA rekeying failed, "
"trying again in %d seconds", retry);
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
- charon->scheduler->schedule_job(charon->scheduler, job, retry);
+ lib->scheduler->schedule_job(lib->scheduler, job, retry);
}
return SUCCESS;
}
@@ -380,6 +393,13 @@ static void collide(private_child_rekey_t *this, task_t *other)
else if (other->get_type(other) == CHILD_DELETE)
{
child_delete_t *del = (child_delete_t*)other;
+ if (del->get_child(del) == this->child_create->get_child(this->child_create))
+ {
+ /* peer deletes redundant child created in collision */
+ this->other_child_destroyed = TRUE;
+ other->destroy(other);
+ return;
+ }
if (del == NULL || del->get_child(del) != this->child_sa)
{
/* not the same child => no collision */
@@ -466,6 +486,7 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol,
this->spi = spi;
this->collision = NULL;
this->child_delete = NULL;
+ this->other_child_destroyed = FALSE;
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_auth.c b/src/libcharon/sa/tasks/ike_auth.c
index a954782f2..b440ec811 100644
--- a/src/libcharon/sa/tasks/ike_auth.c
+++ b/src/libcharon/sa/tasks/ike_auth.c
@@ -481,9 +481,8 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
{
this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
}
- if (this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN) &&
- message->get_notify(message, EAP_ONLY_AUTHENTICATION))
- { /* EAP-only has no official notify, accept only from strongSwan */
+ if (message->get_notify(message, EAP_ONLY_AUTHENTICATION))
+ {
this->ike_sa->enable_extension(this->ike_sa,
EXT_EAP_ONLY_AUTHENTICATION);
}
@@ -538,6 +537,11 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
{
cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, id->clone(id));
}
+ id = (identification_t*)cand->get(cand, AUTH_RULE_AAA_IDENTITY);
+ if (id)
+ {
+ cfg->add(cfg, AUTH_RULE_AAA_IDENTITY, id->clone(id));
+ }
}
/* verify authentication data */
@@ -821,7 +825,7 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
break;
default:
{
- if (type < 16383)
+ if (type <= 16383)
{
DBG1(DBG_IKE, "received %N notify error",
notify_type_names, type);
diff --git a/src/libcharon/sa/tasks/ike_init.c b/src/libcharon/sa/tasks/ike_init.c
index 38fb572f4..dd4a5f5c0 100644
--- a/src/libcharon/sa/tasks/ike_init.c
+++ b/src/libcharon/sa/tasks/ike_init.c
@@ -468,7 +468,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
}
default:
{
- if (type < 16383)
+ if (type <= 16383)
{
DBG1(DBG_IKE, "received %N notify error",
notify_type_names, type);
diff --git a/src/libcharon/sa/tasks/ike_me.c b/src/libcharon/sa/tasks/ike_me.c
index 2d2847ae0..1de6ae8fc 100644
--- a/src/libcharon/sa/tasks/ike_me.c
+++ b/src/libcharon/sa/tasks/ike_me.c
@@ -17,6 +17,7 @@
#include <string.h>
+#include <hydra.h>
#include <daemon.h>
#include <config/peer_cfg.h>
#include <encoding/payloads/id_payload.h>
@@ -134,8 +135,8 @@ static void gather_and_add_endpoints(private_ike_me_t *this, message_t *message)
host = this->ike_sa->get_my_host(this->ike_sa);
port = host->get_port(host);
- enumerator = charon->kernel_interface->create_address_enumerator(
- charon->kernel_interface, FALSE, FALSE);
+ enumerator = hydra->kernel_interface->create_address_enumerator(
+ hydra->kernel_interface, FALSE, FALSE);
while (enumerator->enumerate(enumerator, (void**)&addr))
{
host = addr->clone(addr);
@@ -454,6 +455,9 @@ static status_t process_i(private_ike_me_t *this, message_t *message)
DBG1(DBG_IKE, "server did not return a ME_MEDIATION, aborting");
return FAILED;
}
+ /* if we are on a mediation connection we switch to port 4500 even
+ * if no NAT is detected. */
+ this->ike_sa->float_ports(this->ike_sa);
return NEED_MORE;
}
case IKE_AUTH:
@@ -689,7 +693,7 @@ static status_t build_r_ms(private_ike_me_t *this, message_t *message)
job_t *job = (job_t*)mediation_job_create(this->peer_id,
this->ike_sa->get_other_id(this->ike_sa), this->connect_id,
this->connect_key, this->remote_endpoints, this->response);
- charon->processor->queue_job(charon->processor, job);
+ lib->processor->queue_job(lib->processor, job);
break;
}
default:
diff --git a/src/libcharon/sa/tasks/ike_mobike.c b/src/libcharon/sa/tasks/ike_mobike.c
index a62886f02..5b12eaaac 100644
--- a/src/libcharon/sa/tasks/ike_mobike.c
+++ b/src/libcharon/sa/tasks/ike_mobike.c
@@ -17,6 +17,7 @@
#include <string.h>
+#include <hydra.h>
#include <daemon.h>
#include <sa/tasks/ike_natd.h>
#include <encoding/payloads/notify_payload.h>
@@ -70,6 +71,11 @@ struct private_ike_mobike_t {
* include address list update
*/
bool address;
+
+ /**
+ * additional addresses got updated
+ */
+ bool addresses_updated;
};
/**
@@ -153,6 +159,7 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
host = host_create_from_chunk(family, data, 0);
DBG2(DBG_IKE, "got additional MOBIKE peer address: %H", host);
this->ike_sa->add_additional_address(this->ike_sa, host);
+ this->addresses_updated = TRUE;
break;
}
case UPDATE_SA_ADDRESSES:
@@ -163,6 +170,7 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
case NO_ADDITIONAL_ADDRESSES:
{
flush_additional_addresses(this);
+ this->addresses_updated = TRUE;
break;
}
case NAT_DETECTION_SOURCE_IP:
@@ -193,8 +201,8 @@ static void build_address_list(private_ike_mobike_t *this, message_t *message)
int added = 0;
me = this->ike_sa->get_my_host(this->ike_sa);
- enumerator = charon->kernel_interface->create_address_enumerator(
- charon->kernel_interface, FALSE, FALSE);
+ enumerator = hydra->kernel_interface->create_address_enumerator(
+ hydra->kernel_interface, FALSE, FALSE);
while (enumerator->enumerate(enumerator, (void**)&host))
{
if (me->ip_equals(me, host))
@@ -269,32 +277,23 @@ static void update_children(private_ike_mobike_t *this)
}
/**
- * Apply port of old address if it equals new, port otherwise
+ * Apply the port of the old host, if its ip equals the new, use port otherwise.
*/
-static void apply_port(private_ike_mobike_t *this, host_t *host, host_t *old,
- u_int16_t port)
+static void apply_port(host_t *host, host_t *old, u_int16_t port)
{
if (host->ip_equals(host, old))
{
- host->set_port(host, old->get_port(old));
+ port = old->get_port(old);
}
- else
+ else if (port == IKEV2_UDP_PORT)
{
- if (port == IKEV2_UDP_PORT)
- {
- host->set_port(host, IKEV2_NATT_PORT);
- }
- else
- {
- host->set_port(host, port);
- }
+ port = IKEV2_NATT_PORT;
}
+ host->set_port(host, port);
}
-/**
- * Implementation of ike_mobike_t.transmit
- */
-static void transmit(private_ike_mobike_t *this, packet_t *packet)
+METHOD(ike_mobike_t, transmit, void,
+ private_ike_mobike_t *this, packet_t *packet)
{
host_t *me, *other, *me_old, *other_old;
iterator_t *iterator;
@@ -310,11 +309,11 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
other_old = this->ike_sa->get_other_host(this->ike_sa);
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
- me = charon->kernel_interface->get_source_addr(
- charon->kernel_interface, other_old, NULL);
+ me = hydra->kernel_interface->get_source_addr(
+ hydra->kernel_interface, other_old, NULL);
if (me)
{
- apply_port(this, me, me_old, ike_cfg->get_my_port(ike_cfg));
+ apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg));
DBG1(DBG_IKE, "checking original path %#H - %#H", me, other_old);
copy = packet->clone(packet);
copy->set_source(copy, me);
@@ -324,8 +323,8 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
iterator = this->ike_sa->create_additional_address_iterator(this->ike_sa);
while (iterator->iterate(iterator, (void**)&other))
{
- me = charon->kernel_interface->get_source_addr(
- charon->kernel_interface, other, NULL);
+ me = hydra->kernel_interface->get_source_addr(
+ hydra->kernel_interface, other, NULL);
if (me)
{
if (me->get_family(me) != other->get_family(other))
@@ -334,9 +333,9 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
continue;
}
/* reuse port for an active address, 4500 otherwise */
- apply_port(this, me, me_old, ike_cfg->get_my_port(ike_cfg));
+ apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg));
other = other->clone(other);
- apply_port(this, other, other_old, ike_cfg->get_other_port(ike_cfg));
+ apply_port(other, other_old, ike_cfg->get_other_port(ike_cfg));
DBG1(DBG_IKE, "checking path %#H - %#H", me, other);
copy = packet->clone(packet);
copy->set_source(copy, me);
@@ -347,12 +346,11 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
iterator->destroy(iterator);
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t build_i(private_ike_mobike_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_mobike_t *this, message_t *message)
{
- if (message->get_message_id(message) == 1)
+ if (message->get_exchange_type(message) == IKE_AUTH &&
+ message->get_message_id(message) == 1)
{ /* only in first IKE_AUTH */
message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
build_address_list(this, message);
@@ -363,7 +361,7 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
/* we check if the existing address is still valid */
old = message->get_source(message);
- new = charon->kernel_interface->get_source_addr(charon->kernel_interface,
+ new = hydra->kernel_interface->get_source_addr(hydra->kernel_interface,
message->get_destination(message), old);
if (new)
{
@@ -379,11 +377,12 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
}
if (this->update)
{
- message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, chunk_empty);
+ message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES,
+ chunk_empty);
build_cookie(this, message);
update_children(this);
}
- if (this->address)
+ if (this->address && !this->check)
{
build_address_list(this, message);
}
@@ -395,12 +394,11 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_mobike_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_ike_mobike_t *this, message_t *message)
{
- if (message->get_message_id(message) == 1)
+ if (message->get_exchange_type(message) == IKE_AUTH &&
+ message->get_message_id(message) == 1)
{ /* only first IKE_AUTH */
process_payloads(this, message);
}
@@ -421,14 +419,25 @@ static status_t process_r(private_ike_mobike_t *this, message_t *message)
{
this->natd->task.process(&this->natd->task, message);
}
+ if (this->addresses_updated && this->ike_sa->has_condition(this->ike_sa,
+ COND_ORIGINAL_INITIATOR))
+ {
+ host_t *other = message->get_source(message);
+ host_t *other_old = this->ike_sa->get_other_host(this->ike_sa);
+ if (!other->equals(other, other_old))
+ {
+ DBG1(DBG_IKE, "remote address changed from %H to %H", other_old,
+ other);
+ this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
+ this->update = TRUE;
+ }
+ }
}
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_mobike_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
@@ -460,10 +469,8 @@ static status_t build_r(private_ike_mobike_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_mobike_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
@@ -536,14 +543,22 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message)
}
if (this->update)
{
- /* start the update with the same task */
- this->check = FALSE;
- this->address = FALSE;
- if (this->natd)
- {
- this->natd->task.destroy(&this->natd->task);
+ /* use the same task to ... */
+ if (!this->ike_sa->has_condition(this->ike_sa,
+ COND_ORIGINAL_INITIATOR))
+ { /*... send an updated list of addresses as responder */
+ update_children(this);
+ this->update = FALSE;
+ }
+ else
+ { /* ... send the update as original initiator */
+ if (this->natd)
+ {
+ this->natd->task.destroy(&this->natd->task);
+ }
+ this->natd = ike_natd_create(this->ike_sa, this->initiator);
}
- this->natd = ike_natd_create(this->ike_sa, this->initiator);
+ this->check = FALSE;
this->ike_sa->set_pending_updates(this->ike_sa, 1);
return NEED_MORE;
}
@@ -553,51 +568,48 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of ike_mobike_t.roam.
- */
-static void roam(private_ike_mobike_t *this, bool address)
+METHOD(ike_mobike_t, addresses, void,
+ private_ike_mobike_t *this)
+{
+ this->address = TRUE;
+ this->ike_sa->set_pending_updates(this->ike_sa,
+ this->ike_sa->get_pending_updates(this->ike_sa) + 1);
+}
+
+METHOD(ike_mobike_t, roam, void,
+ private_ike_mobike_t *this, bool address)
{
this->check = TRUE;
this->address = address;
this->ike_sa->set_pending_updates(this->ike_sa,
- this->ike_sa->get_pending_updates(this->ike_sa) + 1);
+ this->ike_sa->get_pending_updates(this->ike_sa) + 1);
}
-/**
- * Implementation of ike_mobike_t.dpd
- */
-static void dpd(private_ike_mobike_t *this)
+METHOD(ike_mobike_t, dpd, void,
+ private_ike_mobike_t *this)
{
if (!this->natd)
{
this->natd = ike_natd_create(this->ike_sa, this->initiator);
}
- this->address = FALSE;
this->ike_sa->set_pending_updates(this->ike_sa,
- this->ike_sa->get_pending_updates(this->ike_sa) + 1);
+ this->ike_sa->get_pending_updates(this->ike_sa) + 1);
}
-/**
- * Implementation of ike_mobike_t.is_probing.
- */
-static bool is_probing(private_ike_mobike_t *this)
+METHOD(ike_mobike_t, is_probing, bool,
+ private_ike_mobike_t *this)
{
return this->check;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_mobike_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_mobike_t *this)
{
return IKE_MOBIKE;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_mobike_t *this, ike_sa_t *ike_sa)
{
chunk_free(&this->cookie2);
this->ike_sa = ike_sa;
@@ -607,10 +619,8 @@ static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa)
}
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_mobike_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_mobike_t *this)
{
chunk_free(&this->cookie2);
if (this->natd)
@@ -625,35 +635,36 @@ static void destroy(private_ike_mobike_t *this)
*/
ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator)
{
- private_ike_mobike_t *this = malloc_thing(private_ike_mobike_t);
-
- this->public.roam = (void(*)(ike_mobike_t*,bool))roam;
- this->public.dpd = (void(*)(ike_mobike_t*))dpd;
- this->public.transmit = (void(*)(ike_mobike_t*,packet_t*))transmit;
- this->public.is_probing = (bool(*)(ike_mobike_t*))is_probing;
- this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
- this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
- this->public.task.destroy = (void(*)(task_t*))destroy;
+ private_ike_mobike_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ .addresses = _addresses,
+ .roam = _roam,
+ .dpd = _dpd,
+ .transmit = _transmit,
+ .is_probing = _is_probing,
+ },
+ .ike_sa = ike_sa,
+ .initiator = initiator,
+ );
if (initiator)
{
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
+ this->public.task.build = _build_i;
+ this->public.task.process = _process_i;
}
else
{
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
+ this->public.task.build = _build_r;
+ this->public.task.process = _process_r;
}
- this->ike_sa = ike_sa;
- this->initiator = initiator;
- this->update = FALSE;
- this->check = FALSE;
- this->address = TRUE;
- this->cookie2 = chunk_empty;
- this->natd = NULL;
-
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_mobike.h b/src/libcharon/sa/tasks/ike_mobike.h
index 05b2224d1..16611939e 100644
--- a/src/libcharon/sa/tasks/ike_mobike.h
+++ b/src/libcharon/sa/tasks/ike_mobike.h
@@ -46,6 +46,11 @@ struct ike_mobike_t {
task_t task;
/**
+ * Use the task to update the list of additional addresses.
+ */
+ void (*addresses)(ike_mobike_t *this);
+
+ /**
* Use the task to roam to other addresses.
*
* @param address TRUE to include address list update
diff --git a/src/libcharon/sa/tasks/ike_natd.c b/src/libcharon/sa/tasks/ike_natd.c
index 9ea20ba36..7839b52eb 100644
--- a/src/libcharon/sa/tasks/ike_natd.c
+++ b/src/libcharon/sa/tasks/ike_natd.c
@@ -18,6 +18,7 @@
#include <string.h>
+#include <hydra.h>
#include <daemon.h>
#include <config/peer_cfg.h>
#include <crypto/hashers/hasher.h>
@@ -265,41 +266,15 @@ static status_t process_i(private_ike_natd_t *this, message_t *message)
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
peer_cfg_t *peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
-
-#ifdef ME
- /* if we are on a mediated connection we have already switched to
- * port 4500 and the correct destination port is already configured,
- * therefore we must not switch again */
- if (peer_cfg->get_mediated_by(peer_cfg))
- {
- return SUCCESS;
- }
-#endif /* ME */
-
if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY) ||
-#ifdef ME
- /* if we are on a mediation connection we switch to port 4500 even
- * if no NAT is detected. */
- peer_cfg->is_mediation(peer_cfg) ||
-#endif /* ME */
/* if peer supports NAT-T, we switch to port 4500 even
- * if no NAT is detected. MOBIKE requires this. */
+ * if no NAT is detected. can't be done later (when we would know
+ * whether the peer supports MOBIKE) because there would be no
+ * exchange to actually do the switch (other than a forced DPD). */
(peer_cfg->use_mobike(peer_cfg) &&
this->ike_sa->supports_extension(this->ike_sa, EXT_NATT)))
{
- host_t *me, *other;
-
- /* do not switch if we have a custom port from mobike/NAT */
- me = this->ike_sa->get_my_host(this->ike_sa);
- if (me->get_port(me) == IKEV2_UDP_PORT)
- {
- me->set_port(me, IKEV2_NATT_PORT);
- }
- other = this->ike_sa->get_other_host(this->ike_sa);
- if (other->get_port(other) == IKEV2_UDP_PORT)
- {
- other->set_port(other, IKEV2_NATT_PORT);
- }
+ this->ike_sa->float_ports(this->ike_sa);
}
}
@@ -342,7 +317,7 @@ static status_t build_i(private_ike_natd_t *this, message_t *message)
}
else
{
- host = charon->kernel_interface->get_source_addr(charon->kernel_interface,
+ host = hydra->kernel_interface->get_source_addr(hydra->kernel_interface,
this->ike_sa->get_other_host(this->ike_sa), NULL);
if (host)
{ /* 2. */
@@ -353,8 +328,8 @@ static status_t build_i(private_ike_natd_t *this, message_t *message)
}
else
{ /* 3. */
- enumerator = charon->kernel_interface->create_address_enumerator(
- charon->kernel_interface, FALSE, FALSE);
+ enumerator = hydra->kernel_interface->create_address_enumerator(
+ hydra->kernel_interface, FALSE, FALSE);
while (enumerator->enumerate(enumerator, (void**)&host))
{
/* apply port 500 to host, but work on a copy */
diff --git a/src/libcharon/sa/tasks/ike_rekey.c b/src/libcharon/sa/tasks/ike_rekey.c
index a2275e796..1a6c140c4 100644
--- a/src/libcharon/sa/tasks/ike_rekey.c
+++ b/src/libcharon/sa/tasks/ike_rekey.c
@@ -196,7 +196,7 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
DBG1(DBG_IKE, "peer seems to not support IKE rekeying, "
"starting reauthentication");
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- charon->processor->queue_job(charon->processor,
+ lib->processor->queue_job(lib->processor,
(job_t*)rekey_ike_sa_job_create(
this->ike_sa->get_id(this->ike_sa), TRUE));
return SUCCESS;
@@ -217,7 +217,7 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
DBG1(DBG_IKE, "IKE_SA rekeying failed, "
"trying again in %d seconds", retry);
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- charon->scheduler->schedule_job(charon->scheduler, job, retry);
+ lib->scheduler->schedule_job(lib->scheduler, job, retry);
}
return SUCCESS;
case NEED_MORE:
@@ -241,51 +241,56 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
if (this->collision &&
this->collision->get_type(this->collision) == IKE_REKEY)
{
- chunk_t this_nonce, other_nonce;
- host_t *host;
private_ike_rekey_t *other = (private_ike_rekey_t*)this->collision;
- this_nonce = this->ike_init->get_lower_nonce(this->ike_init);
- other_nonce = other->ike_init->get_lower_nonce(other->ike_init);
-
- /* if we have the lower nonce, delete rekeyed SA. If not, delete
- * the redundant. */
- if (memcmp(this_nonce.ptr, other_nonce.ptr,
- min(this_nonce.len, other_nonce.len)) < 0)
- {
- /* peer should delete this SA. Add a timeout just in case. */
- job_t *job = (job_t*)delete_ike_sa_job_create(
- other->new_sa->get_id(other->new_sa), TRUE);
- charon->scheduler->schedule_job(charon->scheduler, job, 10);
- DBG1(DBG_IKE, "IKE_SA rekey collision won, deleting rekeyed IKE_SA");
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, other->new_sa);
- other->new_sa = NULL;
- }
- else
+ /* ike_init can be NULL, if child_sa is half-open */
+ if (other->ike_init)
{
- DBG1(DBG_IKE, "IKE_SA rekey collision lost, deleting redundant IKE_SA");
- /* apply host for a proper delete */
- host = this->ike_sa->get_my_host(this->ike_sa);
- this->new_sa->set_my_host(this->new_sa, host->clone(host));
- host = this->ike_sa->get_other_host(this->ike_sa);
- this->new_sa->set_other_host(this->new_sa, host->clone(host));
- this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- if (this->new_sa->delete(this->new_sa) == DESTROY_ME)
+ host_t *host;
+ chunk_t this_nonce, other_nonce;
+
+ this_nonce = this->ike_init->get_lower_nonce(this->ike_init);
+ other_nonce = other->ike_init->get_lower_nonce(other->ike_init);
+
+ /* if we have the lower nonce, delete rekeyed SA. If not, delete
+ * the redundant. */
+ if (memcmp(this_nonce.ptr, other_nonce.ptr,
+ min(this_nonce.len, other_nonce.len)) < 0)
{
- charon->ike_sa_manager->checkin_and_destroy(
- charon->ike_sa_manager, this->new_sa);
+ /* peer should delete this SA. Add a timeout just in case. */
+ job_t *job = (job_t*)delete_ike_sa_job_create(
+ other->new_sa->get_id(other->new_sa), TRUE);
+ lib->scheduler->schedule_job(lib->scheduler, job, 10);
+ DBG1(DBG_IKE, "IKE_SA rekey collision won, deleting rekeyed IKE_SA");
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, other->new_sa);
+ other->new_sa = NULL;
}
else
{
- charon->ike_sa_manager->checkin(
- charon->ike_sa_manager, this->new_sa);
+ DBG1(DBG_IKE, "IKE_SA rekey collision lost, deleting redundant IKE_SA");
+ /* apply host for a proper delete */
+ host = this->ike_sa->get_my_host(this->ike_sa);
+ this->new_sa->set_my_host(this->new_sa, host->clone(host));
+ host = this->ike_sa->get_other_host(this->ike_sa);
+ this->new_sa->set_other_host(this->new_sa, host->clone(host));
+ this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
+ if (this->new_sa->delete(this->new_sa) == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, this->new_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(
+ charon->ike_sa_manager, this->new_sa);
+ }
+ /* set threads active IKE_SA after checkin */
+ charon->bus->set_sa(charon->bus, this->ike_sa);
+ /* inherit to other->new_sa in destroy() */
+ this->new_sa = other->new_sa;
+ other->new_sa = NULL;
+ return SUCCESS;
}
- /* set threads active IKE_SA after checkin */
- charon->bus->set_sa(charon->bus, this->ike_sa);
- /* inherit to other->new_sa in destroy() */
- this->new_sa = other->new_sa;
- other->new_sa = NULL;
- return SUCCESS;
}
/* set threads active IKE_SA after checkin */
charon->bus->set_sa(charon->bus, this->ike_sa);
diff --git a/src/libcharon/sa/tasks/ike_vendor.c b/src/libcharon/sa/tasks/ike_vendor.c
index 7c435b6d1..1c14ee06b 100644
--- a/src/libcharon/sa/tasks/ike_vendor.c
+++ b/src/libcharon/sa/tasks/ike_vendor.c
@@ -123,12 +123,14 @@ ike_vendor_t *ike_vendor_create(ike_sa_t *ike_sa, bool initiator)
private_ike_vendor_t *this;
INIT(this,
- .public.task = {
- .build = _build,
- .process = _process,
- .migrate = _migrate,
- .get_type = _get_type,
- .destroy = _destroy,
+ .public = {
+ .task = {
+ .build = _build,
+ .process = _process,
+ .migrate = _migrate,
+ .get_type = _get_type,
+ .destroy = _destroy,
+ },
},
.initiator = initiator,
.ike_sa = ike_sa,
diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c
index 80bf647cd..f91eff077 100644
--- a/src/libcharon/sa/trap_manager.c
+++ b/src/libcharon/sa/trap_manager.c
@@ -15,6 +15,7 @@
#include "trap_manager.h"
+#include <hydra.h>
#include <daemon.h>
#include <threading/rwlock.h>
#include <utils/linked_list.h>
@@ -138,8 +139,8 @@ static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer,
if (!me || me->is_anyaddr(me))
{
DESTROY_IF(me);
- me = charon->kernel_interface->get_source_addr(
- charon->kernel_interface, other, NULL);
+ me = hydra->kernel_interface->get_source_addr(
+ hydra->kernel_interface, other, NULL);
if (!me)
{
DBG1(DBG_CFG, "installing trap failed, local address unknown");
diff --git a/src/libcharon/kernel/kernel_ipsec.c b/src/libcharon/tnccs/tnccs.c
index 5b0335b16..2facf02c8 100644
--- a/src/libcharon/kernel/kernel_ipsec.c
+++ b/src/libcharon/tnccs/tnccs.c
@@ -1,6 +1,6 @@
/*
- * Copyright (C) 2008 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -13,17 +13,10 @@
* for more details.
*/
-#include "kernel_ipsec.h"
+#include "tnccs.h"
-ENUM(ipsec_mode_names, MODE_TRANSPORT, MODE_BEET,
- "TRANSPORT",
- "TUNNEL",
- "BEET",
+ENUM(eap_type_names, TNCCS_1_1, TNCCS_2_0,
+ "TNCCS 1.1",
+ "TNCCS SOH",
+ "TNCCS 2.0",
);
-
-ENUM(policy_dir_names, POLICY_IN, POLICY_FWD,
- "in",
- "out",
- "fwd"
-);
-
diff --git a/src/libcharon/tnccs/tnccs.h b/src/libcharon/tnccs/tnccs.h
new file mode 100644
index 000000000..583512e82
--- /dev/null
+++ b/src/libcharon/tnccs/tnccs.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tnccs tnccs
+ * @{ @ingroup libcharon
+ */
+
+#ifndef TNCCS_H_
+#define TNCCS_H_
+
+typedef enum tnccs_type_t tnccs_type_t;
+
+#include <library.h>
+
+/**
+ * Type of TNC Client/Server protocol
+ */
+enum tnccs_type_t {
+ TNCCS_1_1,
+ TNCCS_SOH,
+ TNCCS_2_0
+};
+
+/**
+ * enum names for tnccs_type_t.
+ */
+extern enum_name_t *tnccs_type_names;
+
+typedef struct tnccs_t tnccs_t;
+
+/**
+ * Constructor definition for a pluggable TNCCS protocol implementation.
+ *
+ * @param is_server TRUE if TNC Server, FALSE if TNC Client
+ * @return implementation of the tnccs_t interface
+ */
+typedef tnccs_t* (*tnccs_constructor_t)(bool is_server);
+
+#endif /** TNC_H_ @}*/
diff --git a/src/libcharon/tnccs/tnccs_manager.c b/src/libcharon/tnccs/tnccs_manager.c
new file mode 100644
index 000000000..0fd6737c0
--- /dev/null
+++ b/src/libcharon/tnccs/tnccs_manager.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "tnccs_manager.h"
+
+#include <utils/linked_list.h>
+#include <threading/rwlock.h>
+
+typedef struct private_tnccs_manager_t private_tnccs_manager_t;
+typedef struct tnccs_entry_t tnccs_entry_t;
+
+/**
+ * TNCCS constructor entry
+ */
+struct tnccs_entry_t {
+
+ /**
+ * TNCCS protocol type
+ */
+ tnccs_type_t type;
+
+ /**
+ * constructor function to create instance
+ */
+ tnccs_constructor_t constructor;
+};
+
+/**
+ * private data of tnccs_manager
+ */
+struct private_tnccs_manager_t {
+
+ /**
+ * public functions
+ */
+ tnccs_manager_t public;
+
+ /**
+ * list of tnccs_entry_t's
+ */
+ linked_list_t *protocols;
+
+ /**
+ * rwlock to lock methods
+ */
+ rwlock_t *lock;
+};
+
+METHOD(tnccs_manager_t, add_method, void,
+ private_tnccs_manager_t *this, tnccs_type_t type,
+ tnccs_constructor_t constructor)
+{
+ tnccs_entry_t *entry = malloc_thing(tnccs_entry_t);
+
+ entry->type = type;
+ entry->constructor = constructor;
+
+ this->lock->write_lock(this->lock);
+ this->protocols->insert_last(this->protocols, entry);
+ this->lock->unlock(this->lock);
+}
+
+METHOD(tnccs_manager_t, remove_method, void,
+ private_tnccs_manager_t *this, tnccs_constructor_t constructor)
+{
+ enumerator_t *enumerator;
+ tnccs_entry_t *entry;
+
+ this->lock->write_lock(this->lock);
+ enumerator = this->protocols->create_enumerator(this->protocols);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (constructor == entry->constructor)
+ {
+ this->protocols->remove_at(this->protocols, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+}
+
+METHOD(tnccs_manager_t, create_instance, tnccs_t*,
+ private_tnccs_manager_t *this, tnccs_type_t type, bool is_server)
+{
+ enumerator_t *enumerator;
+ tnccs_entry_t *entry;
+ tnccs_t *protocol = NULL;
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->protocols->create_enumerator(this->protocols);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (type == entry->type)
+ {
+ protocol = entry->constructor(is_server);
+ if (protocol)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+ return protocol;
+}
+
+METHOD(tnccs_manager_t, destroy, void,
+ private_tnccs_manager_t *this)
+{
+ this->protocols->destroy_function(this->protocols, free);
+ this->lock->destroy(this->lock);
+ free(this);
+}
+
+/*
+ * See header
+ */
+tnccs_manager_t *tnccs_manager_create()
+{
+ private_tnccs_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .add_method = _add_method,
+ .remove_method = _remove_method,
+ .create_instance = _create_instance,
+ .destroy = _destroy,
+ },
+ .protocols = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/tnccs/tnccs_manager.h b/src/libcharon/tnccs/tnccs_manager.h
new file mode 100644
index 000000000..2f4a961a7
--- /dev/null
+++ b/src/libcharon/tnccs/tnccs_manager.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup tnccs_manager tnccs_manager
+ * @{ @ingroup tnccs
+ */
+
+#ifndef TNCCS_MANAGER_H_
+#define TNCCS_MANAGER_H_
+
+#include "tnccs.h"
+
+typedef struct tnccs_manager_t tnccs_manager_t;
+
+/**
+ * The TNCCS manager manages all TNCCS implementations and creates instances.
+ *
+ * A plugin registers its implemented TNCCS protocol with the manager by
+ * providing type and a constructor function. The manager then creates
+ * TNCCS protocol instances via the provided constructor.
+ */
+struct tnccs_manager_t {
+
+ /**
+ * Register a TNCCS protocol implementation.
+ *
+ * @param type TNCCS protocol type
+ * @param constructor constructor, returns a TNCCS protocol implementation
+ */
+ void (*add_method)(tnccs_manager_t *this, tnccs_type_t type,
+ tnccs_constructor_t constructor);
+
+ /**
+ * Unregister a TNCCS protocol implementation using it's constructor.
+ *
+ * @param constructor constructor function to remove, as added in add_method
+ */
+ void (*remove_method)(tnccs_manager_t *this, tnccs_constructor_t constructor);
+
+ /**
+ * Create a new TNCCS protocol instance.
+ *
+ * @param type type of the TNCCS protocol
+ * @param is_server TRUE if TNC Server, FALSE if TNC Client
+ * @return TNCCS protocol instance, NULL if no constructor found
+ */
+ tnccs_t* (*create_instance)(tnccs_manager_t *this, tnccs_type_t type,
+ bool is_server);
+
+ /**
+ * Destroy a tnccs_manager instance.
+ */
+ void (*destroy)(tnccs_manager_t *this);
+};
+
+/**
+ * Create a tnccs_manager instance.
+ */
+tnccs_manager_t *tnccs_manager_create();
+
+#endif /** TNCCS_MANAGER_H_ @}*/