summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@corsac.net>2012-06-28 21:16:07 +0200
committerYves-Alexis Perez <corsac@corsac.net>2012-06-28 21:16:07 +0200
commitb34738ed08c2227300d554b139e2495ca5da97d6 (patch)
tree62f33b52820f2e49f0e53c0f8c636312037c8054 /src
parent0a9d51a49042a68daa15b0c74a2b7f152f52606b (diff)
downloadvyos-strongswan-b34738ed08c2227300d554b139e2495ca5da97d6.tar.gz
vyos-strongswan-b34738ed08c2227300d554b139e2495ca5da97d6.zip
Imported Upstream version 4.6.4
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am20
-rw-r--r--src/Makefile.in51
-rw-r--r--src/_copyright/Makefile.in7
-rw-r--r--src/_updown/Makefile.in7
-rw-r--r--src/_updown_espmark/Makefile.in7
-rw-r--r--src/charon/Android.mk2
-rw-r--r--src/charon/Makefile.in7
-rw-r--r--src/charon/charon.c17
-rw-r--r--src/checksum/Makefile.am106
-rw-r--r--src/checksum/Makefile.in179
-rw-r--r--src/checksum/checksum_builder.c41
-rw-r--r--src/conftest/Makefile.in7
-rw-r--r--src/conftest/actions.c36
-rw-r--r--src/dumm/Makefile.am9
-rw-r--r--src/dumm/Makefile.in70
-rw-r--r--src/dumm/bridge.c45
-rw-r--r--src/dumm/cowfs.c40
-rw-r--r--src/dumm/dumm.c130
-rw-r--r--src/dumm/ext/dumm.c14
-rw-r--r--src/dumm/guest.c138
-rw-r--r--src/dumm/iface.c90
-rw-r--r--src/dumm/iface.h10
-rw-r--r--src/dumm/mconsole.c45
-rw-r--r--src/include/Makefile.am2
-rw-r--r--src/include/Makefile.in9
-rw-r--r--src/include/linux/jhash.h143
-rw-r--r--src/include/linux/rtnetlink.h1
-rw-r--r--src/include/linux/udp.h2
-rw-r--r--src/ipsec/Android.mk33
-rw-r--r--src/ipsec/Makefile.am3
-rw-r--r--src/ipsec/Makefile.in10
-rw-r--r--src/ipsec/ipsec.82
-rwxr-xr-xsrc/ipsec/ipsec.in11
-rw-r--r--src/libcharon/Android.mk37
-rw-r--r--src/libcharon/Makefile.am70
-rw-r--r--src/libcharon/Makefile.in368
-rw-r--r--src/libcharon/bus/bus.c39
-rw-r--r--src/libcharon/bus/bus.h14
-rw-r--r--src/libcharon/bus/listeners/listener.h2
-rw-r--r--src/libcharon/config/backend_manager.c8
-rw-r--r--src/libcharon/config/child_cfg.h4
-rw-r--r--src/libcharon/config/ike_cfg.c20
-rw-r--r--src/libcharon/config/peer_cfg.c288
-rw-r--r--src/libcharon/config/peer_cfg.h15
-rw-r--r--src/libcharon/config/proposal.c5
-rw-r--r--src/libcharon/config/proposal.h8
-rw-r--r--src/libcharon/control/controller.c228
-rw-r--r--src/libcharon/control/controller.h21
-rw-r--r--src/libcharon/daemon.c50
-rw-r--r--src/libcharon/daemon.h30
-rw-r--r--src/libcharon/encoding/generator.c2
-rw-r--r--src/libcharon/encoding/message.c36
-rw-r--r--src/libcharon/encoding/message.h2
-rw-r--r--src/libcharon/encoding/parser.c60
-rw-r--r--src/libcharon/encoding/payloads/certreq_payload.c3
-rw-r--r--src/libcharon/encoding/payloads/cp_payload.h2
-rw-r--r--src/libcharon/encoding/payloads/eap_payload.c12
-rw-r--r--src/libcharon/encoding/payloads/eap_payload.h13
-rw-r--r--src/libcharon/encoding/payloads/encryption_payload.c2
-rw-r--r--src/libcharon/encoding/payloads/endpoint_notify.c125
-rw-r--r--src/libcharon/encoding/payloads/endpoint_notify.h15
-rw-r--r--src/libcharon/encoding/payloads/ike_header.c9
-rw-r--r--src/libcharon/encoding/payloads/ike_header.h5
-rw-r--r--src/libcharon/encoding/payloads/notify_payload.c50
-rw-r--r--src/libcharon/encoding/payloads/notify_payload.h22
-rw-r--r--src/libcharon/encoding/payloads/payload.c23
-rw-r--r--src/libcharon/encoding/payloads/payload.h7
-rw-r--r--src/libcharon/encoding/payloads/proposal_substructure.c2
-rw-r--r--src/libcharon/encoding/payloads/sa_payload.c12
-rw-r--r--src/libcharon/encoding/payloads/transform_substructure.c2
-rw-r--r--src/libcharon/encoding/payloads/transform_substructure.h2
-rw-r--r--src/libcharon/kernel/kernel_handler.c2
-rw-r--r--src/libcharon/network/receiver.c221
-rw-r--r--src/libcharon/network/receiver.h4
-rw-r--r--src/libcharon/network/sender.c4
-rw-r--r--src/libcharon/network/socket.c36
-rw-r--r--src/libcharon/network/socket.h15
-rw-r--r--src/libcharon/plugins/addrblock/Makefile.in7
-rw-r--r--src/libcharon/plugins/android/Makefile.in7
-rw-r--r--src/libcharon/plugins/android/android_handler.c36
-rw-r--r--src/libcharon/plugins/android/android_handler.h6
-rw-r--r--src/libcharon/plugins/android/android_logger.c5
-rw-r--r--src/libcharon/plugins/android/android_plugin.c11
-rw-r--r--src/libcharon/plugins/certexpire/Makefile.am19
-rw-r--r--src/libcharon/plugins/certexpire/Makefile.in621
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_cron.c227
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_cron.h67
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_export.c388
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_export.h52
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_listener.c148
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_listener.h54
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_plugin.c82
-rw-r--r--src/libcharon/plugins/certexpire/certexpire_plugin.h42
-rw-r--r--src/libcharon/plugins/coupling/Makefile.in7
-rw-r--r--src/libcharon/plugins/dhcp/Makefile.in7
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_socket.c4
-rw-r--r--src/libcharon/plugins/duplicheck/Makefile.in7
-rw-r--r--src/libcharon/plugins/duplicheck/duplicheck_notify.c4
-rw-r--r--src/libcharon/plugins/duplicheck/duplicheck_plugin.c2
-rw-r--r--src/libcharon/plugins/eap_aka/Makefile.in7
-rw-r--r--src/libcharon/plugins/eap_aka/eap_aka_peer.c48
-rw-r--r--src/libcharon/plugins/eap_aka/eap_aka_peer.h2
-rw-r--r--src/libcharon/plugins/eap_aka/eap_aka_plugin.c75
-rw-r--r--src/libcharon/plugins/eap_aka/eap_aka_plugin.h5
-rw-r--r--src/libcharon/plugins/eap_aka/eap_aka_server.c45
-rw-r--r--src/libcharon/plugins/eap_aka/eap_aka_server.h2
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/Makefile.am9
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/Makefile.in16
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c61
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.h6
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c71
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h2
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c79
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c56
-rw-r--r--src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.h6
-rw-r--r--src/libcharon/plugins/eap_gtc/Makefile.in7
-rw-r--r--src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c19
-rw-r--r--src/libcharon/plugins/eap_identity/Makefile.in7
-rw-r--r--src/libcharon/plugins/eap_identity/eap_identity_plugin.c24
-rw-r--r--src/libcharon/plugins/eap_md5/Makefile.in7
-rw-r--r--src/libcharon/plugins/eap_md5/eap_md5_plugin.c28
-rw-r--r--src/libcharon/plugins/eap_mschapv2/Makefile.in7
-rw-r--r--src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c9
-rw-r--r--src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c32
-rw-r--r--src/libcharon/plugins/eap_peap/Makefile.in7
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap.c3
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_avp.c19
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_avp.h8
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_peer.c4
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_plugin.c33
-rw-r--r--src/libcharon/plugins/eap_peap/eap_peap_server.c4
-rw-r--r--src/libcharon/plugins/eap_radius/Makefile.am10
-rw-r--r--src/libcharon/plugins/eap_radius/Makefile.in31
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius.c61
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_accounting.c339
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_accounting.h49
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_dae.c543
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_dae.h44
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_forward.c458
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_forward.h65
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_plugin.c177
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_plugin.h9
-rw-r--r--src/libcharon/plugins/eap_sim/Makefile.in7
-rw-r--r--src/libcharon/plugins/eap_sim/eap_sim_peer.c42
-rw-r--r--src/libcharon/plugins/eap_sim/eap_sim_peer.h3
-rw-r--r--src/libcharon/plugins/eap_sim/eap_sim_plugin.c74
-rw-r--r--src/libcharon/plugins/eap_sim/eap_sim_plugin.h5
-rw-r--r--src/libcharon/plugins/eap_sim/eap_sim_server.c44
-rw-r--r--src/libcharon/plugins/eap_sim/eap_sim_server.h3
-rw-r--r--src/libcharon/plugins/eap_sim_file/Makefile.am3
-rw-r--r--src/libcharon/plugins/eap_sim_file/Makefile.in13
-rw-r--r--src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c4
-rw-r--r--src/libcharon/plugins/eap_sim_file/eap_sim_file_card.h6
-rw-r--r--src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c79
-rw-r--r--src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c2
-rw-r--r--src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.h6
-rw-r--r--src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c12
-rw-r--r--src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.h2
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/Makefile.am9
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/Makefile.in18
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c25
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h6
-rw-r--r--src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c24
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am3
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in13
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c58
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h6
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c68
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c47
-rw-r--r--src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h6
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/Makefile.am3
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/Makefile.in13
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c59
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h6
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c68
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c58
-rw-r--r--src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h6
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/Makefile.am3
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/Makefile.in13
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c4
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.h6
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_plugin.c114
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.c12
-rw-r--r--src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.h6
-rw-r--r--src/libcharon/plugins/eap_tls/Makefile.in7
-rw-r--r--src/libcharon/plugins/eap_tls/eap_tls.c6
-rw-r--r--src/libcharon/plugins/eap_tls/eap_tls_plugin.c31
-rw-r--r--src/libcharon/plugins/eap_tnc/Makefile.am13
-rw-r--r--src/libcharon/plugins/eap_tnc/Makefile.in24
-rw-r--r--src/libcharon/plugins/eap_tnc/eap_tnc.c6
-rw-r--r--src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c28
-rw-r--r--src/libcharon/plugins/eap_ttls/Makefile.am3
-rw-r--r--src/libcharon/plugins/eap_ttls/Makefile.in10
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls.c3
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_avp.c8
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_avp.h8
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_peer.c8
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c33
-rw-r--r--src/libcharon/plugins/eap_ttls/eap_ttls_server.c4
-rw-r--r--src/libcharon/plugins/farp/Makefile.in7
-rw-r--r--src/libcharon/plugins/farp/farp_listener.c147
-rw-r--r--src/libcharon/plugins/farp/farp_listener.h9
-rw-r--r--src/libcharon/plugins/farp/farp_spoofer.c20
-rw-r--r--src/libcharon/plugins/ha/Makefile.am2
-rw-r--r--src/libcharon/plugins/ha/Makefile.in9
-rw-r--r--src/libcharon/plugins/ha/ha_cache.c35
-rw-r--r--src/libcharon/plugins/ha/ha_ctl.c4
-rw-r--r--src/libcharon/plugins/ha/ha_dispatcher.c21
-rw-r--r--src/libcharon/plugins/ha/ha_ike.c19
-rw-r--r--src/libcharon/plugins/ha/ha_kernel.c157
-rw-r--r--src/libcharon/plugins/ha/ha_message.c4
-rw-r--r--src/libcharon/plugins/ha/ha_message.h4
-rw-r--r--src/libcharon/plugins/ha/ha_segments.c7
-rw-r--r--src/libcharon/plugins/ha/ha_segments.h4
-rw-r--r--src/libcharon/plugins/ha/ha_socket.c4
-rw-r--r--src/libcharon/plugins/led/Makefile.in7
-rw-r--r--src/libcharon/plugins/led/led_listener.c6
-rw-r--r--src/libcharon/plugins/load_tester/Makefile.in7
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_config.c162
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_creds.c130
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_ipsec.c60
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_listener.c59
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_listener.h7
-rw-r--r--src/libcharon/plugins/load_tester/load_tester_plugin.c47
-rw-r--r--src/libcharon/plugins/maemo/Makefile.in7
-rw-r--r--src/libcharon/plugins/maemo/maemo_service.c5
-rw-r--r--src/libcharon/plugins/medcli/Makefile.in7
-rw-r--r--src/libcharon/plugins/medcli/medcli_config.c92
-rw-r--r--src/libcharon/plugins/medcli/medcli_creds.c96
-rw-r--r--src/libcharon/plugins/medcli/medcli_listener.c44
-rw-r--r--src/libcharon/plugins/medsrv/Makefile.in7
-rw-r--r--src/libcharon/plugins/medsrv/medsrv_config.c67
-rw-r--r--src/libcharon/plugins/medsrv/medsrv_creds.c74
-rw-r--r--src/libcharon/plugins/nm/Makefile.in7
-rw-r--r--src/libcharon/plugins/nm/nm_creds.c176
-rw-r--r--src/libcharon/plugins/nm/nm_handler.c61
-rw-r--r--src/libcharon/plugins/nm/nm_plugin.c5
-rw-r--r--src/libcharon/plugins/nm/nm_service.c8
-rw-r--r--src/libcharon/plugins/nm/nm_service.h2
-rw-r--r--src/libcharon/plugins/radattr/Makefile.am17
-rw-r--r--src/libcharon/plugins/radattr/Makefile.in616
-rw-r--r--src/libcharon/plugins/radattr/radattr_listener.c221
-rw-r--r--src/libcharon/plugins/radattr/radattr_listener.h49
-rw-r--r--src/libcharon/plugins/radattr/radattr_plugin.c75
-rw-r--r--src/libcharon/plugins/radattr/radattr_plugin.h42
-rw-r--r--src/libcharon/plugins/smp/Makefile.in7
-rw-r--r--src/libcharon/plugins/smp/smp.c39
-rw-r--r--src/libcharon/plugins/socket_default/Makefile.in7
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_plugin.c19
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_socket.c9
-rw-r--r--src/libcharon/plugins/socket_dynamic/Makefile.in7
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c18
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c2
-rw-r--r--src/libcharon/plugins/socket_raw/Makefile.in7
-rw-r--r--src/libcharon/plugins/socket_raw/socket_raw_plugin.c18
-rw-r--r--src/libcharon/plugins/socket_raw/socket_raw_socket.c22
-rw-r--r--src/libcharon/plugins/sql/Makefile.in7
-rw-r--r--src/libcharon/plugins/sql/sql_logger.c38
-rw-r--r--src/libcharon/plugins/stroke/Makefile.in7
-rw-r--r--src/libcharon/plugins/stroke/stroke_ca.c2
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c225
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.h10
-rw-r--r--src/libcharon/plugins/stroke/stroke_control.c100
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.c223
-rw-r--r--src/libcharon/plugins/stroke/stroke_cred.h24
-rw-r--r--src/libcharon/plugins/stroke/stroke_list.c232
-rw-r--r--src/libcharon/plugins/stroke/stroke_list.h4
-rw-r--r--src/libcharon/plugins/stroke/stroke_socket.c199
-rw-r--r--src/libcharon/plugins/tnc_ifmap/Makefile.am21
-rw-r--r--src/libcharon/plugins/tnc_ifmap/Makefile.in620
-rw-r--r--src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c173
-rw-r--r--src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h51
-rw-r--r--src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.c99
-rw-r--r--src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.h42
-rw-r--r--src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c859
-rw-r--r--src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h95
-rw-r--r--src/libcharon/plugins/tnc_imc/Makefile.am9
-rw-r--r--src/libcharon/plugins/tnc_imc/Makefile.in21
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc.c214
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c147
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_manager.c130
-rw-r--r--src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c183
-rw-r--r--src/libcharon/plugins/tnc_imv/Makefile.am11
-rw-r--r--src/libcharon/plugins/tnc_imv/Makefile.in23
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv.c211
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c117
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_manager.c142
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c179
-rw-r--r--src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c29
-rw-r--r--src/libcharon/plugins/tnc_pdp/Makefile.am24
-rw-r--r--src/libcharon/plugins/tnc_pdp/Makefile.in627
-rw-r--r--src/libcharon/plugins/tnc_pdp/tnc_pdp.c648
-rw-r--r--src/libcharon/plugins/tnc_pdp/tnc_pdp.h46
-rw-r--r--src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c220
-rw-r--r--src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h77
-rw-r--r--src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.c91
-rw-r--r--src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.h42
-rw-r--r--src/libcharon/plugins/tnc_tnccs/Makefile.am22
-rw-r--r--src/libcharon/plugins/tnc_tnccs/Makefile.in624
-rw-r--r--src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.c (renamed from src/libcharon/tnc/tnccs/tnccs_manager.c)345
-rw-r--r--src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.h31
-rw-r--r--src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.c98
-rw-r--r--src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.h42
-rw-r--r--src/libcharon/plugins/tnccs_11/Makefile.am11
-rw-r--r--src/libcharon/plugins/tnccs_11/Makefile.in24
-rw-r--r--src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c5
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c3
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h2
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h2
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c45
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c2
-rw-r--r--src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h2
-rw-r--r--src/libcharon/plugins/tnccs_11/tnccs_11.c114
-rw-r--r--src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c23
-rw-r--r--src/libcharon/plugins/tnccs_20/Makefile.am11
-rw-r--r--src/libcharon/plugins/tnccs_20/Makefile.in22
-rw-r--r--src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c64
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c12
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c15
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c19
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c4
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c41
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h30
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c12
-rw-r--r--src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c12
-rw-r--r--src/libcharon/plugins/tnccs_20/tnccs_20.c161
-rw-r--r--src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c23
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/Makefile.am11
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/Makefile.in22
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c8
-rw-r--r--src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c24
-rw-r--r--src/libcharon/plugins/uci/Makefile.in7
-rw-r--r--src/libcharon/plugins/uci/uci_config.c112
-rw-r--r--src/libcharon/plugins/uci/uci_control.c37
-rw-r--r--src/libcharon/plugins/uci/uci_creds.c70
-rw-r--r--src/libcharon/plugins/uci/uci_parser.c43
-rw-r--r--src/libcharon/plugins/uci/uci_plugin.c4
-rw-r--r--src/libcharon/plugins/unit_tester/Makefile.in7
-rw-r--r--src/libcharon/plugins/updown/Makefile.in7
-rw-r--r--src/libcharon/plugins/updown/updown_listener.c46
-rw-r--r--src/libcharon/plugins/whitelist/Makefile.in7
-rw-r--r--src/libcharon/plugins/whitelist/whitelist_control.c4
-rw-r--r--src/libcharon/processing/jobs/acquire_job.c7
-rw-r--r--src/libcharon/processing/jobs/delete_child_sa_job.c7
-rw-r--r--src/libcharon/processing/jobs/delete_ike_sa_job.c7
-rw-r--r--src/libcharon/processing/jobs/inactivity_job.c17
-rw-r--r--src/libcharon/processing/jobs/initiate_mediation_job.c50
-rw-r--r--src/libcharon/processing/jobs/mediation_job.c43
-rw-r--r--src/libcharon/processing/jobs/migrate_job.c13
-rw-r--r--src/libcharon/processing/jobs/process_message_job.c22
-rw-r--r--src/libcharon/processing/jobs/rekey_child_sa_job.c7
-rw-r--r--src/libcharon/processing/jobs/rekey_ike_sa_job.c7
-rw-r--r--src/libcharon/processing/jobs/retransmit_job.c7
-rw-r--r--src/libcharon/processing/jobs/roam_job.c10
-rw-r--r--src/libcharon/processing/jobs/send_dpd_job.c7
-rw-r--r--src/libcharon/processing/jobs/send_keepalive_job.c7
-rw-r--r--src/libcharon/processing/jobs/start_action_job.c23
-rw-r--r--src/libcharon/processing/jobs/update_sa_job.c7
-rw-r--r--src/libcharon/sa/authenticators/authenticator.c7
-rw-r--r--src/libcharon/sa/authenticators/authenticator.h6
-rw-r--r--src/libcharon/sa/authenticators/eap/eap_method.c20
-rw-r--r--src/libcharon/sa/authenticators/eap/eap_method.h15
-rw-r--r--src/libcharon/sa/authenticators/eap_authenticator.c25
-rw-r--r--src/libcharon/sa/child_sa.c150
-rw-r--r--src/libcharon/sa/connect_manager.c322
-rw-r--r--src/libcharon/sa/ike_sa.c391
-rw-r--r--src/libcharon/sa/ike_sa.h126
-rw-r--r--src/libcharon/sa/ike_sa_id.c103
-rw-r--r--src/libcharon/sa/ike_sa_id.h22
-rw-r--r--src/libcharon/sa/ike_sa_manager.c176
-rw-r--r--src/libcharon/sa/ike_sa_manager.h12
-rw-r--r--src/libcharon/sa/keymat.c2
-rw-r--r--src/libcharon/sa/keymat.h7
-rw-r--r--src/libcharon/sa/mediation_manager.c131
-rw-r--r--src/libcharon/sa/shunt_manager.c251
-rw-r--r--src/libcharon/sa/shunt_manager.h69
-rw-r--r--src/libcharon/sa/task_manager.c118
-rw-r--r--src/libcharon/sa/tasks/child_create.c10
-rw-r--r--src/libcharon/sa/tasks/child_delete.c109
-rw-r--r--src/libcharon/sa/tasks/child_rekey.c93
-rw-r--r--src/libcharon/sa/tasks/ike_auth.c82
-rw-r--r--src/libcharon/sa/tasks/ike_auth.h2
-rw-r--r--src/libcharon/sa/tasks/ike_auth_lifetime.c69
-rw-r--r--src/libcharon/sa/tasks/ike_cert_post.c72
-rw-r--r--src/libcharon/sa/tasks/ike_cert_post.h2
-rw-r--r--src/libcharon/sa/tasks/ike_cert_pre.c75
-rw-r--r--src/libcharon/sa/tasks/ike_cert_pre.h2
-rw-r--r--src/libcharon/sa/tasks/ike_config.c79
-rw-r--r--src/libcharon/sa/tasks/ike_delete.c75
-rw-r--r--src/libcharon/sa/tasks/ike_dpd.c57
-rw-r--r--src/libcharon/sa/tasks/ike_dpd.h2
-rw-r--r--src/libcharon/sa/tasks/ike_init.c130
-rw-r--r--src/libcharon/sa/tasks/ike_init.h2
-rw-r--r--src/libcharon/sa/tasks/ike_me.c159
-rw-r--r--src/libcharon/sa/tasks/ike_mobike.c59
-rw-r--r--src/libcharon/sa/tasks/ike_natd.c95
-rw-r--r--src/libcharon/sa/tasks/ike_natd.h2
-rw-r--r--src/libcharon/sa/tasks/ike_reauth.c145
-rw-r--r--src/libcharon/sa/tasks/ike_rekey.c10
-rw-r--r--src/libcharon/sa/tasks/ike_vendor.h2
-rw-r--r--src/libcharon/sa/tasks/task.h6
-rw-r--r--src/libcharon/sa/trap_manager.c178
-rw-r--r--src/libcharon/sa/trap_manager.h5
-rw-r--r--src/libfast/Makefile.am4
-rw-r--r--src/libfast/Makefile.in63
-rw-r--r--src/libfast/dispatcher.c104
-rw-r--r--src/libfast/request.c183
-rw-r--r--src/libfast/session.c56
-rw-r--r--src/libfast/session.h2
-rw-r--r--src/libfast/smtp.h2
-rw-r--r--src/libfreeswan/Android.mk38
-rw-r--r--src/libfreeswan/Makefile.am20
-rw-r--r--src/libfreeswan/Makefile.in27
-rw-r--r--src/libfreeswan/datatot.c1
-rw-r--r--src/libfreeswan/pfkey_v2_parse.c4
-rw-r--r--src/libhydra/Android.mk4
-rw-r--r--src/libhydra/Makefile.am4
-rw-r--r--src/libhydra/Makefile.in77
-rw-r--r--src/libhydra/attributes/attribute_manager.c124
-rw-r--r--src/libhydra/attributes/attributes.c58
-rw-r--r--src/libhydra/attributes/attributes.h1
-rw-r--r--src/libhydra/kernel/kernel_interface.c60
-rw-r--r--src/libhydra/kernel/kernel_interface.h28
-rw-r--r--src/libhydra/kernel/kernel_ipsec.c24
-rw-r--r--src/libhydra/kernel/kernel_ipsec.h60
-rw-r--r--src/libhydra/kernel/kernel_listener.h2
-rw-r--r--src/libhydra/kernel/kernel_net.c37
-rw-r--r--src/libhydra/kernel/kernel_net.h15
-rw-r--r--src/libhydra/plugins/attr/Makefile.in7
-rw-r--r--src/libhydra/plugins/attr_sql/Makefile.in7
-rw-r--r--src/libhydra/plugins/attr_sql/pool.c8
-rw-r--r--src/libhydra/plugins/attr_sql/sql_attribute.c56
-rw-r--r--src/libhydra/plugins/kernel_klips/Makefile.in7
-rw-r--r--src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c27
-rw-r--r--src/libhydra/plugins/kernel_klips/kernel_klips_plugin.c17
-rw-r--r--src/libhydra/plugins/kernel_netlink/Makefile.in7
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c1035
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c41
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_plugin.c23
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c41
-rw-r--r--src/libhydra/plugins/kernel_pfkey/Makefile.in7
-rw-r--r--src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c917
-rw-r--r--src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c17
-rw-r--r--src/libhydra/plugins/kernel_pfroute/Makefile.in7
-rw-r--r--src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c4
-rw-r--r--src/libhydra/plugins/kernel_pfroute/kernel_pfroute_plugin.c17
-rw-r--r--src/libhydra/plugins/resolve/Makefile.in7
-rw-r--r--src/libhydra/plugins/resolve/resolve_handler.c245
-rw-r--r--src/libhydra/plugins/resolve/resolve_plugin.c2
-rw-r--r--src/libimcv/Makefile.am38
-rw-r--r--src/libimcv/Makefile.in845
-rw-r--r--src/libimcv/ietf/ietf_attr.c63
-rw-r--r--src/libimcv/ietf/ietf_attr.h63
-rw-r--r--src/libimcv/ietf/ietf_attr_pa_tnc_error.c472
-rw-r--r--src/libimcv/ietf/ietf_attr_pa_tnc_error.h134
-rw-r--r--src/libimcv/ietf/ietf_attr_port_filter.c288
-rw-r--r--src/libimcv/ietf/ietf_attr_port_filter.h74
-rw-r--r--src/libimcv/ietf/ietf_attr_product_info.c255
-rw-r--r--src/libimcv/ietf/ietf_attr_product_info.h67
-rw-r--r--src/libimcv/imc/imc_agent.c693
-rw-r--r--src/libimcv/imc/imc_agent.h175
-rw-r--r--src/libimcv/imc/imc_state.h79
-rw-r--r--src/libimcv/imcv.c161
-rw-r--r--src/libimcv/imcv.h49
-rw-r--r--src/libimcv/imv/imv_agent.c792
-rw-r--r--src/libimcv/imv/imv_agent.h197
-rw-r--r--src/libimcv/imv/imv_state.h111
-rw-r--r--src/libimcv/ita/ita_attr.c35
-rw-r--r--src/libimcv/ita/ita_attr.h50
-rw-r--r--src/libimcv/ita/ita_attr_command.c196
-rw-r--r--src/libimcv/ita/ita_attr_command.h61
-rw-r--r--src/libimcv/pa_tnc/pa_tnc_attr.h96
-rw-r--r--src/libimcv/pa_tnc/pa_tnc_attr_manager.c155
-rw-r--r--src/libimcv/pa_tnc/pa_tnc_attr_manager.h85
-rw-r--r--src/libimcv/pa_tnc/pa_tnc_msg.c427
-rw-r--r--src/libimcv/pa_tnc/pa_tnc_msg.h103
-rw-r--r--src/libimcv/plugins/imc_scanner/Makefile.am15
-rw-r--r--src/libimcv/plugins/imc_scanner/Makefile.in600
-rw-r--r--src/libimcv/plugins/imc_scanner/imc_scanner.c384
-rw-r--r--src/libimcv/plugins/imc_scanner/imc_scanner_state.c115
-rw-r--r--src/libimcv/plugins/imc_scanner/imc_scanner_state.h47
-rw-r--r--src/libimcv/plugins/imc_test/Makefile.am15
-rw-r--r--src/libimcv/plugins/imc_test/Makefile.in600
-rw-r--r--src/libimcv/plugins/imc_test/imc_test.c379
-rw-r--r--src/libimcv/plugins/imc_test/imc_test_state.c178
-rw-r--r--src/libimcv/plugins/imc_test/imc_test_state.h80
-rw-r--r--src/libimcv/plugins/imv_scanner/Makefile.am15
-rw-r--r--src/libimcv/plugins/imv_scanner/Makefile.in600
-rw-r--r--src/libimcv/plugins/imv_scanner/imv_scanner.c409
-rw-r--r--src/libimcv/plugins/imv_scanner/imv_scanner_state.c243
-rw-r--r--src/libimcv/plugins/imv_scanner/imv_scanner_state.h52
-rw-r--r--src/libimcv/plugins/imv_test/Makefile.am15
-rw-r--r--src/libimcv/plugins/imv_test/Makefile.in600
-rw-r--r--src/libimcv/plugins/imv_test/imv_test.c315
-rw-r--r--src/libimcv/plugins/imv_test/imv_test_state.c297
-rw-r--r--src/libimcv/plugins/imv_test/imv_test_state.h70
-rw-r--r--src/libpts/Makefile.am58
-rw-r--r--src/libpts/Makefile.in1083
-rw-r--r--src/libpts/libpts.c96
-rw-r--r--src/libpts/libpts.h49
-rw-r--r--src/libpts/plugins/imc_attestation/Makefile.am18
-rw-r--r--src/libpts/plugins/imc_attestation/Makefile.in608
-rw-r--r--src/libpts/plugins/imc_attestation/imc_attestation.c358
-rw-r--r--src/libpts/plugins/imc_attestation/imc_attestation_process.c466
-rw-r--r--src/libpts/plugins/imc_attestation/imc_attestation_process.h49
-rw-r--r--src/libpts/plugins/imc_attestation/imc_attestation_state.c161
-rw-r--r--src/libpts/plugins/imc_attestation/imc_attestation_state.h73
-rw-r--r--src/libpts/plugins/imv_attestation/Makefile.am33
-rw-r--r--src/libpts/plugins/imv_attestation/Makefile.in686
-rw-r--r--src/libpts/plugins/imv_attestation/attest.c373
-rw-r--r--src/libpts/plugins/imv_attestation/attest_db.c1200
-rw-r--r--src/libpts/plugins/imv_attestation/attest_db.h190
-rw-r--r--src/libpts/plugins/imv_attestation/attest_usage.c80
-rw-r--r--src/libpts/plugins/imv_attestation/attest_usage.h25
-rw-r--r--src/libpts/plugins/imv_attestation/data.sql1305
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation.c520
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_build.c300
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_build.h50
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_process.c399
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_process.h57
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_state.c407
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_state.h156
-rw-r--r--src/libpts/plugins/imv_attestation/tables.sql82
-rw-r--r--src/libpts/pts/components/ita/ita_comp_func_name.c45
-rw-r--r--src/libpts/pts/components/ita/ita_comp_func_name.h85
-rw-r--r--src/libpts/pts/components/ita/ita_comp_ima.c439
-rw-r--r--src/libpts/pts/components/ita/ita_comp_ima.h36
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tboot.c335
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tboot.h36
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tgrub.c184
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tgrub.h36
-rw-r--r--src/libpts/pts/components/pts_comp_evidence.c251
-rw-r--r--src/libpts/pts/components/pts_comp_evidence.h170
-rw-r--r--src/libpts/pts/components/pts_comp_func_name.c152
-rw-r--r--src/libpts/pts/components/pts_comp_func_name.h96
-rw-r--r--src/libpts/pts/components/pts_component.h94
-rw-r--r--src/libpts/pts/components/pts_component_manager.c317
-rw-r--r--src/libpts/pts/components/pts_component_manager.h125
-rw-r--r--src/libpts/pts/components/tcg/tcg_comp_func_name.c48
-rw-r--r--src/libpts/pts/components/tcg/tcg_comp_func_name.h98
-rw-r--r--src/libpts/pts/pts.c1539
-rw-r--r--src/libpts/pts/pts.h353
-rw-r--r--src/libpts/pts/pts_creds.c136
-rw-r--r--src/libpts/pts/pts_creds.h55
-rw-r--r--src/libpts/pts/pts_database.c312
-rw-r--r--src/libpts/pts/pts_database.h153
-rw-r--r--src/libpts/pts/pts_dh_group.c175
-rw-r--r--src/libpts/pts/pts_dh_group.h104
-rw-r--r--src/libpts/pts/pts_error.c99
-rw-r--r--src/libpts/pts/pts_error.h89
-rw-r--r--src/libpts/pts/pts_file_meas.c186
-rw-r--r--src/libpts/pts/pts_file_meas.h85
-rw-r--r--src/libpts/pts/pts_file_meta.c96
-rw-r--r--src/libpts/pts/pts_file_meta.h85
-rw-r--r--src/libpts/pts/pts_file_type.c33
-rw-r--r--src/libpts/pts/pts_file_type.h63
-rw-r--r--src/libpts/pts/pts_meas_algo.c170
-rw-r--r--src/libpts/pts/pts_meas_algo.h105
-rw-r--r--src/libpts/pts/pts_proto_caps.h44
-rw-r--r--src/libpts/pts/pts_req_func_comp_evid.h42
-rw-r--r--src/libpts/pts/pts_simple_evid_final.h47
-rw-r--r--src/libpts/tcg/tcg_attr.c209
-rw-r--r--src/libpts/tcg/tcg_attr.h81
-rw-r--r--src/libpts/tcg/tcg_pts_attr_aik.c256
-rw-r--r--src/libpts/tcg/tcg_pts_attr_aik.h65
-rw-r--r--src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c276
-rw-r--r--src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.h89
-rw-r--r--src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c247
-rw-r--r--src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.h72
-rw-r--r--src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c295
-rw-r--r--src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.h93
-rw-r--r--src/libpts/tcg/tcg_pts_attr_file_meas.c308
-rw-r--r--src/libpts/tcg/tcg_pts_attr_file_meas.h65
-rw-r--r--src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c214
-rw-r--r--src/libpts/tcg/tcg_pts_attr_gen_attest_evid.h53
-rw-r--r--src/libpts/tcg/tcg_pts_attr_get_aik.c211
-rw-r--r--src/libpts/tcg/tcg_pts_attr_get_aik.h53
-rw-r--r--src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c214
-rw-r--r--src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.h54
-rw-r--r--src/libpts/tcg/tcg_pts_attr_meas_algo.c230
-rw-r--r--src/libpts/tcg/tcg_pts_attr_meas_algo.h68
-rw-r--r--src/libpts/tcg/tcg_pts_attr_proto_caps.c230
-rw-r--r--src/libpts/tcg/tcg_pts_attr_proto_caps.h67
-rw-r--r--src/libpts/tcg/tcg_pts_attr_req_file_meas.c303
-rw-r--r--src/libpts/tcg/tcg_pts_attr_req_file_meas.h91
-rw-r--r--src/libpts/tcg/tcg_pts_attr_req_file_meta.c286
-rw-r--r--src/libpts/tcg/tcg_pts_attr_req_file_meta.h81
-rw-r--r--src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c378
-rw-r--r--src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.h80
-rw-r--r--src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c514
-rw-r--r--src/libpts/tcg/tcg_pts_attr_simple_comp_evid.h64
-rw-r--r--src/libpts/tcg/tcg_pts_attr_simple_evid_final.c394
-rw-r--r--src/libpts/tcg/tcg_pts_attr_simple_evid_final.h91
-rw-r--r--src/libpts/tcg/tcg_pts_attr_tpm_version_info.c237
-rw-r--r--src/libpts/tcg/tcg_pts_attr_tpm_version_info.h70
-rw-r--r--src/libpts/tcg/tcg_pts_attr_unix_file_meta.c360
-rw-r--r--src/libpts/tcg/tcg_pts_attr_unix_file_meta.h65
-rw-r--r--src/libradius/Makefile.am11
-rw-r--r--src/libradius/Makefile.in598
-rw-r--r--src/libradius/radius_client.c (renamed from src/libcharon/plugins/eap_radius/radius_client.c)65
-rw-r--r--src/libradius/radius_client.h (renamed from src/libcharon/plugins/eap_radius/radius_client.h)6
-rw-r--r--src/libradius/radius_config.c (renamed from src/libcharon/plugins/eap_radius/radius_server.c)50
-rw-r--r--src/libradius/radius_config.h (renamed from src/libcharon/plugins/eap_radius/radius_server.h)45
-rw-r--r--src/libradius/radius_message.c (renamed from src/libcharon/plugins/eap_radius/radius_message.c)116
-rw-r--r--src/libradius/radius_message.h (renamed from src/libcharon/plugins/eap_radius/radius_message.h)48
-rw-r--r--src/libradius/radius_mppe.h40
-rw-r--r--src/libradius/radius_socket.c (renamed from src/libcharon/plugins/eap_radius/radius_socket.c)126
-rw-r--r--src/libradius/radius_socket.h (renamed from src/libcharon/plugins/eap_radius/radius_socket.h)9
-rw-r--r--src/libsimaka/Makefile.am5
-rw-r--r--src/libsimaka/Makefile.in94
-rw-r--r--src/libsimaka/simaka_card.h (renamed from src/libcharon/sa/authenticators/eap/sim_card.h)34
-rw-r--r--src/libsimaka/simaka_crypto.c136
-rw-r--r--src/libsimaka/simaka_hooks.h (renamed from src/libcharon/sa/authenticators/eap/sim_hooks.h)22
-rw-r--r--src/libsimaka/simaka_manager.c (renamed from src/libcharon/sa/authenticators/eap/sim_manager.c)264
-rw-r--r--src/libsimaka/simaka_manager.h (renamed from src/libcharon/sa/authenticators/eap/sim_manager.h)110
-rw-r--r--src/libsimaka/simaka_message.c169
-rw-r--r--src/libsimaka/simaka_message.h11
-rw-r--r--src/libsimaka/simaka_provider.h (renamed from src/libcharon/sa/authenticators/eap/sim_provider.h)34
-rw-r--r--src/libstrongswan/Android.mk14
-rw-r--r--src/libstrongswan/Makefile.am27
-rw-r--r--src/libstrongswan/Makefile.in344
-rw-r--r--src/libstrongswan/asn1/asn1.c69
-rw-r--r--src/libstrongswan/asn1/asn1.h10
-rw-r--r--src/libstrongswan/asn1/asn1_parser.c18
-rw-r--r--src/libstrongswan/asn1/oid.c676
-rw-r--r--src/libstrongswan/asn1/oid.h357
-rw-r--r--src/libstrongswan/asn1/oid.txt6
-rw-r--r--src/libstrongswan/bio/bio_reader.c (renamed from src/libtls/tls_reader.c)89
-rw-r--r--src/libstrongswan/bio/bio_reader.h (renamed from src/libtls/tls_reader.h)54
-rw-r--r--src/libstrongswan/bio/bio_writer.c (renamed from src/libtls/tls_writer.c)90
-rw-r--r--src/libstrongswan/bio/bio_writer.h (renamed from src/libtls/tls_writer.h)59
-rw-r--r--src/libstrongswan/chunk.c11
-rw-r--r--src/libstrongswan/chunk.h16
-rw-r--r--src/libstrongswan/credentials/auth_cfg.c413
-rw-r--r--src/libstrongswan/credentials/auth_cfg.h46
-rw-r--r--src/libstrongswan/credentials/builder.c3
-rw-r--r--src/libstrongswan/credentials/builder.h8
-rw-r--r--src/libstrongswan/credentials/cert_validator.h2
-rw-r--r--src/libstrongswan/credentials/certificates/ac.h1
-rw-r--r--src/libstrongswan/credentials/certificates/certificate.c1
-rw-r--r--src/libstrongswan/credentials/certificates/certificate.h18
-rw-r--r--src/libstrongswan/credentials/certificates/crl.h6
-rw-r--r--src/libstrongswan/credentials/certificates/x509.h12
-rw-r--r--src/libstrongswan/credentials/cred_encoding.c70
-rw-r--r--src/libstrongswan/credentials/cred_encoding.h2
-rw-r--r--src/libstrongswan/credentials/credential_factory.h2
-rw-r--r--src/libstrongswan/credentials/credential_manager.c4
-rw-r--r--src/libstrongswan/credentials/credential_manager.h28
-rw-r--r--src/libstrongswan/credentials/credential_set.h4
-rw-r--r--src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c118
-rw-r--r--src/libstrongswan/credentials/keys/private_key.h10
-rw-r--r--src/libstrongswan/credentials/keys/public_key.c3
-rw-r--r--src/libstrongswan/credentials/keys/public_key.h12
-rw-r--r--src/libstrongswan/credentials/keys/shared_key.c47
-rw-r--r--src/libstrongswan/credentials/sets/auth_cfg_wrapper.c39
-rw-r--r--src/libstrongswan/credentials/sets/cert_cache.c52
-rw-r--r--src/libstrongswan/credentials/sets/ocsp_response_wrapper.c40
-rw-r--r--src/libstrongswan/crypto/aead.h2
-rw-r--r--src/libstrongswan/crypto/crypto_tester.c10
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.c24
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.h7
-rw-r--r--src/libstrongswan/crypto/pkcs9.c112
-rw-r--r--src/libstrongswan/crypto/prf_plus.c35
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords.c31
-rw-r--r--src/libstrongswan/crypto/proposal/proposal_keywords.txt3
-rw-r--r--src/libstrongswan/crypto/signers/signer.h4
-rw-r--r--src/libstrongswan/database/database.c22
-rw-r--r--src/libstrongswan/database/database.h7
-rw-r--r--src/libstrongswan/database/database_factory.c47
-rw-r--r--src/libstrongswan/debug.c8
-rw-r--r--src/libstrongswan/debug.h8
-rw-r--r--src/libstrongswan/eap/eap.c18
-rw-r--r--src/libstrongswan/fetcher/fetcher_manager.h2
-rw-r--r--src/libstrongswan/integrity_checker.h1
-rw-r--r--src/libstrongswan/library.c79
-rw-r--r--src/libstrongswan/library.h31
-rw-r--r--src/libstrongswan/pen/pen.c33
-rw-r--r--src/libstrongswan/pen/pen.h46
-rw-r--r--src/libstrongswan/plugins/aes/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/aes/aes_plugin.c20
-rw-r--r--src/libstrongswan/plugins/af_alg/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_crypter.c19
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_crypter.h11
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_hasher.c7
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_hasher.h11
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_ops.c2
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_plugin.c38
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_prf.c9
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_prf.h11
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_signer.c7
-rw-r--r--src/libstrongswan/plugins/af_alg/af_alg_signer.h11
-rw-r--r--src/libstrongswan/plugins/agent/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/agent/agent_plugin.c17
-rw-r--r--src/libstrongswan/plugins/agent/agent_private_key.c6
-rw-r--r--src/libstrongswan/plugins/blowfish/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/ccm/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/ccm/ccm_aead.c2
-rw-r--r--src/libstrongswan/plugins/ccm/ccm_plugin.c79
-rw-r--r--src/libstrongswan/plugins/cmac/Makefile.am16
-rw-r--r--src/libstrongswan/plugins/cmac/Makefile.in613
-rw-r--r--src/libstrongswan/plugins/cmac/cmac.c321
-rw-r--r--src/libstrongswan/plugins/cmac/cmac.h78
-rw-r--r--src/libstrongswan/plugins/cmac/cmac_plugin.c81
-rw-r--r--src/libstrongswan/plugins/cmac/cmac_plugin.h42
-rw-r--r--src/libstrongswan/plugins/cmac/cmac_prf.c121
-rw-r--r--src/libstrongswan/plugins/cmac/cmac_prf.h50
-rw-r--r--src/libstrongswan/plugins/cmac/cmac_signer.c159
-rw-r--r--src/libstrongswan/plugins/cmac/cmac_signer.h47
-rw-r--r--src/libstrongswan/plugins/constraints/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/ctr/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/ctr/ctr_plugin.c42
-rw-r--r--src/libstrongswan/plugins/curl/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/curl/curl_plugin.c35
-rw-r--r--src/libstrongswan/plugins/des/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/des/des_crypter.c6
-rw-r--r--src/libstrongswan/plugins/des/des_plugin.c24
-rw-r--r--src/libstrongswan/plugins/dnskey/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/dnskey/dnskey_plugin.c21
-rw-r--r--src/libstrongswan/plugins/fips_prf/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf.c6
-rw-r--r--src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c25
-rw-r--r--src/libstrongswan/plugins/gcm/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/gcm/gcm_plugin.c46
-rw-r--r--src/libstrongswan/plugins/gcrypt/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c174
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c6
-rw-r--r--src/libstrongswan/plugins/gmp/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_plugin.c121
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c2
-rw-r--r--src/libstrongswan/plugins/hmac/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/hmac/hmac.c4
-rw-r--r--src/libstrongswan/plugins/hmac/hmac.h4
-rw-r--r--src/libstrongswan/plugins/hmac/hmac_plugin.c105
-rw-r--r--src/libstrongswan/plugins/ldap/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/ldap/ldap_plugin.c21
-rw-r--r--src/libstrongswan/plugins/md4/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/md4/md4_hasher.c48
-rw-r--r--src/libstrongswan/plugins/md4/md4_plugin.c18
-rw-r--r--src/libstrongswan/plugins/md5/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/md5/md5_hasher.c50
-rw-r--r--src/libstrongswan/plugins/md5/md5_plugin.c16
-rw-r--r--src/libstrongswan/plugins/mysql/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_database.c1
-rw-r--r--src/libstrongswan/plugins/mysql/mysql_plugin.c18
-rw-r--r--src/libstrongswan/plugins/openssl/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_crl.c2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_ec_private_key.c39
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_plugin.c309
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c3
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_util.c2
-rw-r--r--src/libstrongswan/plugins/openssl/openssl_x509.c45
-rw-r--r--src/libstrongswan/plugins/padlock/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/pem/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/pem/pem_builder.c49
-rw-r--r--src/libstrongswan/plugins/pem/pem_plugin.c114
-rw-r--r--src/libstrongswan/plugins/pgp/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/pgp/pgp_builder.c4
-rw-r--r--src/libstrongswan/plugins/pgp/pgp_cert.c156
-rw-r--r--src/libstrongswan/plugins/pgp/pgp_plugin.c42
-rw-r--r--src/libstrongswan/plugins/pgp/pgp_utils.c18
-rw-r--r--src/libstrongswan/plugins/pkcs1/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/pkcs1/pkcs1_builder.c6
-rw-r--r--src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c29
-rw-r--r--src/libstrongswan/plugins/pkcs11/Makefile.am2
-rw-r--r--src/libstrongswan/plugins/pkcs11/Makefile.in14
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11.h24
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_dh.c446
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_dh.h51
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c3
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_library.c203
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_library.h46
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_manager.c19
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_manager.h10
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c217
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c184
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h16
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c597
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h2
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_rng.c137
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_rng.h47
-rw-r--r--src/libstrongswan/plugins/pkcs8/Makefile.am16
-rw-r--r--src/libstrongswan/plugins/pkcs8/Makefile.in611
-rw-r--r--src/libstrongswan/plugins/pkcs8/pkcs8_builder.c632
-rw-r--r--src/libstrongswan/plugins/pkcs8/pkcs8_builder.h36
-rw-r--r--src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c78
-rw-r--r--src/libstrongswan/plugins/pkcs8/pkcs8_plugin.h42
-rw-r--r--src/libstrongswan/plugins/plugin.h18
-rw-r--r--src/libstrongswan/plugins/plugin_feature.c383
-rw-r--r--src/libstrongswan/plugins/plugin_feature.h331
-rw-r--r--src/libstrongswan/plugins/plugin_loader.c485
-rw-r--r--src/libstrongswan/plugins/plugin_loader.h18
-rw-r--r--src/libstrongswan/plugins/pubkey/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_cert.c170
-rw-r--r--src/libstrongswan/plugins/pubkey/pubkey_plugin.c17
-rw-r--r--src/libstrongswan/plugins/random/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/random/random_plugin.c21
-rw-r--r--src/libstrongswan/plugins/revocation/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/revocation/revocation_validator.c12
-rw-r--r--src/libstrongswan/plugins/sha1/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_hasher.c49
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_plugin.c24
-rw-r--r--src/libstrongswan/plugins/sha1/sha1_prf.c60
-rw-r--r--src/libstrongswan/plugins/sha2/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_hasher.c279
-rw-r--r--src/libstrongswan/plugins/sha2/sha2_plugin.c27
-rw-r--r--src/libstrongswan/plugins/soup/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/soup/soup_plugin.c21
-rw-r--r--src/libstrongswan/plugins/sqlite/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/sqlite/sqlite_plugin.c18
-rw-r--r--src/libstrongswan/plugins/test_vectors/Makefile.am1
-rw-r--r--src/libstrongswan/plugins/test_vectors/Makefile.in27
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors.h11
-rw-r--r--src/libstrongswan/plugins/test_vectors/test_vectors/aes_cmac.c141
-rw-r--r--src/libstrongswan/plugins/x509/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/x509/x509_ac.c206
-rw-r--r--src/libstrongswan/plugins/x509/x509_cert.c76
-rw-r--r--src/libstrongswan/plugins/x509/x509_crl.c12
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_request.c126
-rw-r--r--src/libstrongswan/plugins/x509/x509_ocsp_response.c154
-rw-r--r--src/libstrongswan/plugins/x509/x509_pkcs10.c146
-rw-r--r--src/libstrongswan/plugins/x509/x509_plugin.c80
-rw-r--r--src/libstrongswan/plugins/xcbc/Makefile.in7
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc.c4
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc.h2
-rw-r--r--src/libstrongswan/plugins/xcbc/xcbc_plugin.c44
-rw-r--r--src/libstrongswan/printf_hook.c2
-rw-r--r--src/libstrongswan/processing/jobs/callback_job.c31
-rw-r--r--src/libstrongswan/processing/jobs/callback_job.h16
-rw-r--r--src/libstrongswan/processing/jobs/job.c23
-rw-r--r--src/libstrongswan/processing/jobs/job.h32
-rw-r--r--src/libstrongswan/processing/processor.c154
-rw-r--r--src/libstrongswan/processing/processor.h15
-rw-r--r--src/libstrongswan/processing/scheduler.c3
-rw-r--r--src/libstrongswan/processing/scheduler.h2
-rw-r--r--src/libstrongswan/selectors/traffic_selector.c166
-rw-r--r--src/libstrongswan/settings.c1
-rw-r--r--src/libstrongswan/settings.h2
-rw-r--r--src/libstrongswan/threading/mutex.c128
-rw-r--r--src/libstrongswan/threading/rwlock.c106
-rw-r--r--src/libstrongswan/threading/thread.c96
-rw-r--r--src/libstrongswan/threading/thread_value.c32
-rw-r--r--src/libstrongswan/utils.c78
-rw-r--r--src/libstrongswan/utils.h99
-rw-r--r--src/libstrongswan/utils/backtrace.c87
-rw-r--r--src/libstrongswan/utils/backtrace.h14
-rw-r--r--src/libstrongswan/utils/enumerator.h4
-rw-r--r--src/libstrongswan/utils/hashtable.c225
-rw-r--r--src/libstrongswan/utils/host.c98
-rw-r--r--src/libstrongswan/utils/identification.c2
-rw-r--r--src/libstrongswan/utils/identification.h6
-rw-r--r--src/libstrongswan/utils/iterator.h114
-rw-r--r--src/libstrongswan/utils/leak_detective.c224
-rw-r--r--src/libstrongswan/utils/leak_detective.h7
-rw-r--r--src/libstrongswan/utils/linked_list.c547
-rw-r--r--src/libstrongswan/utils/linked_list.h60
-rw-r--r--src/libstrongswan/utils/optionsfrom.c10
-rw-r--r--src/libtls/Makefile.am5
-rw-r--r--src/libtls/Makefile.in97
-rw-r--r--src/libtls/tls.c12
-rw-r--r--src/libtls/tls.h9
-rw-r--r--src/libtls/tls_alert.h2
-rw-r--r--src/libtls/tls_application.h8
-rw-r--r--src/libtls/tls_cache.c237
-rw-r--r--src/libtls/tls_cache.h78
-rw-r--r--src/libtls/tls_compression.h4
-rw-r--r--src/libtls/tls_crypto.c174
-rw-r--r--src/libtls/tls_crypto.h60
-rw-r--r--src/libtls/tls_fragmentation.c50
-rw-r--r--src/libtls/tls_fragmentation.h4
-rw-r--r--src/libtls/tls_handshake.h22
-rw-r--r--src/libtls/tls_peer.c169
-rw-r--r--src/libtls/tls_protection.c57
-rw-r--r--src/libtls/tls_protection.h4
-rw-r--r--src/libtls/tls_server.c209
-rw-r--r--src/libtls/tls_socket.c115
-rw-r--r--src/libtls/tls_socket.h22
-rw-r--r--src/libtnccs/Android.mk33
-rw-r--r--src/libtnccs/Makefile.am16
-rw-r--r--src/libtnccs/Makefile.in629
-rw-r--r--src/libtnccs/tnc/imc/imc.h (renamed from src/libcharon/tnc/imc/imc.h)127
-rw-r--r--src/libtnccs/tnc/imc/imc_manager.h (renamed from src/libcharon/tnc/imc/imc_manager.h)69
-rw-r--r--src/libtnccs/tnc/imv/imv.h (renamed from src/libcharon/tnc/imv/imv.h)127
-rw-r--r--src/libtnccs/tnc/imv/imv_manager.h (renamed from src/libcharon/tnc/imv/imv_manager.h)69
-rw-r--r--src/libtnccs/tnc/imv/imv_recommendations.c (renamed from src/libcharon/tnc/imv/imv_recommendations.c)0
-rw-r--r--src/libtnccs/tnc/imv/imv_recommendations.h (renamed from src/libcharon/tnc/imv/imv_recommendations.h)8
-rw-r--r--src/libtnccs/tnc/tnc.c268
-rw-r--r--src/libtnccs/tnc/tnc.h87
-rw-r--r--src/libtnccs/tnc/tnccs/tnccs.c (renamed from src/libcharon/tnc/tnccs/tnccs.c)1
-rw-r--r--src/libtnccs/tnc/tnccs/tnccs.h (renamed from src/libcharon/tnc/tnccs/tnccs.h)43
-rw-r--r--src/libtnccs/tnc/tnccs/tnccs_manager.c63
-rw-r--r--src/libtnccs/tnc/tnccs/tnccs_manager.h (renamed from src/libcharon/tnc/tnccs/tnccs_manager.h)63
-rw-r--r--src/libtncif/Android.mk28
-rw-r--r--src/libtncif/Makefile.am9
-rw-r--r--src/libtncif/Makefile.in545
-rw-r--r--src/libtncif/tncif.h (renamed from src/libcharon/tnc/tncif.h)66
-rw-r--r--src/libtncif/tncif_names.c (renamed from src/libcharon/tnc/tncifimv.c)13
-rw-r--r--src/libtncif/tncif_names.h34
-rw-r--r--src/libtncif/tncif_pa_subtypes.c93
-rw-r--r--src/libtncif/tncif_pa_subtypes.h104
-rw-r--r--src/libtncif/tncifimc.h (renamed from src/libcharon/tnc/tncifimc.h)155
-rw-r--r--src/libtncif/tncifimv.h (renamed from src/libcharon/tnc/tncifimv.h)236
-rw-r--r--src/manager/Makefile.in7
-rw-r--r--src/manager/controller/auth_controller.c39
-rw-r--r--src/manager/controller/config_controller.c39
-rw-r--r--src/manager/controller/control_controller.c39
-rw-r--r--src/manager/controller/gateway_controller.c40
-rw-r--r--src/manager/controller/ikesa_controller.c39
-rw-r--r--src/manager/gateway.c65
-rw-r--r--src/manager/gateway.h3
-rw-r--r--src/manager/manager.c63
-rw-r--r--src/manager/manager.h4
-rw-r--r--src/manager/storage.c35
-rw-r--r--src/manager/storage.h2
-rw-r--r--src/manager/templates/static/jquery.js2
-rw-r--r--src/manager/xml.c66
-rw-r--r--src/medsrv/Makefile.am2
-rw-r--r--src/medsrv/Makefile.in11
-rwxr-xr-xsrc/medsrv/controller/peer_controller.c41
-rwxr-xr-xsrc/medsrv/controller/user_controller.c46
-rwxr-xr-xsrc/medsrv/filter/auth_filter.c137
-rwxr-xr-xsrc/medsrv/filter/auth_filter.h90
-rw-r--r--src/medsrv/user.c34
-rw-r--r--src/openac/Makefile.in7
-rw-r--r--src/pki/Makefile.in7
-rw-r--r--src/pki/command.c7
-rw-r--r--src/pki/commands/issue.c2
-rw-r--r--src/pki/commands/print.c7
-rw-r--r--src/pki/commands/self.c2
-rw-r--r--src/pki/commands/signcrl.c30
-rw-r--r--src/pluto/Android.mk80
-rw-r--r--src/pluto/Makefile.am26
-rw-r--r--src/pluto/Makefile.in166
-rw-r--r--src/pluto/ac.c4
-rw-r--r--src/pluto/adns.c4
-rw-r--r--src/pluto/adns.h11
-rw-r--r--src/pluto/builder.c18
-rw-r--r--src/pluto/ca.c7
-rw-r--r--src/pluto/connections.c21
-rw-r--r--src/pluto/constants.c4
-rw-r--r--src/pluto/constants.h2
-rw-r--r--src/pluto/crl.c2
-rw-r--r--src/pluto/crypto.c2
-rw-r--r--src/pluto/defs.c8
-rw-r--r--src/pluto/demux.c4
-rw-r--r--src/pluto/dnskey.c341
-rw-r--r--src/pluto/dnskey.h7
-rw-r--r--src/pluto/event_queue.c4
-rw-r--r--src/pluto/ipsec_doi.c17
-rw-r--r--src/pluto/kernel.c15
-rw-r--r--src/pluto/kernel_alg.c2
-rw-r--r--src/pluto/keys.c58
-rw-r--r--src/pluto/lex.h2
-rw-r--r--src/pluto/log.c55
-rw-r--r--src/pluto/myid.c2
-rw-r--r--src/pluto/nat_traversal.c2
-rw-r--r--src/pluto/ocsp.c18
-rw-r--r--src/pluto/plugin_list.c72
-rw-r--r--src/pluto/plugin_list.h21
-rw-r--r--src/pluto/plugins/xauth/Makefile.in7
-rw-r--r--src/pluto/plugins/xauth/xauth_default_verifier.c7
-rw-r--r--src/pluto/pluto.84
-rw-r--r--src/pluto/plutomain.c188
-rw-r--r--src/pluto/rcv_whack.c17
-rw-r--r--src/pluto/server.c88
-rw-r--r--src/pluto/spdb.c2
-rw-r--r--src/pluto/spdb.h2
-rw-r--r--src/pluto/state.c2
-rw-r--r--src/pluto/timer.c13
-rw-r--r--src/pluto/vendor.c2
-rw-r--r--src/pluto/x509.c2
-rw-r--r--src/scepclient/Makefile.in7
-rw-r--r--src/scepclient/scepclient.c49
-rw-r--r--src/starter/Android.mk47
-rw-r--r--src/starter/Makefile.am26
-rw-r--r--src/starter/Makefile.in83
-rw-r--r--src/starter/args.c5
-rw-r--r--src/starter/args.h2
-rw-r--r--src/starter/confread.c170
-rw-r--r--src/starter/confread.h9
-rw-r--r--src/starter/files.h1
-rw-r--r--src/starter/invokepluto.c5
-rw-r--r--src/starter/ipsec-parser.h55
-rw-r--r--src/starter/keywords.c267
-rw-r--r--src/starter/keywords.h1
-rw-r--r--src/starter/keywords.txt1
-rw-r--r--src/starter/lexer.c (renamed from src/starter/lex.yy.c)154
-rw-r--r--src/starter/lexer.l (renamed from src/starter/parser.l)108
-rw-r--r--src/starter/netkey.c17
-rw-r--r--src/starter/parser.c (renamed from src/starter/y.tab.c)30
-rw-r--r--src/starter/parser.h141
-rw-r--r--src/starter/parser.y2
-rw-r--r--src/starter/starter.c142
-rw-r--r--src/starter/starterstroke.c42
-rw-r--r--src/starter/y.tab.h88
-rw-r--r--src/stroke/Android.mk27
-rw-r--r--src/stroke/Makefile.am6
-rw-r--r--src/stroke/Makefile.in13
-rw-r--r--src/stroke/stroke.c73
-rw-r--r--src/stroke/stroke_keywords.c90
-rw-r--r--src/stroke/stroke_keywords.h4
-rw-r--r--src/stroke/stroke_keywords.txt4
-rw-r--r--src/stroke/stroke_msg.h19
-rw-r--r--src/whack/Android.mk30
-rw-r--r--src/whack/Makefile.am6
-rw-r--r--src/whack/Makefile.in14
-rw-r--r--src/whack/whack.c10
-rw-r--r--src/whack/whack.h3
1008 files changed, 71397 insertions, 14189 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index cd75de5e9..1440de20f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,6 +16,26 @@ if USE_TLS
SUBDIRS += libtls
endif
+if USE_RADIUS
+ SUBDIRS += libradius
+endif
+
+if USE_LIBTNCIF
+ SUBDIRS += libtncif
+endif
+
+if USE_LIBTNCCS
+ SUBDIRS += libtnccs
+endif
+
+if USE_IMCV
+ SUBDIRS += libimcv
+endif
+
+if USE_PTS
+ SUBDIRS += libpts
+endif
+
if USE_LIBCHARON
SUBDIRS += libcharon
endif
diff --git a/src/Makefile.in b/src/Makefile.in
index eff3f1337..caa0c5bb9 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -37,20 +37,25 @@ host_triplet = @host@
@USE_LIBHYDRA_TRUE@am__append_2 = libhydra
@USE_SIMAKA_TRUE@am__append_3 = libsimaka
@USE_TLS_TRUE@am__append_4 = libtls
-@USE_LIBCHARON_TRUE@am__append_5 = libcharon
-@USE_FILE_CONFIG_TRUE@am__append_6 = libfreeswan starter
-@USE_IPSEC_SCRIPT_TRUE@am__append_7 = ipsec _copyright
-@USE_PLUTO_TRUE@am__append_8 = pluto whack
-@USE_CHARON_TRUE@am__append_9 = charon
-@USE_STROKE_TRUE@am__append_10 = stroke
-@USE_UPDOWN_TRUE@am__append_11 = _updown _updown_espmark
-@USE_TOOLS_TRUE@am__append_12 = libfreeswan openac scepclient pki
-@USE_CONFTEST_TRUE@am__append_13 = conftest
-@USE_DUMM_TRUE@am__append_14 = dumm
-@USE_FAST_TRUE@am__append_15 = libfast
-@USE_MANAGER_TRUE@am__append_16 = manager
-@USE_MEDSRV_TRUE@am__append_17 = medsrv
-@USE_INTEGRITY_TEST_TRUE@am__append_18 = checksum
+@USE_RADIUS_TRUE@am__append_5 = libradius
+@USE_LIBTNCIF_TRUE@am__append_6 = libtncif
+@USE_LIBTNCCS_TRUE@am__append_7 = libtnccs
+@USE_IMCV_TRUE@am__append_8 = libimcv
+@USE_PTS_TRUE@am__append_9 = libpts
+@USE_LIBCHARON_TRUE@am__append_10 = libcharon
+@USE_FILE_CONFIG_TRUE@am__append_11 = libfreeswan starter
+@USE_IPSEC_SCRIPT_TRUE@am__append_12 = ipsec _copyright
+@USE_PLUTO_TRUE@am__append_13 = pluto whack
+@USE_CHARON_TRUE@am__append_14 = charon
+@USE_STROKE_TRUE@am__append_15 = stroke
+@USE_UPDOWN_TRUE@am__append_16 = _updown _updown_espmark
+@USE_TOOLS_TRUE@am__append_17 = libfreeswan openac scepclient pki
+@USE_CONFTEST_TRUE@am__append_18 = conftest
+@USE_DUMM_TRUE@am__append_19 = dumm
+@USE_FAST_TRUE@am__append_20 = libfast
+@USE_MANAGER_TRUE@am__append_21 = manager
+@USE_MEDSRV_TRUE@am__append_22 = medsrv
+@USE_INTEGRITY_TEST_TRUE@am__append_23 = checksum
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -85,9 +90,10 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = . include libstrongswan libhydra libsimaka libtls \
- libcharon libfreeswan starter ipsec _copyright pluto whack \
- charon stroke _updown _updown_espmark openac scepclient pki \
- conftest dumm libfast manager medsrv checksum
+ libradius libtncif libtnccs libimcv libpts libcharon \
+ libfreeswan starter ipsec _copyright pluto whack charon stroke \
+ _updown _updown_espmark openac scepclient pki conftest dumm \
+ libfast manager medsrv checksum
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -205,6 +211,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -213,6 +222,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -229,11 +239,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -277,6 +289,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -292,7 +305,9 @@ SUBDIRS = . include $(am__append_1) $(am__append_2) $(am__append_3) \
$(am__append_7) $(am__append_8) $(am__append_9) \
$(am__append_10) $(am__append_11) $(am__append_12) \
$(am__append_13) $(am__append_14) $(am__append_15) \
- $(am__append_16) $(am__append_17) $(am__append_18)
+ $(am__append_16) $(am__append_17) $(am__append_18) \
+ $(am__append_19) $(am__append_20) $(am__append_21) \
+ $(am__append_22) $(am__append_23)
EXTRA_DIST = strongswan.conf
all: all-recursive
diff --git a/src/_copyright/Makefile.in b/src/_copyright/Makefile.in
index 5eab0bb5b..ae15d3cde 100644
--- a/src/_copyright/Makefile.in
+++ b/src/_copyright/Makefile.in
@@ -168,6 +168,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -176,6 +179,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -192,11 +196,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -240,6 +246,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/_updown/Makefile.in b/src/_updown/Makefile.in
index d4361dd78..a406d79ac 100644
--- a/src/_updown/Makefile.in
+++ b/src/_updown/Makefile.in
@@ -172,6 +172,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -180,6 +183,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -196,11 +200,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -244,6 +250,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/_updown_espmark/Makefile.in b/src/_updown_espmark/Makefile.in
index 7e2839cb0..3ae236a90 100644
--- a/src/_updown_espmark/Makefile.in
+++ b/src/_updown_espmark/Makefile.in
@@ -172,6 +172,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -180,6 +183,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -196,11 +200,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -244,6 +250,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/charon/Android.mk b/src/charon/Android.mk
index 491d7f946..eb7eca9dd 100644
--- a/src/charon/Android.mk
+++ b/src/charon/Android.mk
@@ -17,6 +17,8 @@ LOCAL_CFLAGS := $(strongswan_CFLAGS)
LOCAL_MODULE := charon
+LOCAL_MODULE_TAGS := optional
+
LOCAL_ARM_MODE := arm
LOCAL_PRELINK_MODULE := false
diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in
index 3ba9c2731..5da167dfd 100644
--- a/src/charon/Makefile.in
+++ b/src/charon/Makefile.in
@@ -171,6 +171,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -179,6 +182,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -195,11 +199,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -243,6 +249,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/charon/charon.c b/src/charon/charon.c
index dda09f66d..6dbb0b592 100644
--- a/src/charon/charon.c
+++ b/src/charon/charon.c
@@ -41,7 +41,7 @@
#include <threading/thread.h>
#ifdef ANDROID
-#include <private/android_filesystem_config.h>
+#include <private/android_filesystem_config.h> /* for AID_VPN */
#endif
#ifndef LOG_AUTHPRIV /* not defined on OpenSolaris */
@@ -242,6 +242,7 @@ static bool check_pidfile()
memset(buf, 0, sizeof(buf));
if (fread(buf, 1, sizeof(buf), pidfile))
{
+ buf[sizeof(buf) - 1] = '\0';
pid = atoi(buf);
}
fclose(pidfile);
@@ -290,7 +291,7 @@ static void initialize_loggers(bool use_stderr, level_t levels[])
sys_logger_t *sys_logger;
file_logger_t *file_logger;
enumerator_t *enumerator;
- char *facility, *filename;
+ char *identifier, *facility, *filename;
int loggers_defined = 0;
debug_t group;
level_t def;
@@ -298,6 +299,12 @@ static void initialize_loggers(bool use_stderr, level_t levels[])
FILE *file;
/* setup sysloggers */
+ identifier = lib->settings->get_str(lib->settings,
+ "charon.syslog.identifier", NULL);
+ if (identifier)
+ { /* set identifier, which is prepended to each log line */
+ openlog(identifier, 0, 0);
+ }
enumerator = lib->settings->create_section_enumerator(lib->settings,
"charon.syslog");
while (enumerator->enumerate(enumerator, &facility))
@@ -425,7 +432,7 @@ static void usage(const char *msg)
" [--version]\n"
" [--use-syslog]\n"
" [--debug-<type> <level>]\n"
- " <type>: log context type (dmn|mgr|ike|chd|job|cfg|knl|net|enc|tnc|tls|lib)\n"
+ " <type>: log context type (dmn|mgr|ike|chd|job|cfg|knl|net|asn|enc|tnc|imc|imv|pts|tls|lib)\n"
" <level>: log verbosity (-1 = silent, 0 = audit, 1 = control,\n"
" 2 = controlmore, 3 = raw, 4 = private)\n"
"\n"
@@ -496,8 +503,12 @@ int main(int argc, char *argv[])
{ "debug-cfg", required_argument, &group, DBG_CFG },
{ "debug-knl", required_argument, &group, DBG_KNL },
{ "debug-net", required_argument, &group, DBG_NET },
+ { "debug-asn", required_argument, &group, DBG_ASN },
{ "debug-enc", required_argument, &group, DBG_ENC },
{ "debug-tnc", required_argument, &group, DBG_TNC },
+ { "debug-imc", required_argument, &group, DBG_IMC },
+ { "debug-imv", required_argument, &group, DBG_IMV },
+ { "debug-pts", required_argument, &group, DBG_PTS },
{ "debug-tls", required_argument, &group, DBG_TLS },
{ "debug-lib", required_argument, &group, DBG_LIB },
{ 0,0,0,0 }
diff --git a/src/checksum/Makefile.am b/src/checksum/Makefile.am
index 3aded1d9e..58292a45a 100644
--- a/src/checksum/Makefile.am
+++ b/src/checksum/Makefile.am
@@ -1,9 +1,10 @@
-ipsec_LTLIBRARIES = libchecksum.la
-noinst_PROGRAMS = checksum_builder
-
+# this lib is not built until make install is called (see rules at the bottom)
+EXTRA_LTLIBRARIES = libchecksum.la
+ipseclib_LTLIBRARIES = $(LIBCHECKSUM_LIBS)
nodist_libchecksum_la_SOURCES = checksum.c
-libchecksum_la_LDFLAGS = -module -avoid-version
+libchecksum_la_LDFLAGS = -module -avoid-version -rpath '$(ipseclibdir)'
+noinst_PROGRAMS = checksum_builder
checksum_builder_SOURCES = checksum_builder.c
checksum_builder_LDADD = \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
@@ -11,39 +12,100 @@ checksum_builder_LDADD = \
$(top_builddir)/src/libcharon/libcharon.la \
$(DLLIB)
-BUILT_SOURCES = checksum.c
CLEANFILES = checksum.c
-INCLUDES = -I$(top_srcdir)/src/libstrongswan
-AM_CFLAGS = -rdynamic \
- -DS_PLUGINS=\""${s_plugins}\"" -DS_PATH=\""${top_builddir}/src/libstrongswan/plugins\"" \
- -DH_PLUGINS=\""${h_plugins}\"" -DH_PATH=\""${top_builddir}/src/libhydra/plugins\"" \
- -DP_PLUGINS=\""${p_plugins}\"" -DP_PATH=\""${top_builddir}/src/pluto/plugins\"" \
- -DC_PLUGINS=\""${c_plugins}\"" -DC_PATH=\""${top_builddir}/src/libcharon/plugins\""
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+AM_CFLAGS = \
+ -DPLUGINDIR=\"${plugindir}\" \
+ -rdynamic
-libs = $(top_builddir)/src/libstrongswan/.libs/libstrongswan.so
+# we keep track of build dependencies in deps and use libs to store the paths
+# to the installed libraries. for executables we use the built files directly
+# as these are not relinked during installation.
+deps = $(top_builddir)/src/libstrongswan/libstrongswan.la
+libs = $(DESTDIR)$(ipseclibdir)/libstrongswan.so
+exes =
+
+if !MONOLITHIC
+ AM_CFLAGS += -DS_PLUGINS=\""${s_plugins}\""
+endif
if USE_LIBHYDRA
- libs += $(top_builddir)/src/libhydra/.libs/libhydra.so
+ deps += $(top_builddir)/src/libhydra/libhydra.la
+ libs += $(DESTDIR)$(ipseclibdir)/libhydra.so
+if !MONOLITHIC
+ AM_CFLAGS += -DH_PLUGINS=\""${h_plugins}\""
+endif
+endif
+
+if USE_TLS
+ deps += $(top_builddir)/src/libtls/libtls.la
+ libs += $(DESTDIR)$(ipseclibdir)/libtls.so
+endif
+
+if USE_RADIUS
+ deps += $(top_builddir)/src/libradius/libradius.la
+ libs += $(DESTDIR)$(ipseclibdir)/libradius.so
+endif
+
+if USE_LIBTNCCS
+ deps += $(top_builddir)/src/libtnccs/libtnccs.la
+ libs += $(DESTDIR)$(ipseclibdir)/libtnccs.so
+endif
+
+if USE_SIMAKA
+ deps += $(top_builddir)/src/libsimaka/libsimaka.la
+ libs += $(DESTDIR)$(ipseclibdir)/libsimaka.so
+endif
+
+if USE_IMCV
+ deps += $(top_builddir)/src/libimcv/libimcv.la
+ libs += $(DESTDIR)$(ipseclibdir)/libimcv.so
+endif
+
+if USE_PTS
+ deps += $(top_builddir)/src/libpts/libpts.la
+ libs += $(DESTDIR)$(ipseclibdir)/libpts.so
endif
if USE_CHARON
- libs += $(top_builddir)/src/libcharon/.libs/libcharon.so
- libs += $(top_builddir)/src/charon/.libs/charon
+ deps += $(top_builddir)/src/libcharon/libcharon.la
+ libs += $(DESTDIR)$(ipseclibdir)/libcharon.so
+ exes += $(top_builddir)/src/charon/.libs/charon
+if !MONOLITHIC
+ AM_CFLAGS += -DC_PLUGINS=\""${c_plugins}\""
+endif
endif
if USE_PLUTO
- libs += $(top_builddir)/src/pluto/.libs/pluto
+ exes += $(top_builddir)/src/pluto/.libs/pluto
+ AM_CFLAGS += -DP_PLUGINS=\""${p_plugins}\""
endif
if USE_TOOLS
- libs += $(top_builddir)/src/openac/.libs/openac
- libs += $(top_builddir)/src/pki/.libs/pki
- libs += $(top_builddir)/src/scepclient/.libs/scepclient
+ exes += $(top_builddir)/src/openac/.libs/openac
+ exes += $(top_builddir)/src/pki/.libs/pki
+ exes += $(top_builddir)/src/scepclient/.libs/scepclient
endif
if USE_ATTR_SQL
- libs += $(top_builddir)/src/libhydra/plugins/attr_sql/.libs/pool
+ exes += $(top_builddir)/src/libhydra/plugins/attr_sql/.libs/pool
+endif
+
+if USE_IMV_ATTESTATION
+ exes += $(top_builddir)/src/libpts/plugins/imv_attestation/.libs/attest
endif
-checksum.c : checksum_builder $(libs)
- ./checksum_builder $(libs) > checksum.c
+checksum.c : checksum_builder $(deps) $(exes)
+ ./checksum_builder $(libs) $(exes) > checksum.c
+
+install-data-hook : $(EXTRA_LTLIBRARIES)
+ $(MAKE) $(AM_MAKEFLAGS) LIBCHECKSUM_LIBS='$(EXTRA_LTLIBRARIES)' install-ipseclibLTLIBRARIES
+
+uninstall-hook :
+ $(MAKE) $(AM_MAKEFLAGS) LIBCHECKSUM_LIBS='$(EXTRA_LTLIBRARIES)' uninstall-ipseclibLTLIBRARIES
+
+clean-local :
+ $(MAKE) $(AM_MAKEFLAGS) LIBCHECKSUM_LIBS='$(EXTRA_LTLIBRARIES)' clean-ipseclibLTLIBRARIES
diff --git a/src/checksum/Makefile.in b/src/checksum/Makefile.in
index 2e11fe1f5..8c89fc615 100644
--- a/src/checksum/Makefile.in
+++ b/src/checksum/Makefile.in
@@ -36,15 +36,34 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = checksum_builder$(EXEEXT)
-@USE_LIBHYDRA_TRUE@am__append_1 = $(top_builddir)/src/libhydra/.libs/libhydra.so
-@USE_CHARON_TRUE@am__append_2 = $(top_builddir)/src/libcharon/.libs/libcharon.so \
-@USE_CHARON_TRUE@ $(top_builddir)/src/charon/.libs/charon
-@USE_PLUTO_TRUE@am__append_3 = $(top_builddir)/src/pluto/.libs/pluto
-@USE_TOOLS_TRUE@am__append_4 = \
+@MONOLITHIC_FALSE@am__append_1 = -DS_PLUGINS=\""${s_plugins}\""
+@USE_LIBHYDRA_TRUE@am__append_2 = $(top_builddir)/src/libhydra/libhydra.la
+@USE_LIBHYDRA_TRUE@am__append_3 = $(DESTDIR)$(ipseclibdir)/libhydra.so
+@MONOLITHIC_FALSE@@USE_LIBHYDRA_TRUE@am__append_4 = -DH_PLUGINS=\""${h_plugins}\""
+@USE_TLS_TRUE@am__append_5 = $(top_builddir)/src/libtls/libtls.la
+@USE_TLS_TRUE@am__append_6 = $(DESTDIR)$(ipseclibdir)/libtls.so
+@USE_RADIUS_TRUE@am__append_7 = $(top_builddir)/src/libradius/libradius.la
+@USE_RADIUS_TRUE@am__append_8 = $(DESTDIR)$(ipseclibdir)/libradius.so
+@USE_LIBTNCCS_TRUE@am__append_9 = $(top_builddir)/src/libtnccs/libtnccs.la
+@USE_LIBTNCCS_TRUE@am__append_10 = $(DESTDIR)$(ipseclibdir)/libtnccs.so
+@USE_SIMAKA_TRUE@am__append_11 = $(top_builddir)/src/libsimaka/libsimaka.la
+@USE_SIMAKA_TRUE@am__append_12 = $(DESTDIR)$(ipseclibdir)/libsimaka.so
+@USE_IMCV_TRUE@am__append_13 = $(top_builddir)/src/libimcv/libimcv.la
+@USE_IMCV_TRUE@am__append_14 = $(DESTDIR)$(ipseclibdir)/libimcv.so
+@USE_PTS_TRUE@am__append_15 = $(top_builddir)/src/libpts/libpts.la
+@USE_PTS_TRUE@am__append_16 = $(DESTDIR)$(ipseclibdir)/libpts.so
+@USE_CHARON_TRUE@am__append_17 = $(top_builddir)/src/libcharon/libcharon.la
+@USE_CHARON_TRUE@am__append_18 = $(DESTDIR)$(ipseclibdir)/libcharon.so
+@USE_CHARON_TRUE@am__append_19 = $(top_builddir)/src/charon/.libs/charon
+@MONOLITHIC_FALSE@@USE_CHARON_TRUE@am__append_20 = -DC_PLUGINS=\""${c_plugins}\""
+@USE_PLUTO_TRUE@am__append_21 = $(top_builddir)/src/pluto/.libs/pluto
+@USE_PLUTO_TRUE@am__append_22 = -DP_PLUGINS=\""${p_plugins}\""
+@USE_TOOLS_TRUE@am__append_23 = \
@USE_TOOLS_TRUE@ $(top_builddir)/src/openac/.libs/openac \
@USE_TOOLS_TRUE@ $(top_builddir)/src/pki/.libs/pki \
@USE_TOOLS_TRUE@ $(top_builddir)/src/scepclient/.libs/scepclient
-@USE_ATTR_SQL_TRUE@am__append_5 = $(top_builddir)/src/libhydra/plugins/attr_sql/.libs/pool
+@USE_ATTR_SQL_TRUE@am__append_24 = $(top_builddir)/src/libhydra/plugins/attr_sql/.libs/pool
+@USE_IMV_ATTESTATION_TRUE@am__append_25 = $(top_builddir)/src/libpts/plugins/imv_attestation/.libs/attest
subdir = src/checksum
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -83,8 +102,8 @@ am__nobase_list = $(am__nobase_strip_setup); \
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)$(ipsecdir)"
-LTLIBRARIES = $(ipsec_LTLIBRARIES)
+am__installdirs = "$(DESTDIR)$(ipseclibdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
libchecksum_la_LIBADD =
nodist_libchecksum_la_OBJECTS = checksum.lo
libchecksum_la_OBJECTS = $(nodist_libchecksum_la_OBJECTS)
@@ -209,6 +228,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -217,6 +239,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -233,11 +256,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -281,6 +306,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -291,9 +317,12 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-ipsec_LTLIBRARIES = libchecksum.la
+
+# this lib is not built until make install is called (see rules at the bottom)
+EXTRA_LTLIBRARIES = libchecksum.la
+ipseclib_LTLIBRARIES = $(LIBCHECKSUM_LIBS)
nodist_libchecksum_la_SOURCES = checksum.c
-libchecksum_la_LDFLAGS = -module -avoid-version
+libchecksum_la_LDFLAGS = -module -avoid-version -rpath '$(ipseclibdir)'
checksum_builder_SOURCES = checksum_builder.c
checksum_builder_LDADD = \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
@@ -301,20 +330,29 @@ checksum_builder_LDADD = \
$(top_builddir)/src/libcharon/libcharon.la \
$(DLLIB)
-BUILT_SOURCES = checksum.c
CLEANFILES = checksum.c
-INCLUDES = -I$(top_srcdir)/src/libstrongswan
-AM_CFLAGS = -rdynamic \
- -DS_PLUGINS=\""${s_plugins}\"" -DS_PATH=\""${top_builddir}/src/libstrongswan/plugins\"" \
- -DH_PLUGINS=\""${h_plugins}\"" -DH_PATH=\""${top_builddir}/src/libhydra/plugins\"" \
- -DP_PLUGINS=\""${p_plugins}\"" -DP_PATH=\""${top_builddir}/src/pluto/plugins\"" \
- -DC_PLUGINS=\""${c_plugins}\"" -DC_PATH=\""${top_builddir}/src/libcharon/plugins\""
-
-libs = $(top_builddir)/src/libstrongswan/.libs/libstrongswan.so \
- $(am__append_1) $(am__append_2) $(am__append_3) \
- $(am__append_4) $(am__append_5)
-all: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) all-am
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = -DPLUGINDIR=\"${plugindir}\" -rdynamic $(am__append_1) \
+ $(am__append_4) $(am__append_20) $(am__append_22)
+
+# we keep track of build dependencies in deps and use libs to store the paths
+# to the installed libraries. for executables we use the built files directly
+# as these are not relinked during installation.
+deps = $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(am__append_2) $(am__append_5) $(am__append_7) \
+ $(am__append_9) $(am__append_11) $(am__append_13) \
+ $(am__append_15) $(am__append_17)
+libs = $(DESTDIR)$(ipseclibdir)/libstrongswan.so $(am__append_3) \
+ $(am__append_6) $(am__append_8) $(am__append_10) \
+ $(am__append_12) $(am__append_14) $(am__append_16) \
+ $(am__append_18)
+exes = $(am__append_19) $(am__append_21) $(am__append_23) \
+ $(am__append_24) $(am__append_25)
+all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
@@ -348,39 +386,39 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
-install-ipsecLTLIBRARIES: $(ipsec_LTLIBRARIES)
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(ipsecdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsecdir)"
- @list='$(ipsec_LTLIBRARIES)'; test -n "$(ipsecdir)" || list=; \
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(ipsecdir)'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipsecdir)"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
}
-uninstall-ipsecLTLIBRARIES:
+uninstall-ipseclibLTLIBRARIES:
@$(NORMAL_UNINSTALL)
- @list='$(ipsec_LTLIBRARIES)'; test -n "$(ipsecdir)" || list=; \
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipsecdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipsecdir)/$$f"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
done
-clean-ipsecLTLIBRARIES:
- -test -z "$(ipsec_LTLIBRARIES)" || rm -f $(ipsec_LTLIBRARIES)
- @list='$(ipsec_LTLIBRARIES)'; for p in $$list; do \
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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
libchecksum.la: $(libchecksum_la_OBJECTS) $(libchecksum_la_DEPENDENCIES)
- $(libchecksum_la_LINK) -rpath $(ipsecdir) $(libchecksum_la_OBJECTS) $(libchecksum_la_LIBADD) $(LIBS)
+ $(libchecksum_la_LINK) $(libchecksum_la_OBJECTS) $(libchecksum_la_LIBADD) $(LIBS)
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
@@ -513,15 +551,13 @@ distdir: $(DISTFILES)
fi; \
done
check-am: all-am
-check: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) check-am
+check: check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
installdirs:
- for dir in "$(DESTDIR)$(ipsecdir)"; do \
+ for dir in "$(DESTDIR)$(ipseclibdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
-install: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) install-am
+install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
@@ -547,11 +583,10 @@ distclean-generic:
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
- -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am
-clean-am: clean-generic clean-ipsecLTLIBRARIES clean-libtool \
- clean-noinstPROGRAMS mostlyclean-am
+clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
+ clean-local clean-noinstPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
@@ -571,8 +606,9 @@ info: info-am
info-am:
-install-data-am: install-ipsecLTLIBRARIES
-
+install-data-am: install-ipseclibLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
install-dvi: install-dvi-am
install-dvi-am:
@@ -617,28 +653,39 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-ipsecLTLIBRARIES
-
-.MAKE: all check install install-am install-strip
+uninstall-am: uninstall-ipseclibLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
+.MAKE: install-am install-data-am install-strip uninstall-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-ipsecLTLIBRARIES clean-libtool clean-noinstPROGRAMS \
- 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-ipsecLTLIBRARIES install-man \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am \
- uninstall-ipsecLTLIBRARIES
-
-
-checksum.c : checksum_builder $(libs)
- ./checksum_builder $(libs) > checksum.c
+ clean-ipseclibLTLIBRARIES clean-libtool clean-local \
+ clean-noinstPROGRAMS 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-data-hook install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
+ install-ipseclibLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-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-hook \
+ uninstall-ipseclibLTLIBRARIES
+
+
+checksum.c : checksum_builder $(deps) $(exes)
+ ./checksum_builder $(libs) $(exes) > checksum.c
+
+install-data-hook : $(EXTRA_LTLIBRARIES)
+ $(MAKE) $(AM_MAKEFLAGS) LIBCHECKSUM_LIBS='$(EXTRA_LTLIBRARIES)' install-ipseclibLTLIBRARIES
+
+uninstall-hook :
+ $(MAKE) $(AM_MAKEFLAGS) LIBCHECKSUM_LIBS='$(EXTRA_LTLIBRARIES)' uninstall-ipseclibLTLIBRARIES
+
+clean-local :
+ $(MAKE) $(AM_MAKEFLAGS) LIBCHECKSUM_LIBS='$(EXTRA_LTLIBRARIES)' clean-ipseclibLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/checksum/checksum_builder.c b/src/checksum/checksum_builder.c
index dc1de99c3..670ec76bd 100644
--- a/src/checksum/checksum_builder.c
+++ b/src/checksum/checksum_builder.c
@@ -19,6 +19,8 @@
#include <dlfcn.h>
#include <library.h>
+#include <hydra.h>
+#include <daemon.h>
#include <utils/enumerator.h>
/* we need to fake the pluto symbol to dlopen() the xauth plugin */
@@ -62,16 +64,16 @@ static void build_checksum(char *path, char *name, char *sname)
fprintf(stderr, "dlopen failed: %s\n", dlerror());
}
}
- printf("\t{\"%-20s%7u, 0x%08x, %6u, 0x%08x},\n",
+ printf("\t{\"%-25s%7u, 0x%08x, %6u, 0x%08x},\n",
name, fsize, fsum, ssize, ssum);
- fprintf(stderr, "\"%-20s%7u / 0x%08x %6u / 0x%08x\n",
+ fprintf(stderr, "\"%-25s%7u / 0x%08x %6u / 0x%08x\n",
name, fsize, fsum, ssize, ssum);
}
/**
- * Build checksums for a set of plugins in a given path prefix
+ * Build checksums for a set of plugins
*/
-static void build_plugin_checksums(char *plugins, char *prefix)
+static void build_plugin_checksums(char *plugins)
{
enumerator_t *enumerator;
char *plugin, path[256], under[128], sname[128], name[128];
@@ -81,8 +83,8 @@ static void build_plugin_checksums(char *plugins, char *prefix)
{
snprintf(under, sizeof(under), "%s", plugin);
translate(under, "-", "_");
- snprintf(path, sizeof(path), "%s/%s/.libs/libstrongswan-%s.so",
- prefix, under, plugin);
+ snprintf(path, sizeof(path), "%s/libstrongswan-%s.so",
+ PLUGINDIR, plugin);
snprintf(sname, sizeof(sname), "%s_plugin_create", under);
snprintf(name, sizeof(name), "%s\",", plugin);
build_checksum(path, name, sname);
@@ -127,9 +129,15 @@ int main(int argc, char* argv[])
{
int i;
+ /* forces link against libhydra/libcharon, imports symbols needed to
+ * dlopen plugins */
+ hydra = NULL;
+ charon = NULL;
+
/* avoid confusing leak reports in build process */
setenv("LEAK_DETECTIVE_DISABLE", "1", 0);
- library_init(NULL);
+ /* don't use a strongswan.conf, forces integrity check to disabled */
+ library_init("");
atexit(library_deinit);
integrity = integrity_checker_create(NULL);
@@ -143,15 +151,24 @@ int main(int argc, char* argv[])
printf("\n");
printf("integrity_checksum_t checksums[] = {\n");
fprintf(stderr, "integrity test data:\n");
- fprintf(stderr, "module name, file size / checksum segment size / checksum\n");
+ fprintf(stderr, "module name, file size / checksum "
+ "segment size / checksum\n");
for (i = 1; i < argc; i++)
{
build_binary_checksum(argv[i]);
}
- build_plugin_checksums(S_PLUGINS, S_PATH);
- build_plugin_checksums(H_PLUGINS, H_PATH);
- build_plugin_checksums(P_PLUGINS, P_PATH);
- build_plugin_checksums(C_PLUGINS, C_PATH);
+#ifdef S_PLUGINS
+ build_plugin_checksums(S_PLUGINS);
+#endif
+#ifdef H_PLUGINS
+ build_plugin_checksums(H_PLUGINS);
+#endif
+#ifdef P_PLUGINS
+ build_plugin_checksums(P_PLUGINS);
+#endif
+#ifdef C_PLUGINS
+ build_plugin_checksums(C_PLUGINS);
+#endif
printf("};\n");
printf("\n");
diff --git a/src/conftest/Makefile.in b/src/conftest/Makefile.in
index a89df8f27..4efdeaad5 100644
--- a/src/conftest/Makefile.in
+++ b/src/conftest/Makefile.in
@@ -182,6 +182,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -190,6 +193,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -206,11 +210,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -254,6 +260,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/conftest/actions.c b/src/conftest/actions.c
index e66e9d7f1..7532e95cf 100644
--- a/src/conftest/actions.c
+++ b/src/conftest/actions.c
@@ -65,7 +65,7 @@ static job_requeue_t initiate(char *config)
{
DBG1(DBG_CFG, "initiating IKE_SA for CHILD_SA config '%s'", config);
charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
- NULL, NULL);
+ NULL, NULL, 0);
}
else
{
@@ -85,7 +85,8 @@ static job_requeue_t rekey_ike(char *config)
job_t *job = NULL;
ike_sa_t *ike_sa;
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (strcaseeq(config, ike_sa->get_name(ike_sa)))
@@ -113,18 +114,18 @@ static job_requeue_t rekey_ike(char *config)
*/
static job_requeue_t rekey_child(char *config)
{
- enumerator_t *enumerator;
- iterator_t *children;
+ enumerator_t *enumerator, *children;
ike_sa_t *ike_sa;
child_sa_t *child_sa;
u_int32_t reqid = 0, spi = 0;
protocol_id_t proto = PROTO_ESP;
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
+ children = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (children->enumerate(children, (void**)&child_sa))
{
if (streq(config, child_sa->get_name(child_sa)))
{
@@ -159,7 +160,8 @@ static job_requeue_t liveness(char *config)
job_t *job = NULL;
ike_sa_t *ike_sa;
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (strcaseeq(config, ike_sa->get_name(ike_sa)))
@@ -191,7 +193,8 @@ static job_requeue_t close_ike(char *config)
ike_sa_t *ike_sa;
int id = 0;
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (strcaseeq(config, ike_sa->get_name(ike_sa)))
@@ -204,7 +207,7 @@ static job_requeue_t close_ike(char *config)
if (id)
{
DBG1(DBG_CFG, "closing IKE_SA '%s'", config);
- charon->controller->terminate_ike(charon->controller, id, NULL, NULL);
+ charon->controller->terminate_ike(charon->controller, id, NULL, NULL, 0);
}
else
{
@@ -218,18 +221,18 @@ static job_requeue_t close_ike(char *config)
*/
static job_requeue_t close_child(char *config)
{
- enumerator_t *enumerator;
- iterator_t *children;
+ enumerator_t *enumerator, *children;
ike_sa_t *ike_sa;
child_sa_t *child_sa;
int id = 0;
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
+ children = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (children->enumerate(children, (void**)&child_sa))
{
if (streq(config, child_sa->get_name(child_sa)))
{
@@ -243,7 +246,8 @@ static job_requeue_t close_child(char *config)
if (id)
{
DBG1(DBG_CFG, "closing CHILD_SA '%s'", config);
- charon->controller->terminate_child(charon->controller, id, NULL, NULL);
+ charon->controller->terminate_child(charon->controller, id,
+ NULL, NULL, 0);
}
else
{
diff --git a/src/dumm/Makefile.am b/src/dumm/Makefile.am
index b7fb3f7c8..8b8cebcd8 100644
--- a/src/dumm/Makefile.am
+++ b/src/dumm/Makefile.am
@@ -1,7 +1,7 @@
EXTRA_DIST = ext/dumm.c ext/README \
ext/lib/dumm.rb ext/lib/dumm/guest.rb
-lib_LTLIBRARIES = libdumm.la
+ipseclib_LTLIBRARIES = libdumm.la
ipsec_PROGRAMS = dumm irdumm
libdumm_la_SOURCES = dumm.c dumm.h guest.c guest.h iface.c iface.h \
@@ -9,10 +9,9 @@ libdumm_la_SOURCES = dumm.c dumm.h guest.c guest.h iface.c iface.h \
dumm_SOURCES = main.c
irdumm_SOURCES = irdumm.c
-libdumm_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
- -lbridge -lfuse -lutil
-dumm_LDADD = libdumm.la ${gtk_LIBS}
-irdumm_LDADD = libdumm.la -lruby1.8
+libdumm_la_LIBADD = -lbridge -lfuse -lutil $(top_builddir)/src/libstrongswan/libstrongswan.la
+dumm_LDADD = libdumm.la ${gtk_LIBS} $(top_builddir)/src/libstrongswan/libstrongswan.la
+irdumm_LDADD = libdumm.la -lruby1.8 $(top_builddir)/src/libstrongswan/libstrongswan.la
INCLUDES = -I$(top_srcdir)/src/libstrongswan ${gtk_CFLAGS} \
${RUBYINCLUDE}
diff --git a/src/dumm/Makefile.in b/src/dumm/Makefile.in
index 4a8f142ca..bd172b701 100644
--- a/src/dumm/Makefile.in
+++ b/src/dumm/Makefile.in
@@ -74,8 +74,8 @@ am__nobase_list = $(am__nobase_strip_setup); \
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)$(libdir)" "$(DESTDIR)$(ipsecdir)"
-LTLIBRARIES = $(lib_LTLIBRARIES)
+am__installdirs = "$(DESTDIR)$(ipseclibdir)" "$(DESTDIR)$(ipsecdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
libdumm_la_DEPENDENCIES = \
$(top_builddir)/src/libstrongswan/libstrongswan.la
am_libdumm_la_OBJECTS = dumm.lo guest.lo iface.lo bridge.lo \
@@ -85,10 +85,12 @@ PROGRAMS = $(ipsec_PROGRAMS)
am_dumm_OBJECTS = main.$(OBJEXT)
dumm_OBJECTS = $(am_dumm_OBJECTS)
am__DEPENDENCIES_1 =
-dumm_DEPENDENCIES = libdumm.la $(am__DEPENDENCIES_1)
+dumm_DEPENDENCIES = libdumm.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
am_irdumm_OBJECTS = irdumm.$(OBJEXT)
irdumm_OBJECTS = $(am_irdumm_OBJECTS)
-irdumm_DEPENDENCIES = libdumm.la
+irdumm_DEPENDENCIES = libdumm.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -198,6 +200,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -206,6 +211,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -222,11 +228,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -270,6 +278,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -283,17 +292,15 @@ xml_LIBS = @xml_LIBS@
EXTRA_DIST = ext/dumm.c ext/README \
ext/lib/dumm.rb ext/lib/dumm/guest.rb
-lib_LTLIBRARIES = libdumm.la
+ipseclib_LTLIBRARIES = libdumm.la
libdumm_la_SOURCES = dumm.c dumm.h guest.c guest.h iface.c iface.h \
bridge.c bridge.h mconsole.c mconsole.h cowfs.h cowfs.c
dumm_SOURCES = main.c
irdumm_SOURCES = irdumm.c
-libdumm_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
- -lbridge -lfuse -lutil
-
-dumm_LDADD = libdumm.la ${gtk_LIBS}
-irdumm_LDADD = libdumm.la -lruby1.8
+libdumm_la_LIBADD = -lbridge -lfuse -lutil $(top_builddir)/src/libstrongswan/libstrongswan.la
+dumm_LDADD = libdumm.la ${gtk_LIBS} $(top_builddir)/src/libstrongswan/libstrongswan.la
+irdumm_LDADD = libdumm.la -lruby1.8 $(top_builddir)/src/libstrongswan/libstrongswan.la
INCLUDES = -I$(top_srcdir)/src/libstrongswan ${gtk_CFLAGS} \
${RUBYINCLUDE}
@@ -332,39 +339,39 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(libdir)'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
}
-uninstall-libLTLIBRARIES:
+uninstall-ipseclibLTLIBRARIES:
@$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
done
-clean-libLTLIBRARIES:
- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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
libdumm.la: $(libdumm_la_OBJECTS) $(libdumm_la_DEPENDENCIES)
- $(LINK) -rpath $(libdir) $(libdumm_la_OBJECTS) $(libdumm_la_LIBADD) $(LIBS)
+ $(LINK) -rpath $(ipseclibdir) $(libdumm_la_OBJECTS) $(libdumm_la_LIBADD) $(LIBS)
install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(ipsecdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsecdir)"
@@ -543,7 +550,7 @@ check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) all-local
installdirs:
- for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(ipsecdir)"; do \
+ for dir in "$(DESTDIR)$(ipseclibdir)" "$(DESTDIR)$(ipsecdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -573,7 +580,7 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-ipsecPROGRAMS clean-libLTLIBRARIES \
+clean-am: clean-generic clean-ipsecPROGRAMS clean-ipseclibLTLIBRARIES \
clean-libtool clean-local mostlyclean-am
distclean: distclean-am
@@ -594,13 +601,14 @@ info: info-am
info-am:
-install-data-am: install-data-local install-ipsecPROGRAMS
+install-data-am: install-data-local install-ipsecPROGRAMS \
+ install-ipseclibLTLIBRARIES
install-dvi: install-dvi-am
install-dvi-am:
-install-exec-am: install-libLTLIBRARIES
+install-exec-am:
install-html: install-html-am
@@ -640,25 +648,25 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-ipsecPROGRAMS uninstall-libLTLIBRARIES
+uninstall-am: uninstall-ipsecPROGRAMS uninstall-ipseclibLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am all-local check check-am clean \
- clean-generic clean-ipsecPROGRAMS clean-libLTLIBRARIES \
+ clean-generic clean-ipsecPROGRAMS clean-ipseclibLTLIBRARIES \
clean-libtool clean-local 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-data-local install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am \
- install-ipsecPROGRAMS install-libLTLIBRARIES install-man \
+ install-ipsecPROGRAMS install-ipseclibLTLIBRARIES install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \
- uninstall-ipsecPROGRAMS uninstall-libLTLIBRARIES
+ uninstall-ipsecPROGRAMS uninstall-ipseclibLTLIBRARIES
all-local: ext
diff --git a/src/dumm/bridge.c b/src/dumm/bridge.c
index 9c63beed9..85b6471b6 100644
--- a/src/dumm/bridge.c
+++ b/src/dumm/bridge.c
@@ -37,26 +37,20 @@ struct private_bridge_t {
*/
bool iface_control(char *name, bool up);
-/**
- * Implementation of bridge_t.get_name.
- */
-static char* get_name(private_bridge_t *this)
+METHOD(bridge_t, get_name, char*,
+ private_bridge_t *this)
{
return this->name;
}
-/**
- * Implementation of bridge_t.create_iface_enumerator.
- */
-static enumerator_t* create_iface_enumerator(private_bridge_t *this)
+METHOD(bridge_t, create_iface_enumerator, enumerator_t*,
+ private_bridge_t *this)
{
return this->ifaces->create_enumerator(this->ifaces);
}
-/**
- * Implementation of bridge_t.disconnect_iface.
- */
-static bool disconnect_iface(private_bridge_t *this, iface_t *iface)
+METHOD(bridge_t, disconnect_iface, bool,
+ private_bridge_t *this, iface_t *iface)
{
enumerator_t *enumerator;
iface_t *current = NULL;
@@ -90,10 +84,8 @@ static bool disconnect_iface(private_bridge_t *this, iface_t *iface)
return good;
}
-/**
- * Implementation of bridge_t.connect_iface.
- */
-static bool connect_iface(private_bridge_t *this, iface_t *iface)
+METHOD(bridge_t, connect_iface, bool,
+ private_bridge_t *this, iface_t *iface)
{
if (br_add_interface(this->name, iface->get_hostif(iface)) != 0)
{
@@ -111,10 +103,8 @@ static bool connect_iface(private_bridge_t *this, iface_t *iface)
*/
static int instances = 0;
-/**
- * Implementation of bridge_t.destroy.
- */
-static void destroy(private_bridge_t *this)
+METHOD(bridge_t, destroy, void,
+ private_bridge_t *this)
{
enumerator_t *enumerator;
iface_t *iface;
@@ -161,12 +151,15 @@ bridge_t *bridge_create(char *name)
}
}
- this = malloc_thing(private_bridge_t);
- this->public.get_name = (char*(*)(bridge_t*))get_name;
- this->public.create_iface_enumerator = (enumerator_t*(*)(bridge_t*))create_iface_enumerator;
- this->public.disconnect_iface = (bool(*)(bridge_t*, iface_t *iface))disconnect_iface;
- this->public.connect_iface = (bool(*)(bridge_t*, iface_t *iface))connect_iface;
- this->public.destroy = (void*)destroy;
+ INIT(this,
+ .public = {
+ .get_name = _get_name,
+ .create_iface_enumerator = _create_iface_enumerator,
+ .disconnect_iface = _disconnect_iface,
+ .connect_iface = _connect_iface,
+ .destroy = _destroy,
+ }
+ );
if (br_add_bridge(name) != 0)
{
diff --git a/src/dumm/cowfs.c b/src/dumm/cowfs.c
index b92be53e0..f708a293b 100644
--- a/src/dumm/cowfs.c
+++ b/src/dumm/cowfs.c
@@ -835,10 +835,8 @@ static struct fuse_operations cowfs_operations = {
.init = cowfs_init,
};
-/**
- * Implementation of cowfs_t.add_overlay.
- */
-static bool add_overlay(private_cowfs_t *this, char *path)
+METHOD(cowfs_t, add_overlay, bool,
+ private_cowfs_t *this, char *path)
{
overlay_t *over = malloc_thing(overlay_t);
over->fd = open(path, O_RDONLY | O_DIRECTORY);
@@ -856,10 +854,8 @@ static bool add_overlay(private_cowfs_t *this, char *path)
return TRUE;
}
-/**
- * Implementation of cowfs_t.del_overlay.
- */
-static bool del_overlay(private_cowfs_t *this, char *path)
+METHOD(cowfs_t, del_overlay, bool,
+ private_cowfs_t *this, char *path)
{
bool removed;
char real[PATH_MAX];
@@ -869,10 +865,8 @@ static bool del_overlay(private_cowfs_t *this, char *path)
return removed;
}
-/**
- * Implementation of cowfs_t.pop_overlay.
- */
-static bool pop_overlay(private_cowfs_t *this)
+METHOD(cowfs_t, pop_overlay, bool,
+ private_cowfs_t *this)
{
overlay_t *over;
this->lock->write_lock(this->lock);
@@ -886,10 +880,8 @@ static bool pop_overlay(private_cowfs_t *this)
return TRUE;
}
-/**
- * stop, umount and destroy a cowfs FUSE filesystem
- */
-static void destroy(private_cowfs_t *this)
+METHOD(cowfs_t, destroy, void,
+ private_cowfs_t *this)
{
fuse_exit(this->fuse);
fuse_unmount(this->mount, this->chan);
@@ -911,12 +903,16 @@ static void destroy(private_cowfs_t *this)
cowfs_t *cowfs_create(char *master, char *host, char *mount)
{
struct fuse_args args = {0, NULL, 0};
- private_cowfs_t *this = malloc_thing(private_cowfs_t);
-
- this->public.add_overlay = (bool(*)(cowfs_t*, char *path))add_overlay;
- this->public.del_overlay = (bool(*)(cowfs_t*, char *path))del_overlay;
- this->public.pop_overlay = (bool(*)(cowfs_t*))pop_overlay;
- this->public.destroy = (void(*)(cowfs_t*))destroy;
+ private_cowfs_t *this;
+
+ INIT(this,
+ .public = {
+ .add_overlay = _add_overlay,
+ .del_overlay = _del_overlay,
+ .pop_overlay = _pop_overlay,
+ .destroy = _destroy,
+ }
+ );
this->master_fd = open(master, O_RDONLY | O_DIRECTORY);
if (this->master_fd < 0)
diff --git a/src/dumm/dumm.c b/src/dumm/dumm.c
index 8cd413519..59751fa09 100644
--- a/src/dumm/dumm.c
+++ b/src/dumm/dumm.c
@@ -49,11 +49,8 @@ struct private_dumm_t {
linked_list_t *bridges;
};
-/**
- * Implementation of dumm_t.create_guest.
- */
-static guest_t* create_guest(private_dumm_t *this, char *name, char *kernel,
- char *master, char *args)
+METHOD(dumm_t, create_guest, guest_t*,
+ private_dumm_t *this, char *name, char *kernel, char *master, char *args)
{
guest_t *guest;
@@ -65,18 +62,14 @@ static guest_t* create_guest(private_dumm_t *this, char *name, char *kernel,
return guest;
}
-/**
- * Implementation of dumm_t.create_guest_enumerator.
- */
-static enumerator_t* create_guest_enumerator(private_dumm_t *this)
+METHOD(dumm_t, create_guest_enumerator, enumerator_t*,
+ private_dumm_t *this)
{
return this->guests->create_enumerator(this->guests);
}
-/**
- * Implementation of dumm_t.delete_guest.
- */
-static void delete_guest(private_dumm_t *this, guest_t *guest)
+METHOD(dumm_t, delete_guest, void,
+ private_dumm_t *this, guest_t *guest)
{
if (this->guests->remove(this->guests, guest, NULL))
{
@@ -93,10 +86,8 @@ static void delete_guest(private_dumm_t *this, guest_t *guest)
}
}
-/**
- * Implementation of dumm_t.create_bridge.
- */
-static bridge_t* create_bridge(private_dumm_t *this, char *name)
+METHOD(dumm_t, create_bridge, bridge_t*,
+ private_dumm_t *this, char *name)
{
bridge_t *bridge;
@@ -108,18 +99,14 @@ static bridge_t* create_bridge(private_dumm_t *this, char *name)
return bridge;
}
-/**
- * Implementation of dumm_t.create_bridge_enumerator.
- */
-static enumerator_t* create_bridge_enumerator(private_dumm_t *this)
+METHOD(dumm_t, create_bridge_enumerator, enumerator_t*,
+ private_dumm_t *this)
{
return this->bridges->create_enumerator(this->bridges);
}
-/**
- * Implementation of dumm_t.delete_bridge.
- */
-static void delete_bridge(private_dumm_t *this, bridge_t *bridge)
+METHOD(dumm_t, delete_bridge, void,
+ private_dumm_t *this, bridge_t *bridge)
{
if (this->bridges->remove(this->bridges, bridge, NULL))
{
@@ -127,10 +114,8 @@ static void delete_bridge(private_dumm_t *this, bridge_t *bridge)
}
}
-/**
- * Implementation of dumm_t.add_overlay.
- */
-static bool add_overlay(private_dumm_t *this, char *dir)
+METHOD(dumm_t, add_overlay, bool,
+ private_dumm_t *this, char *dir)
{
enumerator_t *enumerator;
guest_t *guest;
@@ -184,10 +169,8 @@ error:
return FALSE;
}
-/**
- * Implementation of dumm_t.del_overlay.
- */
-static bool del_overlay(private_dumm_t *this, char *dir)
+METHOD(dumm_t, del_overlay, bool,
+ private_dumm_t *this, char *dir)
{
bool ret = FALSE;
enumerator_t *enumerator;
@@ -209,10 +192,8 @@ static bool del_overlay(private_dumm_t *this, char *dir)
return ret;
}
-/**
- * Implementation of dumm_t.pop_overlay.
- */
-static bool pop_overlay(private_dumm_t *this)
+METHOD(dumm_t, pop_overlay, bool,
+ private_dumm_t *this)
{
bool ret = FALSE;
enumerator_t *enumerator;
@@ -240,10 +221,8 @@ static void clear_template(private_dumm_t *this)
}
}
-/**
- * Implementation of dumm_t.load_template.
- */
-static bool load_template(private_dumm_t *this, char *name)
+METHOD(dumm_t, load_template, bool,
+ private_dumm_t *this, char *name)
{
clear_template(this);
if (name == NULL)
@@ -287,10 +266,8 @@ typedef struct {
enumerator_t *inner;
} template_enumerator_t;
-/**
- * Implementation of template_enumerator_t.enumerate.
- */
-static bool template_enumerate(template_enumerator_t *this, char **template)
+METHOD(enumerator_t, template_enumerate, bool,
+ template_enumerator_t *this, char **template)
{
struct stat st;
char *rel;
@@ -306,25 +283,24 @@ static bool template_enumerate(template_enumerator_t *this, char **template)
return FALSE;
}
-/**
- * Implementation of template_enumerator_t.destroy.
- */
-static void template_enumerator_destroy(template_enumerator_t *this)
+METHOD(enumerator_t, template_enumerator_destroy, void,
+ template_enumerator_t *this)
{
this->inner->destroy(this->inner);
free(this);
}
-/**
- * Implementation of dumm_t.create_template_enumerator.
- */
-static enumerator_t* create_template_enumerator(private_dumm_t *this)
+METHOD(dumm_t, create_template_enumerator, enumerator_t*,
+ private_dumm_t *this)
{
template_enumerator_t *enumerator;
- enumerator = malloc_thing(template_enumerator_t);
- enumerator->public.enumerate = (void*)template_enumerate;
- enumerator->public.destroy = (void*)template_enumerator_destroy;
- enumerator->inner = enumerator_create_directory(TEMPLATE_DIR);
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)_template_enumerate,
+ .destroy = (void*)_template_enumerator_destroy,
+ },
+ .inner = enumerator_create_directory(TEMPLATE_DIR),
+ );
if (!enumerator->inner)
{
free(enumerator);
@@ -333,10 +309,8 @@ static enumerator_t* create_template_enumerator(private_dumm_t *this)
return &enumerator->public;
}
-/**
- * Implementation of dumm_t.destroy.
- */
-static void destroy(private_dumm_t *this)
+METHOD(dumm_t, destroy, void,
+ private_dumm_t *this)
{
enumerator_t *enumerator;
guest_t *guest;
@@ -402,20 +376,24 @@ static void load_guests(private_dumm_t *this)
dumm_t *dumm_create(char *dir)
{
char cwd[PATH_MAX];
- private_dumm_t *this = malloc_thing(private_dumm_t);
-
- this->public.create_guest = (guest_t*(*)(dumm_t*,char*,char*,char*,char*))create_guest;
- this->public.create_guest_enumerator = (enumerator_t*(*)(dumm_t*))create_guest_enumerator;
- this->public.delete_guest = (void(*)(dumm_t*,guest_t*))delete_guest;
- this->public.create_bridge = (bridge_t*(*)(dumm_t*, char *name))create_bridge;
- this->public.create_bridge_enumerator = (enumerator_t*(*)(dumm_t*))create_bridge_enumerator;
- this->public.delete_bridge = (void(*)(dumm_t*,bridge_t*))delete_bridge;
- this->public.add_overlay = (bool(*)(dumm_t*,char*))add_overlay;
- this->public.del_overlay = (bool(*)(dumm_t*,char*))del_overlay;
- this->public.pop_overlay = (bool(*)(dumm_t*))pop_overlay;
- this->public.load_template = (bool(*)(dumm_t*,char*))load_template;
- this->public.create_template_enumerator = (enumerator_t*(*)(dumm_t*))create_template_enumerator;
- this->public.destroy = (void(*)(dumm_t*))destroy;
+ private_dumm_t *this;
+
+ INIT(this,
+ .public = {
+ .create_guest = _create_guest,
+ .create_guest_enumerator = _create_guest_enumerator,
+ .delete_guest = _delete_guest,
+ .create_bridge = _create_bridge,
+ .create_bridge_enumerator = _create_bridge_enumerator,
+ .delete_bridge = _delete_bridge,
+ .add_overlay = _add_overlay,
+ .del_overlay = _del_overlay,
+ .pop_overlay = _pop_overlay,
+ .load_template = _load_template,
+ .create_template_enumerator = _create_template_enumerator,
+ .destroy = _destroy,
+ },
+ );
if (dir && *dir == '/')
{
@@ -440,11 +418,11 @@ dumm_t *dumm_create(char *dir)
this->dir = strdup(cwd);
}
}
- this->template = NULL;
if (asprintf(&this->guest_dir, "%s/%s", this->dir, GUEST_DIR) < 0)
{
this->guest_dir = NULL;
}
+
this->guests = linked_list_create();
this->bridges = linked_list_create();
diff --git a/src/dumm/ext/dumm.c b/src/dumm/ext/dumm.c
index a9c7cb8bd..ca9b29388 100644
--- a/src/dumm/ext/dumm.c
+++ b/src/dumm/ext/dumm.c
@@ -594,21 +594,22 @@ static VALUE iface_add_addr(VALUE self, VALUE name)
{
iface_t *iface;
host_t *addr;
+ int bits;
- addr = host_create_from_string(StringValuePtr(name), 0);
+ addr = host_create_from_subnet(StringValuePtr(name), &bits);
if (!addr)
{
rb_raise(rb_eArgError, "invalid IP address");
}
Data_Get_Struct(self, iface_t, iface);
- if (!iface->add_address(iface, addr))
+ if (!iface->add_address(iface, addr, bits))
{
addr->destroy(addr);
rb_raise(rb_eRuntimeError, "adding address failed");
}
if (rb_block_given_p()) {
rb_yield(self);
- iface->delete_address(iface, addr);
+ iface->delete_address(iface, addr, bits);
}
addr->destroy(addr);
return self;
@@ -647,21 +648,22 @@ static VALUE iface_del_addr(VALUE self, VALUE vaddr)
{
iface_t *iface;
host_t *addr;
+ int bits;
- addr = host_create_from_string(StringValuePtr(vaddr), 0);
+ addr = host_create_from_subnet(StringValuePtr(vaddr), &bits);
if (!addr)
{
rb_raise(rb_eArgError, "invalid IP address");
}
Data_Get_Struct(self, iface_t, iface);
- if (!iface->delete_address(iface, addr))
+ if (!iface->delete_address(iface, addr, bits))
{
addr->destroy(addr);
rb_raise(rb_eRuntimeError, "address not found");
}
if (rb_block_given_p()) {
rb_yield(self);
- iface->add_address(iface, addr);
+ iface->add_address(iface, addr, bits);
}
addr->destroy(addr);
return self;
diff --git a/src/dumm/guest.c b/src/dumm/guest.c
index 36d048dcf..336f6effa 100644
--- a/src/dumm/guest.c
+++ b/src/dumm/guest.c
@@ -82,18 +82,14 @@ ENUM(guest_state_names, GUEST_STOPPED, GUEST_STOPPING,
"STOPPING",
);
-/**
- * Implementation of guest_t.get_name.
- */
-static char* get_name(private_guest_t *this)
+METHOD(guest_t, get_name, char*,
+ private_guest_t *this)
{
return this->name;
}
-/**
- * Implementation of guest_t.create_iface.
- */
-static iface_t* create_iface(private_guest_t *this, char *name)
+METHOD(guest_t, create_iface, iface_t*,
+ private_guest_t *this, char *name)
{
enumerator_t *enumerator;
iface_t *iface;
@@ -126,10 +122,8 @@ static iface_t* create_iface(private_guest_t *this, char *name)
return iface;
}
-/**
- * Implementation of guest_t.destroy_iface.
- */
-static void destroy_iface(private_guest_t *this, iface_t *iface)
+METHOD(guest_t, destroy_iface, void,
+ private_guest_t *this, iface_t *iface)
{
enumerator_t *enumerator;
iface_t *current;
@@ -147,26 +141,20 @@ static void destroy_iface(private_guest_t *this, iface_t *iface)
enumerator->destroy(enumerator);
}
-/**
- * Implementation of guest_t.create_iface_enumerator.
- */
-static enumerator_t* create_iface_enumerator(private_guest_t *this)
+METHOD(guest_t, create_iface_enumerator, enumerator_t*,
+ private_guest_t *this)
{
return this->ifaces->create_enumerator(this->ifaces);
}
-/**
- * Implementation of guest_t.get_state.
- */
-static guest_state_t get_state(private_guest_t *this)
+METHOD(guest_t, get_state, guest_state_t,
+ private_guest_t *this)
{
return this->state;
}
-/**
- * Implementation of guest_t.get_pid.
- */
-static pid_t get_pid(private_guest_t *this)
+METHOD(guest_t, get_pid, pid_t,
+ private_guest_t *this)
{
return this->pid;
}
@@ -193,10 +181,8 @@ static char* write_arg(char **pos, size_t *left, char *format, ...)
return res;
}
-/**
- * Implementation of guest_t.stop.
- */
-static void stop(private_guest_t *this, idle_function_t idle)
+METHOD(guest_t, stop, void,
+ private_guest_t *this, idle_function_t idle)
{
if (this->state != GUEST_STOPPED)
{
@@ -236,11 +222,9 @@ void savepid(private_guest_t *this)
}
}
-/**
- * Implementation of guest_t.start.
- */
-static bool start(private_guest_t *this, invoke_function_t invoke, void* data,
- idle_function_t idle)
+METHOD(guest_t, start, bool,
+ private_guest_t *this, invoke_function_t invoke, void* data,
+ idle_function_t idle)
{
char buf[2048];
char *notify;
@@ -296,10 +280,8 @@ static bool start(private_guest_t *this, invoke_function_t invoke, void* data,
return TRUE;
}
-/**
- * Implementation of guest_t.add_overlay.
- */
-static bool add_overlay(private_guest_t *this, char *path)
+METHOD(guest_t, add_overlay, bool,
+ private_guest_t *this, char *path)
{
if (path == NULL)
{
@@ -319,18 +301,14 @@ static bool add_overlay(private_guest_t *this, char *path)
return this->cowfs->add_overlay(this->cowfs, path);
}
-/**
- * Implementation of guest_t.del_overlay.
- */
-static bool del_overlay(private_guest_t *this, char *path)
+METHOD(guest_t, del_overlay, bool,
+ private_guest_t *this, char *path)
{
return this->cowfs->del_overlay(this->cowfs, path);
}
-/**
- * Implementation of guest_t.pop_overlay.
- */
-static bool pop_overlay(private_guest_t *this)
+METHOD(guest_t, pop_overlay, bool,
+ private_guest_t *this)
{
return this->cowfs->pop_overlay(this->cowfs);
}
@@ -356,11 +334,9 @@ static int vexec(private_guest_t *this, void(*cb)(void*,char*,size_t), void *dat
return -1;
}
-/**
- * Implementation of guest_t.exec
- */
-static int exec(private_guest_t *this, void(*cb)(void*,char*,size_t), void *data,
- char *cmd, ...)
+METHOD(guest_t, exec, int,
+ private_guest_t *this, void(*cb)(void*,char*,size_t), void *data,
+ char *cmd, ...)
{
int res;
va_list args;
@@ -411,11 +387,9 @@ static void exec_str_cb(exec_str_t *data, char *buf, size_t len)
}
}
-/**
- * Implementation of guest_t.exec_str
- */
-static int exec_str(private_guest_t *this, void(*cb)(void*,char*), bool lines,
- void *data, char *cmd, ...)
+METHOD(guest_t, exec_str, int,
+ private_guest_t *this, void(*cb)(void*,char*), bool lines, void *data,
+ char *cmd, ...)
{
int res;
va_list args;
@@ -448,10 +422,8 @@ static int exec_str(private_guest_t *this, void(*cb)(void*,char*), bool lines,
return res;
}
-/**
- * Implementation of guest_t.sigchild.
- */
-static void sigchild(private_guest_t *this)
+METHOD(guest_t, sigchild, void,
+ private_guest_t *this)
{
DESTROY_IF(this->mconsole);
this->mconsole = NULL;
@@ -537,10 +509,8 @@ bool saveargs(private_guest_t *this, char *args)
return retval;
}
-/**
- * Implementation of guest_t.destroy.
- */
-static void destroy(private_guest_t *this)
+METHOD(guest_t, destroy, void,
+ private_guest_t *this)
{
stop(this, NULL);
umount_unionfs(this);
@@ -562,23 +532,27 @@ static private_guest_t *guest_create_generic(char *parent, char *name,
bool create)
{
char cwd[PATH_MAX];
- private_guest_t *this = malloc_thing(private_guest_t);
-
- this->public.get_name = (void*)get_name;
- this->public.get_pid = (pid_t(*)(guest_t*))get_pid;
- this->public.get_state = (guest_state_t(*)(guest_t*))get_state;
- this->public.create_iface = (iface_t*(*)(guest_t*,char*))create_iface;
- this->public.destroy_iface = (void(*)(guest_t*,iface_t*))destroy_iface;
- this->public.create_iface_enumerator = (enumerator_t*(*)(guest_t*))create_iface_enumerator;
- this->public.start = (void*)start;
- this->public.stop = (void*)stop;
- this->public.add_overlay = (bool(*)(guest_t*,char*))add_overlay;
- this->public.del_overlay = (bool(*)(guest_t*,char*))del_overlay;
- this->public.pop_overlay = (bool(*)(guest_t*))pop_overlay;
- this->public.exec = (int(*)(guest_t*, void(*cb)(void*,char*,size_t),void*,char*,...))exec;
- this->public.exec_str = (int(*)(guest_t*, void(*cb)(void*,char*),bool,void*,char*,...))exec_str;
- this->public.sigchild = (void(*)(guest_t*))sigchild;
- this->public.destroy = (void*)destroy;
+ private_guest_t *this;
+
+ INIT(this,
+ .public = {
+ .get_name = _get_name,
+ .get_pid = _get_pid,
+ .get_state = _get_state,
+ .create_iface = _create_iface,
+ .destroy_iface = _destroy_iface,
+ .create_iface_enumerator = _create_iface_enumerator,
+ .start = _start,
+ .stop = _stop,
+ .add_overlay = _add_overlay,
+ .del_overlay = _del_overlay,
+ .pop_overlay = _pop_overlay,
+ .exec = _exec,
+ .exec_str = _exec_str,
+ .sigchild = _sigchild,
+ .destroy = _destroy,
+ }
+ );
if (*parent == '/' || getcwd(cwd, sizeof(cwd)) == NULL)
{
@@ -611,13 +585,9 @@ static private_guest_t *guest_create_generic(char *parent, char *name,
free(this);
return NULL;
}
- this->pid = 0;
this->state = GUEST_STOPPED;
- this->mconsole = NULL;
this->ifaces = linked_list_create();
- this->args = NULL;
this->name = strdup(name);
- this->cowfs = NULL;
return this;
}
diff --git a/src/dumm/iface.c b/src/dumm/iface.c
index 1b5b7d717..214387e88 100644
--- a/src/dumm/iface.c
+++ b/src/dumm/iface.c
@@ -83,29 +83,23 @@ bool iface_control(char *name, bool up)
return good;
}
-/**
- * Implementation of iface_t.get_guestif.
- */
-static char* get_guestif(private_iface_t *this)
+METHOD(iface_t, get_guestif, char*,
+ private_iface_t *this)
{
return this->guestif;
}
-/**
- * Implementation of iface_t.get_hostif.
- */
-static char* get_hostif(private_iface_t *this)
+METHOD(iface_t, get_hostif, char*,
+ private_iface_t *this)
{
return this->hostif;
}
-/**
- * Implementation of iface_t.add_address
- */
-static bool add_address(private_iface_t *this, host_t *addr)
+METHOD(iface_t, add_address, bool,
+ private_iface_t *this, host_t *addr, int bits)
{
return (this->guest->exec(this->guest, NULL, NULL,
- "exec ip addr add %H dev %s", addr, this->guestif) == 0);
+ "exec ip addr add %H/%d dev %s", addr, bits, this->guestif) == 0);
}
/**
@@ -128,10 +122,8 @@ static void destroy_address_list(linked_list_t *list)
list->destroy_offset(list, offsetof(host_t, destroy));
}
-/**
- * Implementation of iface_t.create_address_enumerator
- */
-static enumerator_t* create_address_enumerator(private_iface_t *this)
+METHOD(iface_t, create_address_enumerator, enumerator_t*,
+ private_iface_t *this)
{
linked_list_t *addresses = linked_list_create();
this->guest->exec_str(this->guest, (void(*)(void*,char*))compile_address_list,
@@ -143,19 +135,15 @@ static enumerator_t* create_address_enumerator(private_iface_t *this)
(void(*)(void*))destroy_address_list, addresses);
}
-/**
- * Implementation of iface_t.delete_address
- */
-static bool delete_address(private_iface_t *this, host_t *addr)
+METHOD(iface_t, delete_address, bool,
+ private_iface_t *this, host_t *addr, int bits)
{
return (this->guest->exec(this->guest, NULL, NULL,
- "exec ip addr del %H dev %s", addr, this->guestif) == 0);
+ "exec ip addr del %H/%d dev %s", addr, bits, this->guestif) == 0);
}
-/**
- * Implementation of iface_t.set_bridge.
- */
-static void set_bridge(private_iface_t *this, bridge_t *bridge)
+METHOD(iface_t, set_bridge, void,
+ private_iface_t *this, bridge_t *bridge)
{
if (this->bridge == NULL && bridge)
{
@@ -170,18 +158,14 @@ static void set_bridge(private_iface_t *this, bridge_t *bridge)
this->bridge = bridge;
}
-/**
- * Implementation of iface_t.get_bridge
- */
-static bridge_t *get_bridge(private_iface_t *this)
+METHOD(iface_t, get_bridge, bridge_t*,
+ private_iface_t *this)
{
return this->bridge;
}
-/**
- * Implementation of iface_t.get_guest
- */
-static guest_t* get_guest(private_iface_t *this)
+METHOD(iface_t, get_guest, guest_t*,
+ private_iface_t *this)
{
return this->guest;
}
@@ -250,10 +234,8 @@ static char* create_tap(private_iface_t *this)
return strdup(ifr.ifr_name);
}
-/**
- * Implementation of iface_t.destroy.
- */
-static void destroy(private_iface_t *this)
+METHOD(iface_t, destroy, void,
+ private_iface_t *this)
{
if (this->bridge)
{
@@ -273,23 +255,25 @@ static void destroy(private_iface_t *this)
*/
iface_t *iface_create(char *name, guest_t *guest, mconsole_t *mconsole)
{
- private_iface_t *this = malloc_thing(private_iface_t);
-
- this->public.get_hostif = (char*(*)(iface_t*))get_hostif;
- this->public.get_guestif = (char*(*)(iface_t*))get_guestif;
- this->public.add_address = (bool(*)(iface_t*, host_t *addr))add_address;
- this->public.create_address_enumerator = (enumerator_t*(*)(iface_t*))create_address_enumerator;
- this->public.delete_address = (bool(*)(iface_t*, host_t *addr))delete_address;
- this->public.set_bridge = (void(*)(iface_t*, bridge_t*))set_bridge;
- this->public.get_bridge = (bridge_t*(*)(iface_t*))get_bridge;
- this->public.get_guest = (guest_t*(*)(iface_t*))get_guest;
- this->public.destroy = (void*)destroy;
+ private_iface_t *this;
- this->mconsole = mconsole;
- this->guestif = strdup(name);
- this->guest = guest;
+ INIT(this,
+ .public = {
+ .get_hostif = _get_hostif,
+ .get_guestif = _get_guestif,
+ .add_address = _add_address,
+ .create_address_enumerator = _create_address_enumerator,
+ .delete_address = _delete_address,
+ .set_bridge = _set_bridge,
+ .get_bridge = _get_bridge,
+ .get_guest = _get_guest,
+ .destroy = _destroy,
+ },
+ .mconsole = mconsole,
+ .guestif = strdup(name),
+ .guest = guest,
+ );
this->hostif = create_tap(this);
- this->bridge = NULL;
if (this->hostif == NULL)
{
destroy_tap(this);
diff --git a/src/dumm/iface.h b/src/dumm/iface.h
index dabefaa17..e96ee508c 100644
--- a/src/dumm/iface.h
+++ b/src/dumm/iface.h
@@ -50,10 +50,11 @@ struct iface_t {
/**
* Add an address to the interface.
*
- * @param addr address to add to interface
+ * @param addr address to add to the interface
+ * @param bits network prefix length in bits
* @return TRUE if address added
*/
- bool (*add_address)(iface_t *this, host_t *addr);
+ bool (*add_address)(iface_t *this, host_t *addr, int bits);
/**
* Create an enumerator over all installed addresses.
@@ -65,10 +66,13 @@ struct iface_t {
/**
* Remove an address from an interface.
*
+ * @note The network prefix length has to be the same as used in add_address
+ *
* @param addr address to remove
+ * @param bits network prefix length in bits
* @return TRUE if address removed
*/
- bool (*delete_address)(iface_t *this, host_t *addr);
+ bool (*delete_address)(iface_t *this, host_t *addr, int bits);
/**
* Set the bridge this interface is attached to.
diff --git a/src/dumm/mconsole.c b/src/dumm/mconsole.c
index 7d982a54c..de70b7e69 100644
--- a/src/dumm/mconsole.c
+++ b/src/dumm/mconsole.c
@@ -168,10 +168,8 @@ static void ignore(void *data, char *buf, size_t len)
{
}
-/**
- * Implementation of mconsole_t.add_iface.
- */
-static bool add_iface(private_mconsole_t *this, char *guest, char *host)
+METHOD(mconsole_t, add_iface, bool,
+ private_mconsole_t *this, char *guest, char *host)
{
int tries = 0;
@@ -186,10 +184,8 @@ static bool add_iface(private_mconsole_t *this, char *guest, char *host)
return FALSE;
}
-/**
- * Implementation of mconsole_t.del_iface.
- */
-static bool del_iface(private_mconsole_t *this, char *guest)
+METHOD(mconsole_t, del_iface, bool,
+ private_mconsole_t *this, char *guest)
{
if (request(this, NULL, NULL, "remove %s", guest) != 0)
{
@@ -198,11 +194,9 @@ static bool del_iface(private_mconsole_t *this, char *guest)
return TRUE;
}
-/**
- * Implementation of mconsole_t.exec
- */
-static int exec(private_mconsole_t *this, void(*cb)(void*,char*,size_t),
- void *data, char *cmd)
+METHOD(mconsole_t, exec, int,
+ private_mconsole_t *this, void(*cb)(void*,char*,size_t), void *data,
+ char *cmd)
{
return request(this, cb, data, "%s", cmd);
}
@@ -223,10 +217,8 @@ static void wait_bootup(private_mconsole_t *this)
}
}
-/**
- * Implementation of mconsole_t.destroy.
- */
-static void destroy(private_mconsole_t *this)
+METHOD(mconsole_t, destroy, void,
+ private_mconsole_t *this)
{
close(this->console);
close(this->notify);
@@ -327,14 +319,17 @@ static bool setup_console(private_mconsole_t *this)
*/
mconsole_t *mconsole_create(char *notify, void(*idle)(void))
{
- private_mconsole_t *this = malloc_thing(private_mconsole_t);
-
- this->public.add_iface = (bool(*)(mconsole_t*, char *guest, char *host))add_iface;
- this->public.del_iface = (bool(*)(mconsole_t*, char *guest))del_iface;
- this->public.exec = (int(*)(mconsole_t*, void(*cb)(void*,char*,size_t), void *data, char *cmd))exec;
- this->public.destroy = (void*)destroy;
-
- this->idle = idle;
+ private_mconsole_t *this;
+
+ INIT(this,
+ .public = {
+ .add_iface = _add_iface,
+ .del_iface = _del_iface,
+ .exec = _exec,
+ .destroy = _destroy,
+ },
+ .idle = idle,
+ );
if (!wait_for_notify(this, notify))
{
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index 609e7c5b2..5de713143 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -1,3 +1,3 @@
EXTRA_DIST = linux/if_alg.h linux/ipsec.h linux/netlink.h linux/rtnetlink.h \
linux/pfkeyv2.h linux/udp.h linux/xfrm.h linux/types.h \
- linux/jhash.h sys/queue.h
+ sys/queue.h
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index 59a325a14..8bc6befc7 100644
--- a/src/include/Makefile.in
+++ b/src/include/Makefile.in
@@ -144,6 +144,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -152,6 +155,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -168,11 +172,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -216,6 +222,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -228,7 +235,7 @@ xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
EXTRA_DIST = linux/if_alg.h linux/ipsec.h linux/netlink.h linux/rtnetlink.h \
linux/pfkeyv2.h linux/udp.h linux/xfrm.h linux/types.h \
- linux/jhash.h sys/queue.h
+ sys/queue.h
all: all-am
diff --git a/src/include/linux/jhash.h b/src/include/linux/jhash.h
deleted file mode 100644
index 2a2f99fbc..000000000
--- a/src/include/linux/jhash.h
+++ /dev/null
@@ -1,143 +0,0 @@
-#ifndef _LINUX_JHASH_H
-#define _LINUX_JHASH_H
-
-/* jhash.h: Jenkins hash support.
- *
- * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
- *
- * http://burtleburtle.net/bob/hash/
- *
- * These are the credits from Bob's sources:
- *
- * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
- * hash(), hash2(), hash3, and mix() are externally useful functions.
- * Routines to test the hash are included if SELF_TEST is defined.
- * You can use this free for any purpose. It has no warranty.
- *
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
- *
- * I've modified Bob's hash to be useful in the Linux kernel, and
- * any bugs present are surely my fault. -DaveM
- */
-
-/* NOTE: Arguments are modified. */
-#define __jhash_mix(a, b, c) \
-{ \
- a -= b; a -= c; a ^= (c>>13); \
- b -= c; b -= a; b ^= (a<<8); \
- c -= a; c -= b; c ^= (b>>13); \
- a -= b; a -= c; a ^= (c>>12); \
- b -= c; b -= a; b ^= (a<<16); \
- c -= a; c -= b; c ^= (b>>5); \
- a -= b; a -= c; a ^= (c>>3); \
- b -= c; b -= a; b ^= (a<<10); \
- c -= a; c -= b; c ^= (b>>15); \
-}
-
-/* The golden ration: an arbitrary value */
-#define JHASH_GOLDEN_RATIO 0x9e3779b9
-
-/* The most generic version, hashes an arbitrary sequence
- * of bytes. No alignment or length assumptions are made about
- * the input key.
- */
-static inline u32 jhash(const void *key, u32 length, u32 initval)
-{
- u32 a, b, c, len;
- const u8 *k = key;
-
- len = length;
- a = b = JHASH_GOLDEN_RATIO;
- c = initval;
-
- while (len >= 12) {
- a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24));
- b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24));
- c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24));
-
- __jhash_mix(a,b,c);
-
- k += 12;
- len -= 12;
- }
-
- c += length;
- switch (len) {
- case 11: c += ((u32)k[10]<<24);
- case 10: c += ((u32)k[9]<<16);
- case 9 : c += ((u32)k[8]<<8);
- case 8 : b += ((u32)k[7]<<24);
- case 7 : b += ((u32)k[6]<<16);
- case 6 : b += ((u32)k[5]<<8);
- case 5 : b += k[4];
- case 4 : a += ((u32)k[3]<<24);
- case 3 : a += ((u32)k[2]<<16);
- case 2 : a += ((u32)k[1]<<8);
- case 1 : a += k[0];
- };
-
- __jhash_mix(a,b,c);
-
- return c;
-}
-
-/* A special optimized version that handles 1 or more of u32s.
- * The length parameter here is the number of u32s in the key.
- */
-static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
-{
- u32 a, b, c, len;
-
- a = b = JHASH_GOLDEN_RATIO;
- c = initval;
- len = length;
-
- while (len >= 3) {
- a += k[0];
- b += k[1];
- c += k[2];
- __jhash_mix(a, b, c);
- k += 3; len -= 3;
- }
-
- c += length * 4;
-
- switch (len) {
- case 2 : b += k[1];
- case 1 : a += k[0];
- };
-
- __jhash_mix(a,b,c);
-
- return c;
-}
-
-
-/* A special ultra-optimized versions that knows they are hashing exactly
- * 3, 2 or 1 word(s).
- *
- * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
- * done at the end is not done here.
- */
-static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
-{
- a += JHASH_GOLDEN_RATIO;
- b += JHASH_GOLDEN_RATIO;
- c += initval;
-
- __jhash_mix(a, b, c);
-
- return c;
-}
-
-static inline u32 jhash_2words(u32 a, u32 b, u32 initval)
-{
- return jhash_3words(a, b, 0, initval);
-}
-
-static inline u32 jhash_1word(u32 a, u32 initval)
-{
- return jhash_3words(a, 0, 0, initval);
-}
-
-#endif /* _LINUX_JHASH_H */
diff --git a/src/include/linux/rtnetlink.h b/src/include/linux/rtnetlink.h
index 131822c0f..56835d8bd 100644
--- a/src/include/linux/rtnetlink.h
+++ b/src/include/linux/rtnetlink.h
@@ -263,6 +263,7 @@ enum rtattr_type_t
RTA_CACHEINFO,
RTA_SESSION,
RTA_MP_ALGO,
+ RTA_TABLE,
__RTA_MAX
};
diff --git a/src/include/linux/udp.h b/src/include/linux/udp.h
index c213d2a51..b68a166f2 100644
--- a/src/include/linux/udp.h
+++ b/src/include/linux/udp.h
@@ -47,7 +47,7 @@ struct udp_sock {
unsigned int corkflag; /* Cork is required */
__u16 encap_type; /* Is this an Encapsulation socket? */
/*
- * Following member retains the infomation to create a UDP header
+ * Following member retains the information to create a UDP header
* when the socket is uncorked.
*/
__u16 len; /* total length of pending frames */
diff --git a/src/ipsec/Android.mk b/src/ipsec/Android.mk
new file mode 100644
index 000000000..d134f7fd2
--- /dev/null
+++ b/src/ipsec/Android.mk
@@ -0,0 +1,33 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# build ipsec ------------------------------------------------------------------
+
+LOCAL_MODULE := ipsec
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_CLASS := EXECUTABLES
+
+GEN := $(local-intermediates-dir)/ipsec
+
+$(GEN) : PRIVATE_PATH := $(LOCAL_PATH)
+$(GEN) : PRIVATE_CUSTOM_TOOL = sed \
+ -e "s:@IPSEC_SHELL@:/system/bin/sh:" \
+ -e "s:@IPSEC_VERSION@:$(strongswan_VERSION):" \
+ -e "s:@IPSEC_NAME@:strongSwan:" \
+ -e "s:@IPSEC_DISTRO@::" \
+ -e "s:@IPSEC_DIR@:$(strongswan_DIR):" \
+ -e "s:@IPSEC_SBINDIR@:$(strongswan_SBINDIR):" \
+ -e "s:@IPSEC_CONFDIR@:$(strongswan_CONFDIR):" \
+ -e "s:@IPSEC_PIDDIR@:$(strongswan_PIDDIR):" \
+ $< > $@ && chmod +x $@
+
+$(GEN) : $(strongswan_PATH)/Android.mk
+$(GEN) : $(LOCAL_PATH)/ipsec.in
+ $(transform-generated-source)
+
+LOCAL_GENERATED_SOURCES := $(GEN)
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
diff --git a/src/ipsec/Makefile.am b/src/ipsec/Makefile.am
index 510f1021a..bbf009721 100644
--- a/src/ipsec/Makefile.am
+++ b/src/ipsec/Makefile.am
@@ -1,7 +1,7 @@
sbin_SCRIPTS = ipsec
CLEANFILES = ipsec ipsec.8
dist_man8_MANS = ipsec.8
-EXTRA_DIST = ipsec.in ipsec.8.in
+EXTRA_DIST = ipsec.in ipsec.8.in Android.mk
ipsec.8 : ipsec.8.in
sed \
@@ -10,6 +10,7 @@ ipsec.8 : ipsec.8.in
ipsec : ipsec.in
sed \
+ -e "s:@IPSEC_SHELL@:/bin/sh:" \
-e "s:@IPSEC_VERSION@:$(PACKAGE_VERSION):" \
-e "s:@IPSEC_NAME@:$(PACKAGE_NAME):" \
-e "s:@IPSEC_DISTRO@::" \
diff --git a/src/ipsec/Makefile.in b/src/ipsec/Makefile.in
index 04ca97781..b0474159d 100644
--- a/src/ipsec/Makefile.in
+++ b/src/ipsec/Makefile.in
@@ -172,6 +172,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -180,6 +183,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -196,11 +200,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -244,6 +250,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -257,7 +264,7 @@ xml_LIBS = @xml_LIBS@
sbin_SCRIPTS = ipsec
CLEANFILES = ipsec ipsec.8
dist_man8_MANS = ipsec.8
-EXTRA_DIST = ipsec.in ipsec.8.in
+EXTRA_DIST = ipsec.in ipsec.8.in Android.mk
all: all-am
.SUFFIXES:
@@ -539,6 +546,7 @@ ipsec.8 : ipsec.8.in
ipsec : ipsec.in
sed \
+ -e "s:@IPSEC_SHELL@:/bin/sh:" \
-e "s:@IPSEC_VERSION@:$(PACKAGE_VERSION):" \
-e "s:@IPSEC_NAME@:$(PACKAGE_NAME):" \
-e "s:@IPSEC_DISTRO@::" \
diff --git a/src/ipsec/ipsec.8 b/src/ipsec/ipsec.8
index 6f4117be7..66e43b481 100644
--- a/src/ipsec/ipsec.8
+++ b/src/ipsec/ipsec.8
@@ -1,4 +1,4 @@
-.TH IPSEC 8 "2010-05-30" "4.5.1" "strongSwan"
+.TH IPSEC 8 "2010-05-30" "4.5.3dr3" "strongSwan"
.SH NAME
ipsec \- invoke IPsec utilities
.SH SYNOPSIS
diff --git a/src/ipsec/ipsec.in b/src/ipsec/ipsec.in
index 2ea0ef798..479974a0e 100755
--- a/src/ipsec/ipsec.in
+++ b/src/ipsec/ipsec.in
@@ -1,4 +1,4 @@
-#! /bin/sh
+#! @IPSEC_SHELL@
# prefix command to run stuff from our programs directory
# Copyright (C) 1998-2002 Henry Spencer.
# Copyright (C) 2006 Andreas Steffen
@@ -19,6 +19,7 @@ PATH="/sbin:/bin:/usr/sbin:/usr/bin:@IPSEC_SBINDIR@"
export PATH
# name and version of the ipsec implementation
+OS_NAME=`uname -s`
IPSEC_NAME="@IPSEC_NAME@"
IPSEC_VERSION="U@IPSEC_VERSION@/K`uname -r`"
@@ -60,7 +61,7 @@ case "$1" in
echo " listalgs|listpubkeys|listcerts [--utc]"
echo " listcacerts|listaacerts|listocspcerts [--utc]"
echo " listacerts|listgroups|listcainfos [--utc]"
- echo " listcrls|listocsp|listcards|listall [--utc]"
+ echo " listcrls|listocsp|listcards|listplugins|listall [--utc]"
echo " leases [<poolname> [<address>]]"
echo " rereadsecrets|rereadgroups"
echo " rereadcacerts|rereadaacerts|rereadocspcerts"
@@ -169,7 +170,7 @@ leases)
fi
exit "$rc"
;;
-listalgs|\listpubkeys|\
+listalgs|listpubkeys|listplugins|\
listcerts|listcacerts|listaacerts|\
listacerts|listgroups|listocspcerts|\
listcainfos|listcrls|listocsp|listall|\
@@ -326,7 +327,7 @@ stop)
if [ -n "$spid" ]
then
kill $spid 2>/dev/null
- loop=5
+ loop=11
while [ $loop -gt 0 ] ; do
kill -0 $spid 2>/dev/null || break
sleep 1
@@ -378,7 +379,7 @@ update)
fi
;;
version|--version)
- printf "Linux $IPSEC_NAME $IPSEC_VERSION\n"
+ printf "$OS_NAME $IPSEC_NAME $IPSEC_VERSION\n"
printf "$IPSEC_DISTRO\n"
printf "See 'ipsec --copyright' for copyright information.\n"
exit 0
diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk
index 90e2bdc6a..f98d36a61 100644
--- a/src/libcharon/Android.mk
+++ b/src/libcharon/Android.mk
@@ -41,10 +41,9 @@ 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_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 \
+network/receiver.c network/receiver.h network/sender.c network/sender.h \
+network/packet.c network/packet.h network/socket.c network/socket.h \
+network/socket_manager.c network/socket_manager.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 processing/jobs/delete_ike_sa_job.h \
@@ -63,9 +62,6 @@ 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 \
sa/authenticators/eap/eap_manager.c sa/authenticators/eap/eap_manager.h \
-sa/authenticators/eap/sim_manager.c sa/authenticators/eap/sim_manager.h \
-sa/authenticators/eap/sim_card.h sa/authenticators/eap/sim_provider.h \
-sa/authenticators/eap/sim_hooks.h \
sa/authenticators/psk_authenticator.c sa/authenticators/psk_authenticator.h \
sa/authenticators/pubkey_authenticator.c sa/authenticators/pubkey_authenticator.h \
sa/child_sa.c sa/child_sa.h \
@@ -74,6 +70,7 @@ sa/ike_sa_id.c sa/ike_sa_id.h \
sa/ike_sa_manager.c sa/ike_sa_manager.h \
sa/task_manager.c sa/task_manager.h \
sa/keymat.c sa/keymat.h \
+sa/shunt_manager.c sa/shunt_manager.h \
sa/trap_manager.c sa/trap_manager.h \
sa/tasks/child_create.c sa/tasks/child_create.h \
sa/tasks/child_delete.c sa/tasks/child_delete.h \
@@ -91,13 +88,7 @@ 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 \
-tnc/tncif.h tnc/tncifimc.h tnc/tncifimv.h tnc/tncifimv.c \
-tnc/imc/imc.h tnc/imc/imc_manager.h \
-tnc/imv/imv.h tnc/imv/imv_manager.h \
-tnc/imv/imv_recommendations.c tnc/imv/imv_recommendations.h \
-tnc/tnccs/tnccs.c tnc/tnccs/tnccs.h \
-tnc/tnccs/tnccs_manager.c tnc/tnccs/tnccs_manager.h
+sa/tasks/task.c sa/tasks/task.h
# adding the plugin source files
@@ -141,6 +132,8 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/../libsimaka/
LOCAL_SRC_FILES += $(addprefix ../libsimaka/, \
simaka_message.h simaka_message.c \
simaka_crypto.h simaka_crypto.c \
+ simaka_manager.h simaka_manager.c \
+ simaka_card.h simaka_provider.h simaka_hooks.h \
)
endif
@@ -150,18 +143,30 @@ LOCAL_SRC_FILES += $(call add_plugin, socket-default)
LOCAL_SRC_FILES += $(call add_plugin, socket-dynamic)
+LOCAL_SRC_FILES += $(call add_plugin, socket-raw)
+
+LOCAL_SRC_FILES += $(call add_plugin, stroke)
+ifneq ($(call plugin_enabled, stroke),)
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/../stroke/
+endif
+
+
# build libcharon --------------------------------------------------------------
LOCAL_C_INCLUDES += \
$(libvstr_PATH) \
$(strongswan_PATH)/src/include \
$(strongswan_PATH)/src/libhydra \
- $(strongswan_PATH)/src/libstrongswan
+ $(strongswan_PATH)/src/libstrongswan \
+ $(strongswan_PATH)/src/libtncif
-LOCAL_CFLAGS := $(strongswan_CFLAGS)
+LOCAL_CFLAGS := $(strongswan_CFLAGS) \
+ -DPLUGINS='"$(strongswan_CHARON_PLUGINS)"'
LOCAL_MODULE := libcharon
+LOCAL_MODULE_TAGS := optional
+
LOCAL_ARM_MODE := arm
LOCAL_PRELINK_MODULE := false
diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am
index 9a4b28c3a..b86bd428c 100644
--- a/src/libcharon/Makefile.am
+++ b/src/libcharon/Makefile.am
@@ -1,4 +1,4 @@
-lib_LTLIBRARIES = libcharon.la
+ipseclib_LTLIBRARIES = libcharon.la
libcharon_la_SOURCES = \
bus/bus.c bus/bus.h \
@@ -39,10 +39,9 @@ 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_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 \
+network/receiver.c network/receiver.h network/sender.c network/sender.h \
+network/packet.c network/packet.h network/socket.c network/socket.h \
+network/socket_manager.c network/socket_manager.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 processing/jobs/delete_ike_sa_job.h \
@@ -61,9 +60,6 @@ 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 \
sa/authenticators/eap/eap_manager.c sa/authenticators/eap/eap_manager.h \
-sa/authenticators/eap/sim_manager.c sa/authenticators/eap/sim_manager.h \
-sa/authenticators/eap/sim_card.h sa/authenticators/eap/sim_provider.h \
-sa/authenticators/eap/sim_hooks.h \
sa/authenticators/psk_authenticator.c sa/authenticators/psk_authenticator.h \
sa/authenticators/pubkey_authenticator.c sa/authenticators/pubkey_authenticator.h \
sa/child_sa.c sa/child_sa.h \
@@ -72,6 +68,7 @@ sa/ike_sa_id.c sa/ike_sa_id.h \
sa/ike_sa_manager.c sa/ike_sa_manager.h \
sa/task_manager.c sa/task_manager.h \
sa/keymat.c sa/keymat.h \
+sa/shunt_manager.c sa/shunt_manager.h \
sa/trap_manager.c sa/trap_manager.h \
sa/tasks/child_create.c sa/tasks/child_create.h \
sa/tasks/child_delete.c sa/tasks/child_delete.h \
@@ -89,13 +86,7 @@ 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 \
-tnc/tncif.h tnc/tncifimc.h tnc/tncifimv.h tnc/tncifimv.c \
-tnc/imc/imc.h tnc/imc/imc_manager.h \
-tnc/imv/imv.h tnc/imv/imv_manager.h \
-tnc/imv/imv_recommendations.c tnc/imv/imv_recommendations.h \
-tnc/tnccs/tnccs.c tnc/tnccs/tnccs.h \
-tnc/tnccs/tnccs_manager.c tnc/tnccs/tnccs_manager.h
+sa/tasks/task.c sa/tasks/task.h
daemon.lo : $(top_builddir)/config.status
@@ -335,6 +326,27 @@ if MONOLITHIC
endif
endif
+if USE_RADIUS
+if MONOLITHIC
+ # otherwise this library is linked to eap_radius
+ libcharon_la_LIBADD += $(top_builddir)/src/libradius/libradius.la
+endif
+endif
+
+if USE_TNC_IFMAP
+ SUBDIRS += plugins/tnc_ifmap
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la
+endif
+endif
+
+if USE_TNC_PDP
+ SUBDIRS += plugins/tnc_pdp
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/tnc_pdp/libstrongswan-tnc-pdp.la
+endif
+endif
+
if USE_TNC_IMC
SUBDIRS += plugins/tnc_imc
if MONOLITHIC
@@ -349,6 +361,13 @@ if MONOLITHIC
endif
endif
+if USE_TNC_TNCCS
+ SUBDIRS += plugins/tnc_tnccs
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/tnc_tnccs/libstrongswan-tnc-tnccs.la
+endif
+endif
+
if USE_TNCCS_11
SUBDIRS += plugins/tnccs_11
if MONOLITHIC
@@ -370,6 +389,13 @@ if MONOLITHIC
endif
endif
+if USE_LIBTNCCS
+if MONOLITHIC
+ # otherwise this library is linked to the respective plugins
+ libcharon_la_LIBADD += $(top_builddir)/src/libtnccs/libtnccs.la
+endif
+endif
+
if USE_MEDSRV
SUBDIRS += plugins/medsrv
if MONOLITHIC
@@ -426,6 +452,13 @@ if MONOLITHIC
endif
endif
+if USE_CERTEXPIRE
+ SUBDIRS += plugins/certexpire
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/certexpire/libstrongswan-certexpire.la
+endif
+endif
+
if USE_LED
SUBDIRS += plugins/led
if MONOLITHIC
@@ -447,6 +480,13 @@ if MONOLITHIC
endif
endif
+if USE_RADATTR
+ SUBDIRS += plugins/radattr
+if MONOLITHIC
+ libcharon_la_LIBADD += plugins/radattr/libstrongswan-radattr.la
+endif
+endif
+
if USE_UCI
SUBDIRS += plugins/uci
if MONOLITHIC
diff --git a/src/libcharon/Makefile.in b/src/libcharon/Makefile.in
index 70385f306..ccbd4add2 100644
--- a/src/libcharon/Makefile.in
+++ b/src/libcharon/Makefile.in
@@ -99,44 +99,56 @@ host_triplet = @host@
@USE_EAP_TNC_TRUE@am__append_54 = plugins/eap_tnc
@MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE@am__append_55 = plugins/eap_tnc/libstrongswan-eap-tnc.la
@MONOLITHIC_TRUE@@USE_TLS_TRUE@am__append_56 = $(top_builddir)/src/libtls/libtls.la
-@USE_TNC_IMC_TRUE@am__append_57 = plugins/tnc_imc
-@MONOLITHIC_TRUE@@USE_TNC_IMC_TRUE@am__append_58 = plugins/tnc_imc/libstrongswan-tnc-imc.la
-@USE_TNC_IMV_TRUE@am__append_59 = plugins/tnc_imv
-@MONOLITHIC_TRUE@@USE_TNC_IMV_TRUE@am__append_60 = plugins/tnc_imv/libstrongswan-tnc-imv.la
-@USE_TNCCS_11_TRUE@am__append_61 = plugins/tnccs_11
-@MONOLITHIC_TRUE@@USE_TNCCS_11_TRUE@am__append_62 = plugins/tnccs_11/libstrongswan-tnccs-11.la
-@USE_TNCCS_20_TRUE@am__append_63 = plugins/tnccs_20
-@MONOLITHIC_TRUE@@USE_TNCCS_20_TRUE@am__append_64 = plugins/tnccs_20/libstrongswan-tnccs-20.la
-@USE_TNCCS_DYNAMIC_TRUE@am__append_65 = plugins/tnccs_dynamic
-@MONOLITHIC_TRUE@@USE_TNCCS_DYNAMIC_TRUE@am__append_66 = plugins/tnccs_dynamic/libstrongswan-tnccs-dynamic.la
-@USE_MEDSRV_TRUE@am__append_67 = plugins/medsrv
-@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_68 = plugins/medsrv/libstrongswan-medsrv.la
-@USE_MEDCLI_TRUE@am__append_69 = plugins/medcli
-@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_70 = plugins/medcli/libstrongswan-medcli.la
-@USE_NM_TRUE@am__append_71 = plugins/nm
-@MONOLITHIC_TRUE@@USE_NM_TRUE@am__append_72 = plugins/nm/libstrongswan-nm.la
-@USE_DHCP_TRUE@am__append_73 = plugins/dhcp
-@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_74 = plugins/dhcp/libstrongswan-dhcp.la
-@USE_ANDROID_TRUE@am__append_75 = plugins/android
-@MONOLITHIC_TRUE@@USE_ANDROID_TRUE@am__append_76 = plugins/android/libstrongswan-android.la
-@USE_MAEMO_TRUE@am__append_77 = plugins/maemo
-@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_78 = plugins/maemo/libstrongswan-maemo.la
-@USE_HA_TRUE@am__append_79 = plugins/ha
-@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_80 = plugins/ha/libstrongswan-ha.la
-@USE_WHITELIST_TRUE@am__append_81 = plugins/whitelist
-@MONOLITHIC_TRUE@@USE_WHITELIST_TRUE@am__append_82 = plugins/whitelist/libstrongswan-whitelist.la
-@USE_LED_TRUE@am__append_83 = plugins/led
-@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_84 = plugins/led/libstrongswan-led.la
-@USE_DUPLICHECK_TRUE@am__append_85 = plugins/duplicheck
-@MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE@am__append_86 = plugins/duplicheck/libstrongswan-duplicheck.la
-@USE_COUPLING_TRUE@am__append_87 = plugins/coupling
-@MONOLITHIC_TRUE@@USE_COUPLING_TRUE@am__append_88 = plugins/coupling/libstrongswan-coupling.la
-@USE_UCI_TRUE@am__append_89 = plugins/uci
-@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_90 = plugins/uci/libstrongswan-uci.la
-@USE_ADDRBLOCK_TRUE@am__append_91 = plugins/addrblock
-@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_92 = plugins/uci/libstrongswan-addrblock.la
-@USE_UNIT_TESTS_TRUE@am__append_93 = plugins/unit_tester
-@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_94 = plugins/unit_tester/libstrongswan-unit-tester.la
+@MONOLITHIC_TRUE@@USE_RADIUS_TRUE@am__append_57 = $(top_builddir)/src/libradius/libradius.la
+@USE_TNC_IFMAP_TRUE@am__append_58 = plugins/tnc_ifmap
+@MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE@am__append_59 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la
+@USE_TNC_PDP_TRUE@am__append_60 = plugins/tnc_pdp
+@MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE@am__append_61 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la
+@USE_TNC_IMC_TRUE@am__append_62 = plugins/tnc_imc
+@MONOLITHIC_TRUE@@USE_TNC_IMC_TRUE@am__append_63 = plugins/tnc_imc/libstrongswan-tnc-imc.la
+@USE_TNC_IMV_TRUE@am__append_64 = plugins/tnc_imv
+@MONOLITHIC_TRUE@@USE_TNC_IMV_TRUE@am__append_65 = plugins/tnc_imv/libstrongswan-tnc-imv.la
+@USE_TNC_TNCCS_TRUE@am__append_66 = plugins/tnc_tnccs
+@MONOLITHIC_TRUE@@USE_TNC_TNCCS_TRUE@am__append_67 = plugins/tnc_tnccs/libstrongswan-tnc-tnccs.la
+@USE_TNCCS_11_TRUE@am__append_68 = plugins/tnccs_11
+@MONOLITHIC_TRUE@@USE_TNCCS_11_TRUE@am__append_69 = plugins/tnccs_11/libstrongswan-tnccs-11.la
+@USE_TNCCS_20_TRUE@am__append_70 = plugins/tnccs_20
+@MONOLITHIC_TRUE@@USE_TNCCS_20_TRUE@am__append_71 = plugins/tnccs_20/libstrongswan-tnccs-20.la
+@USE_TNCCS_DYNAMIC_TRUE@am__append_72 = plugins/tnccs_dynamic
+@MONOLITHIC_TRUE@@USE_TNCCS_DYNAMIC_TRUE@am__append_73 = plugins/tnccs_dynamic/libstrongswan-tnccs-dynamic.la
+@MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE@am__append_74 = $(top_builddir)/src/libtnccs/libtnccs.la
+@USE_MEDSRV_TRUE@am__append_75 = plugins/medsrv
+@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_76 = plugins/medsrv/libstrongswan-medsrv.la
+@USE_MEDCLI_TRUE@am__append_77 = plugins/medcli
+@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_78 = plugins/medcli/libstrongswan-medcli.la
+@USE_NM_TRUE@am__append_79 = plugins/nm
+@MONOLITHIC_TRUE@@USE_NM_TRUE@am__append_80 = plugins/nm/libstrongswan-nm.la
+@USE_DHCP_TRUE@am__append_81 = plugins/dhcp
+@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_82 = plugins/dhcp/libstrongswan-dhcp.la
+@USE_ANDROID_TRUE@am__append_83 = plugins/android
+@MONOLITHIC_TRUE@@USE_ANDROID_TRUE@am__append_84 = plugins/android/libstrongswan-android.la
+@USE_MAEMO_TRUE@am__append_85 = plugins/maemo
+@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_86 = plugins/maemo/libstrongswan-maemo.la
+@USE_HA_TRUE@am__append_87 = plugins/ha
+@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_88 = plugins/ha/libstrongswan-ha.la
+@USE_WHITELIST_TRUE@am__append_89 = plugins/whitelist
+@MONOLITHIC_TRUE@@USE_WHITELIST_TRUE@am__append_90 = plugins/whitelist/libstrongswan-whitelist.la
+@USE_CERTEXPIRE_TRUE@am__append_91 = plugins/certexpire
+@MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE@am__append_92 = plugins/certexpire/libstrongswan-certexpire.la
+@USE_LED_TRUE@am__append_93 = plugins/led
+@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_94 = plugins/led/libstrongswan-led.la
+@USE_DUPLICHECK_TRUE@am__append_95 = plugins/duplicheck
+@MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE@am__append_96 = plugins/duplicheck/libstrongswan-duplicheck.la
+@USE_COUPLING_TRUE@am__append_97 = plugins/coupling
+@MONOLITHIC_TRUE@@USE_COUPLING_TRUE@am__append_98 = plugins/coupling/libstrongswan-coupling.la
+@USE_RADATTR_TRUE@am__append_99 = plugins/radattr
+@MONOLITHIC_TRUE@@USE_RADATTR_TRUE@am__append_100 = plugins/radattr/libstrongswan-radattr.la
+@USE_UCI_TRUE@am__append_101 = plugins/uci
+@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_102 = plugins/uci/libstrongswan-uci.la
+@USE_ADDRBLOCK_TRUE@am__append_103 = plugins/addrblock
+@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_104 = plugins/uci/libstrongswan-addrblock.la
+@USE_UNIT_TESTS_TRUE@am__append_105 = plugins/unit_tester
+@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_106 = plugins/unit_tester/libstrongswan-unit-tester.la
subdir = src/libcharon
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -175,8 +187,8 @@ am__nobase_list = $(am__nobase_strip_setup); \
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)$(libdir)"
-LTLIBRARIES = $(lib_LTLIBRARIES)
+am__installdirs = "$(DESTDIR)$(ipseclibdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libcharon_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
@@ -189,13 +201,16 @@ libcharon_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__append_38) $(am__append_39) $(am__append_41) \
$(am__append_43) $(am__append_45) $(am__append_47) \
$(am__append_49) $(am__append_51) $(am__append_53) \
- $(am__append_55) $(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__append_84) $(am__append_86) $(am__append_88) \
- $(am__append_90) $(am__append_92) $(am__append_94)
+ $(am__append_55) $(am__append_56) $(am__append_57) \
+ $(am__append_59) $(am__append_61) $(am__append_63) \
+ $(am__append_65) $(am__append_67) $(am__append_69) \
+ $(am__append_71) $(am__append_73) $(am__append_74) \
+ $(am__append_76) $(am__append_78) $(am__append_80) \
+ $(am__append_82) $(am__append_84) $(am__append_86) \
+ $(am__append_88) $(am__append_90) $(am__append_92) \
+ $(am__append_94) $(am__append_96) $(am__append_98) \
+ $(am__append_100) $(am__append_102) $(am__append_104) \
+ $(am__append_106)
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 \
@@ -244,10 +259,10 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
encoding/payloads/unknown_payload.h \
encoding/payloads/vendor_id_payload.c \
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 \
+ kernel/kernel_handler.h network/receiver.c network/receiver.h \
+ network/sender.c network/sender.h network/packet.c \
+ network/packet.h network/socket.c network/socket.h \
+ network/socket_manager.c network/socket_manager.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 \
@@ -279,11 +294,6 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
sa/authenticators/eap/eap_method.h \
sa/authenticators/eap/eap_manager.c \
sa/authenticators/eap/eap_manager.h \
- sa/authenticators/eap/sim_manager.c \
- sa/authenticators/eap/sim_manager.h \
- sa/authenticators/eap/sim_card.h \
- sa/authenticators/eap/sim_provider.h \
- sa/authenticators/eap/sim_hooks.h \
sa/authenticators/psk_authenticator.c \
sa/authenticators/psk_authenticator.h \
sa/authenticators/pubkey_authenticator.c \
@@ -291,7 +301,8 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \
sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \
sa/ike_sa_id.h sa/ike_sa_manager.c sa/ike_sa_manager.h \
sa/task_manager.c sa/task_manager.h sa/keymat.c sa/keymat.h \
- sa/trap_manager.c sa/trap_manager.h sa/tasks/child_create.c \
+ sa/shunt_manager.c sa/shunt_manager.h sa/trap_manager.c \
+ sa/trap_manager.h sa/tasks/child_create.c \
sa/tasks/child_create.h sa/tasks/child_delete.c \
sa/tasks/child_delete.h sa/tasks/child_rekey.c \
sa/tasks/child_rekey.h sa/tasks/ike_auth.c sa/tasks/ike_auth.h \
@@ -306,12 +317,7 @@ 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 \
- tnc/tncif.h tnc/tncifimc.h tnc/tncifimv.h tnc/tncifimv.c \
- tnc/imc/imc.h tnc/imc/imc_manager.h tnc/imv/imv.h \
- tnc/imv/imv_manager.h tnc/imv/imv_recommendations.c \
- tnc/imv/imv_recommendations.h tnc/tnccs/tnccs.c \
- tnc/tnccs/tnccs.h tnc/tnccs/tnccs_manager.c \
- tnc/tnccs/tnccs_manager.h encoding/payloads/endpoint_notify.c \
+ encoding/payloads/endpoint_notify.c \
encoding/payloads/endpoint_notify.h \
processing/jobs/initiate_mediation_job.c \
processing/jobs/initiate_mediation_job.h \
@@ -333,21 +339,20 @@ am_libcharon_la_OBJECTS = bus.lo file_logger.lo sys_logger.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_handler.lo \
- packet.lo receiver.lo sender.lo socket_manager.lo \
+ receiver.lo sender.lo packet.lo socket.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 start_action_job.lo roam_job.lo \
update_sa_job.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 \
+ 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 shunt_manager.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 \
- tncifimv.lo imv_recommendations.lo tnccs.lo tnccs_manager.lo \
$(am__objects_1)
libcharon_la_OBJECTS = $(am_libcharon_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
@@ -388,12 +393,14 @@ DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \
plugins/eap_aka plugins/eap_aka_3gpp2 plugins/eap_md5 \
plugins/eap_gtc plugins/eap_mschapv2 plugins/eap_radius \
plugins/eap_tls plugins/eap_ttls plugins/eap_peap \
- plugins/eap_tnc plugins/tnc_imc plugins/tnc_imv \
+ plugins/eap_tnc plugins/tnc_ifmap plugins/tnc_pdp \
+ plugins/tnc_imc plugins/tnc_imv plugins/tnc_tnccs \
plugins/tnccs_11 plugins/tnccs_20 plugins/tnccs_dynamic \
plugins/medsrv plugins/medcli plugins/nm plugins/dhcp \
plugins/android plugins/maemo plugins/ha plugins/whitelist \
- plugins/led plugins/duplicheck plugins/coupling plugins/uci \
- plugins/addrblock plugins/unit_tester
+ plugins/certexpire plugins/led plugins/duplicheck \
+ plugins/coupling plugins/radattr plugins/uci plugins/addrblock \
+ plugins/unit_tester
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -511,6 +518,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -519,6 +529,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -535,11 +546,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -583,6 +596,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -593,7 +607,7 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-lib_LTLIBRARIES = libcharon.la
+ipseclib_LTLIBRARIES = libcharon.la
libcharon_la_SOURCES = 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 bus/listeners/sys_logger.h \
@@ -642,10 +656,10 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \
encoding/payloads/unknown_payload.h \
encoding/payloads/vendor_id_payload.c \
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 \
+ kernel/kernel_handler.h network/receiver.c network/receiver.h \
+ network/sender.c network/sender.h network/packet.c \
+ network/packet.h network/socket.c network/socket.h \
+ network/socket_manager.c network/socket_manager.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 \
@@ -677,11 +691,6 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \
sa/authenticators/eap/eap_method.h \
sa/authenticators/eap/eap_manager.c \
sa/authenticators/eap/eap_manager.h \
- sa/authenticators/eap/sim_manager.c \
- sa/authenticators/eap/sim_manager.h \
- sa/authenticators/eap/sim_card.h \
- sa/authenticators/eap/sim_provider.h \
- sa/authenticators/eap/sim_hooks.h \
sa/authenticators/psk_authenticator.c \
sa/authenticators/psk_authenticator.h \
sa/authenticators/pubkey_authenticator.c \
@@ -689,7 +698,8 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \
sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \
sa/ike_sa_id.h sa/ike_sa_manager.c sa/ike_sa_manager.h \
sa/task_manager.c sa/task_manager.h sa/keymat.c sa/keymat.h \
- sa/trap_manager.c sa/trap_manager.h sa/tasks/child_create.c \
+ sa/shunt_manager.c sa/shunt_manager.h sa/trap_manager.c \
+ sa/trap_manager.h sa/tasks/child_create.c \
sa/tasks/child_create.h sa/tasks/child_delete.c \
sa/tasks/child_delete.h sa/tasks/child_rekey.c \
sa/tasks/child_rekey.h sa/tasks/ike_auth.c sa/tasks/ike_auth.h \
@@ -704,12 +714,7 @@ 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 \
- tnc/tncif.h tnc/tncifimc.h tnc/tncifimv.h tnc/tncifimv.c \
- tnc/imc/imc.h tnc/imc/imc_manager.h tnc/imv/imv.h \
- tnc/imv/imv_manager.h tnc/imv/imv_recommendations.c \
- tnc/imv/imv_recommendations.h tnc/tnccs/tnccs.c \
- tnc/tnccs/tnccs.h tnc/tnccs/tnccs_manager.c \
- tnc/tnccs/tnccs_manager.h $(am__append_1)
+ $(am__append_1)
INCLUDES = \
-I${linux_headers} \
-I$(top_srcdir)/src/libstrongswan \
@@ -731,13 +736,16 @@ libcharon_la_LIBADD = -lm $(PTHREADLIB) $(DLLIB) $(SOCKLIB) \
$(am__append_38) $(am__append_39) $(am__append_41) \
$(am__append_43) $(am__append_45) $(am__append_47) \
$(am__append_49) $(am__append_51) $(am__append_53) \
- $(am__append_55) $(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__append_84) $(am__append_86) $(am__append_88) \
- $(am__append_90) $(am__append_92) $(am__append_94)
+ $(am__append_55) $(am__append_56) $(am__append_57) \
+ $(am__append_59) $(am__append_61) $(am__append_63) \
+ $(am__append_65) $(am__append_67) $(am__append_69) \
+ $(am__append_71) $(am__append_73) $(am__append_74) \
+ $(am__append_76) $(am__append_78) $(am__append_80) \
+ $(am__append_82) $(am__append_84) $(am__append_86) \
+ $(am__append_88) $(am__append_90) $(am__append_92) \
+ $(am__append_94) $(am__append_96) $(am__append_98) \
+ $(am__append_100) $(am__append_102) $(am__append_104) \
+ $(am__append_106)
EXTRA_DIST = Android.mk
@MONOLITHIC_FALSE@SUBDIRS = . $(am__append_3) $(am__append_5) \
@MONOLITHIC_FALSE@ $(am__append_7) $(am__append_9) \
@@ -752,16 +760,18 @@ EXTRA_DIST = Android.mk
@MONOLITHIC_FALSE@ $(am__append_44) $(am__append_46) \
@MONOLITHIC_FALSE@ $(am__append_48) $(am__append_50) \
@MONOLITHIC_FALSE@ $(am__append_52) $(am__append_54) \
-@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) $(am__append_83) \
-@MONOLITHIC_FALSE@ $(am__append_85) $(am__append_87) \
-@MONOLITHIC_FALSE@ $(am__append_89) $(am__append_91) \
-@MONOLITHIC_FALSE@ $(am__append_93)
+@MONOLITHIC_FALSE@ $(am__append_58) $(am__append_60) \
+@MONOLITHIC_FALSE@ $(am__append_62) $(am__append_64) \
+@MONOLITHIC_FALSE@ $(am__append_66) $(am__append_68) \
+@MONOLITHIC_FALSE@ $(am__append_70) $(am__append_72) \
+@MONOLITHIC_FALSE@ $(am__append_75) $(am__append_77) \
+@MONOLITHIC_FALSE@ $(am__append_79) $(am__append_81) \
+@MONOLITHIC_FALSE@ $(am__append_83) $(am__append_85) \
+@MONOLITHIC_FALSE@ $(am__append_87) $(am__append_89) \
+@MONOLITHIC_FALSE@ $(am__append_91) $(am__append_93) \
+@MONOLITHIC_FALSE@ $(am__append_95) $(am__append_97) \
+@MONOLITHIC_FALSE@ $(am__append_99) $(am__append_101) \
+@MONOLITHIC_FALSE@ $(am__append_103) $(am__append_105)
# build optional plugins
########################
@@ -778,16 +788,18 @@ EXTRA_DIST = Android.mk
@MONOLITHIC_TRUE@ $(am__append_44) $(am__append_46) \
@MONOLITHIC_TRUE@ $(am__append_48) $(am__append_50) \
@MONOLITHIC_TRUE@ $(am__append_52) $(am__append_54) \
-@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) $(am__append_83) \
-@MONOLITHIC_TRUE@ $(am__append_85) $(am__append_87) \
-@MONOLITHIC_TRUE@ $(am__append_89) $(am__append_91) \
-@MONOLITHIC_TRUE@ $(am__append_93)
+@MONOLITHIC_TRUE@ $(am__append_58) $(am__append_60) \
+@MONOLITHIC_TRUE@ $(am__append_62) $(am__append_64) \
+@MONOLITHIC_TRUE@ $(am__append_66) $(am__append_68) \
+@MONOLITHIC_TRUE@ $(am__append_70) $(am__append_72) \
+@MONOLITHIC_TRUE@ $(am__append_75) $(am__append_77) \
+@MONOLITHIC_TRUE@ $(am__append_79) $(am__append_81) \
+@MONOLITHIC_TRUE@ $(am__append_83) $(am__append_85) \
+@MONOLITHIC_TRUE@ $(am__append_87) $(am__append_89) \
+@MONOLITHIC_TRUE@ $(am__append_91) $(am__append_93) \
+@MONOLITHIC_TRUE@ $(am__append_95) $(am__append_97) \
+@MONOLITHIC_TRUE@ $(am__append_99) $(am__append_101) \
+@MONOLITHIC_TRUE@ $(am__append_103) $(am__append_105)
all: all-recursive
.SUFFIXES:
@@ -822,39 +834,39 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(libdir)'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
}
-uninstall-libLTLIBRARIES:
+uninstall-ipseclibLTLIBRARIES:
@$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
done
-clean-libLTLIBRARIES:
- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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
libcharon.la: $(libcharon_la_OBJECTS) $(libcharon_la_DEPENDENCIES)
- $(LINK) -rpath $(libdir) $(libcharon_la_OBJECTS) $(libcharon_la_LIBADD) $(LIBS)
+ $(LINK) -rpath $(ipseclibdir) $(libcharon_la_OBJECTS) $(libcharon_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -911,7 +923,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_sa_id.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_sa_manager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_vendor.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_recommendations.Plo@am__quote@
@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@
@@ -941,15 +952,13 @@ distclean-compile:
@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@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sim_manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shunt_manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket_manager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/start_action_job.Plo@am__quote@
@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)/tncifimv.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@
@@ -1232,13 +1241,6 @@ kernel_handler.lo: kernel/kernel_handler.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 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
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/packet.Tpo $(DEPDIR)/packet.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/packet.c' object='packet.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 packet.lo `test -f 'network/packet.c' || echo '$(srcdir)/'`network/packet.c
-
receiver.lo: network/receiver.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT receiver.lo -MD -MP -MF $(DEPDIR)/receiver.Tpo -c -o receiver.lo `test -f 'network/receiver.c' || echo '$(srcdir)/'`network/receiver.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/receiver.Tpo $(DEPDIR)/receiver.Plo
@@ -1253,6 +1255,20 @@ sender.lo: network/sender.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 sender.lo `test -f 'network/sender.c' || echo '$(srcdir)/'`network/sender.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
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/packet.Tpo $(DEPDIR)/packet.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/packet.c' object='packet.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 packet.lo `test -f 'network/packet.c' || echo '$(srcdir)/'`network/packet.c
+
+socket.lo: network/socket.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT socket.lo -MD -MP -MF $(DEPDIR)/socket.Tpo -c -o socket.lo `test -f 'network/socket.c' || echo '$(srcdir)/'`network/socket.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/socket.Tpo $(DEPDIR)/socket.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/socket.c' object='socket.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 socket.lo `test -f 'network/socket.c' || echo '$(srcdir)/'`network/socket.c
+
socket_manager.lo: network/socket_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 socket_manager.lo -MD -MP -MF $(DEPDIR)/socket_manager.Tpo -c -o socket_manager.lo `test -f 'network/socket_manager.c' || echo '$(srcdir)/'`network/socket_manager.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/socket_manager.Tpo $(DEPDIR)/socket_manager.Plo
@@ -1386,13 +1402,6 @@ eap_manager.lo: sa/authenticators/eap/eap_manager.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 eap_manager.lo `test -f 'sa/authenticators/eap/eap_manager.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_manager.c
-sim_manager.lo: sa/authenticators/eap/sim_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 sim_manager.lo -MD -MP -MF $(DEPDIR)/sim_manager.Tpo -c -o sim_manager.lo `test -f 'sa/authenticators/eap/sim_manager.c' || echo '$(srcdir)/'`sa/authenticators/eap/sim_manager.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sim_manager.Tpo $(DEPDIR)/sim_manager.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/sim_manager.c' object='sim_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 sim_manager.lo `test -f 'sa/authenticators/eap/sim_manager.c' || echo '$(srcdir)/'`sa/authenticators/eap/sim_manager.c
-
psk_authenticator.lo: sa/authenticators/psk_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 psk_authenticator.lo -MD -MP -MF $(DEPDIR)/psk_authenticator.Tpo -c -o psk_authenticator.lo `test -f 'sa/authenticators/psk_authenticator.c' || echo '$(srcdir)/'`sa/authenticators/psk_authenticator.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/psk_authenticator.Tpo $(DEPDIR)/psk_authenticator.Plo
@@ -1449,6 +1458,13 @@ keymat.lo: sa/keymat.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 keymat.lo `test -f 'sa/keymat.c' || echo '$(srcdir)/'`sa/keymat.c
+shunt_manager.lo: sa/shunt_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 shunt_manager.lo -MD -MP -MF $(DEPDIR)/shunt_manager.Tpo -c -o shunt_manager.lo `test -f 'sa/shunt_manager.c' || echo '$(srcdir)/'`sa/shunt_manager.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/shunt_manager.Tpo $(DEPDIR)/shunt_manager.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/shunt_manager.c' object='shunt_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 shunt_manager.lo `test -f 'sa/shunt_manager.c' || echo '$(srcdir)/'`sa/shunt_manager.c
+
trap_manager.lo: sa/trap_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 trap_manager.lo -MD -MP -MF $(DEPDIR)/trap_manager.Tpo -c -o trap_manager.lo `test -f 'sa/trap_manager.c' || echo '$(srcdir)/'`sa/trap_manager.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/trap_manager.Tpo $(DEPDIR)/trap_manager.Plo
@@ -1575,34 +1591,6 @@ 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
-tncifimv.lo: tnc/tncifimv.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tncifimv.lo -MD -MP -MF $(DEPDIR)/tncifimv.Tpo -c -o tncifimv.lo `test -f 'tnc/tncifimv.c' || echo '$(srcdir)/'`tnc/tncifimv.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tncifimv.Tpo $(DEPDIR)/tncifimv.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/tncifimv.c' object='tncifimv.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 tncifimv.lo `test -f 'tnc/tncifimv.c' || echo '$(srcdir)/'`tnc/tncifimv.c
-
-imv_recommendations.lo: tnc/imv/imv_recommendations.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imv_recommendations.lo -MD -MP -MF $(DEPDIR)/imv_recommendations.Tpo -c -o imv_recommendations.lo `test -f 'tnc/imv/imv_recommendations.c' || echo '$(srcdir)/'`tnc/imv/imv_recommendations.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/imv_recommendations.Tpo $(DEPDIR)/imv_recommendations.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/imv/imv_recommendations.c' object='imv_recommendations.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 imv_recommendations.lo `test -f 'tnc/imv/imv_recommendations.c' || echo '$(srcdir)/'`tnc/imv/imv_recommendations.c
-
-tnccs.lo: tnc/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 'tnc/tnccs/tnccs.c' || echo '$(srcdir)/'`tnc/tnccs/tnccs.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs.Tpo $(DEPDIR)/tnccs.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/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 'tnc/tnccs/tnccs.c' || echo '$(srcdir)/'`tnc/tnccs/tnccs.c
-
-tnccs_manager.lo: tnc/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 'tnc/tnccs/tnccs_manager.c' || echo '$(srcdir)/'`tnc/tnccs/tnccs_manager.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_manager.Tpo $(DEPDIR)/tnccs_manager.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/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 'tnc/tnccs/tnccs_manager.c' || echo '$(srcdir)/'`tnc/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
@@ -1849,7 +1837,7 @@ check: check-recursive
all-am: Makefile $(LTLIBRARIES)
installdirs: installdirs-recursive
installdirs-am:
- for dir in "$(DESTDIR)$(libdir)"; do \
+ for dir in "$(DESTDIR)$(ipseclibdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
@@ -1879,7 +1867,7 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-recursive
@@ -1900,13 +1888,13 @@ info: info-recursive
info-am:
-install-data-am:
+install-data-am: install-ipseclibLTLIBRARIES
install-dvi: install-dvi-recursive
install-dvi-am:
-install-exec-am: install-libLTLIBRARIES
+install-exec-am:
install-html: install-html-recursive
@@ -1946,26 +1934,26 @@ ps: ps-recursive
ps-am:
-uninstall-am: uninstall-libLTLIBRARIES
+uninstall-am: uninstall-ipseclibLTLIBRARIES
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
install-am install-strip tags-recursive
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am check check-am clean clean-generic \
- clean-libLTLIBRARIES clean-libtool ctags ctags-recursive \
+ clean-ipseclibLTLIBRARIES clean-libtool ctags ctags-recursive \
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-libLTLIBRARIES install-man install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs installdirs-am \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
- uninstall-libLTLIBRARIES
+ install-info-am install-ipseclibLTLIBRARIES install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-ipseclibLTLIBRARIES
daemon.lo : $(top_builddir)/config.status
@@ -1974,6 +1962,10 @@ daemon.lo : $(top_builddir)/config.status
@MONOLITHIC_TRUE@@USE_TLS_TRUE@ # otherwise this library is linked to eap_tls
+@MONOLITHIC_TRUE@@USE_RADIUS_TRUE@ # otherwise this library is linked to eap_radius
+
+@MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE@ # otherwise this library is linked to the respective plugins
+
# 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 23931c47d..bf0ab2286 100644
--- a/src/libcharon/bus/bus.c
+++ b/src/libcharon/bus/bus.c
@@ -151,11 +151,20 @@ static void listener_cleanup(cleanup_data_t *data)
entry_destroy(data->entry);
}
-METHOD(bus_t, listen_, void,
- private_bus_t *this, listener_t *listener, job_t *job)
+METHOD(bus_t, listen_, bool,
+ private_bus_t *this, listener_t *listener, job_t *job, u_int timeout)
{
- bool old;
+ bool old, timed_out = FALSE;
cleanup_data_t data;
+ timeval_t tv, add;
+
+ if (timeout)
+ {
+ add.tv_sec = timeout / 1000;
+ add.tv_usec = (timeout - (add.tv_sec * 1000)) * 1000;
+ time_monotonic(&tv);
+ timeradd(&tv, &add, &tv);
+ }
data.this = this;
data.entry = entry_create(listener, TRUE);
@@ -168,13 +177,27 @@ METHOD(bus_t, listen_, void,
old = thread_cancelability(TRUE);
while (data.entry->blocker)
{
- data.entry->condvar->wait(data.entry->condvar, this->mutex);
+ if (timeout)
+ {
+ if (data.entry->condvar->timed_wait_abs(data.entry->condvar,
+ this->mutex, tv))
+ {
+ this->listeners->remove(this->listeners, data.entry, NULL);
+ timed_out = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ data.entry->condvar->wait(data.entry->condvar, this->mutex);
+ }
}
thread_cancelability(old);
thread_cleanup_pop(FALSE);
/* unlock mutex */
thread_cleanup_pop(TRUE);
entry_destroy(data.entry);
+ return timed_out;
}
METHOD(bus_t, set_sa, void,
@@ -564,15 +587,15 @@ METHOD(bus_t, ike_updown, void,
/* a down event for IKE_SA implicitly downs all CHILD_SAs */
if (!up)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
child_sa_t *child_sa;
- iterator = ike_sa->create_child_sa_iterator(ike_sa);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
child_updown(this, child_sa, FALSE);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
}
diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h
index 6a306afcc..69060d383 100644
--- a/src/libcharon/bus/bus.h
+++ b/src/libcharon/bus/bus.h
@@ -80,10 +80,14 @@ typedef struct bus_t bus_t;
* Kind of alerts to raise.
*/
enum alert_t {
- /* a RADIUS server did not respond, no additional arguments */
+ /** a RADIUS server did not respond, no additional arguments */
ALERT_RADIUS_NOT_RESPONDING,
- /* a shutdown signal has been received, argument is a int with the signal */
+ /** a shutdown signal has been received, argument is the signal (int) */
ALERT_SHUTDOWN_SIGNAL,
+ /** peer authentication failed, no arguments */
+ ALERT_PEER_AUTH_FAILED,
+ /** failed to resolve peer address, no arguments */
+ ALERT_PEER_ADDR_FAILED,
};
/**
@@ -148,8 +152,10 @@ struct bus_t {
*
* @param listener listener to register
* @param job job to execute asynchronously when registered, or NULL
+ * @param timeout max timeout in ms to listen for events, 0 to disable
+ * @return TRUE if timed out
*/
- void (*listen)(bus_t *this, listener_t *listener, job_t *job);
+ bool (*listen)(bus_t *this, listener_t *listener, job_t *job, u_int timeout);
/**
* Set the IKE_SA the calling thread is using.
@@ -177,7 +183,7 @@ struct bus_t {
/**
* Send a log message to the bus.
*
- * The signal specifies the type of the event occured. The format string
+ * The signal specifies the type of the event occurred. The format string
* specifies an additional informational or error message with a
* printf() like variable argument list.
* Use the DBG() macros.
diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h
index e7873ee8c..21caed064 100644
--- a/src/libcharon/bus/listeners/listener.h
+++ b/src/libcharon/bus/listeners/listener.h
@@ -84,7 +84,7 @@ struct listener_t {
/**
* Hook called for received/sent messages of an IKE_SA.
*
- * @param ike_sa IKE_SA sending/receving a message
+ * @param ike_sa IKE_SA sending/receiving a message
* @param message message object
* @param incoming TRUE for incoming messages, FALSE for outgoing
* @return TRUE to stay registered, FALSE to unregister
diff --git a/src/libcharon/config/backend_manager.c b/src/libcharon/config/backend_manager.c
index e78cb702d..a93457ea4 100644
--- a/src/libcharon/config/backend_manager.c
+++ b/src/libcharon/config/backend_manager.c
@@ -351,10 +351,18 @@ METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*,
id_match_t match_peer_me, match_peer_other;
ike_cfg_match_t match_ike;
match_entry_t *entry;
+ chunk_t data;
match_peer_me = get_peer_match(my_id, cfg, TRUE);
+ data = my_id->get_encoding(my_id);
+ DBG3(DBG_CFG, "match_peer_me: %d (%N -> %#B)", match_peer_me,
+ id_type_names, my_id->get_type(my_id), &data);
match_peer_other = get_peer_match(other_id, cfg, FALSE);
+ data = other_id->get_encoding(other_id);
+ DBG3(DBG_CFG, "match_peer_other: %d (%N -> %#B)", match_peer_other,
+ id_type_names, other_id->get_type(other_id), &data);
match_ike = get_ike_match(cfg->get_ike_cfg(cfg), me, other);
+ DBG3(DBG_CFG, "match_ike: %d (%H %H)", match_ike, me, other);
if (match_peer_me && match_peer_other && match_ike)
{
diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h
index 175ced76c..370ff9d58 100644
--- a/src/libcharon/config/child_cfg.h
+++ b/src/libcharon/config/child_cfg.h
@@ -73,7 +73,7 @@ struct child_cfg_t {
* Add a proposal to the list.
*
* The proposals are stored by priority, first added
- * is the most prefered.
+ * is the most preferred.
* After add, proposal is owned by child_cfg.
*
* @param proposal proposal to add
@@ -95,7 +95,7 @@ struct child_cfg_t {
*
* Returned propsal is newly created and must be destroyed after usage.
*
- * @param proposals list from from wich proposals are selected
+ * @param proposals list from which proposals are selected
* @param strip_dh TRUE strip out diffie hellman groups
* @param private accept algorithms from a private range
* @return selected proposal, or NULL if nothing matches
diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c
index 89dcd8022..342b9ddbe 100644
--- a/src/libcharon/config/ike_cfg.c
+++ b/src/libcharon/config/ike_cfg.c
@@ -138,26 +138,26 @@ METHOD(ike_cfg_t, get_proposals, linked_list_t*,
METHOD(ike_cfg_t, select_proposal, proposal_t*,
private_ike_cfg_t *this, linked_list_t *proposals, bool private)
{
- iterator_t *stored_iter, *supplied_iter;
+ enumerator_t *stored_enum, *supplied_enum;
proposal_t *stored, *supplied, *selected;
- stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
- supplied_iter = proposals->create_iterator(proposals, TRUE);
+ stored_enum = this->proposals->create_enumerator(this->proposals);
+ supplied_enum = proposals->create_enumerator(proposals);
/* compare all stored proposals with all supplied. Stored ones are preferred.*/
- while (stored_iter->iterate(stored_iter, (void**)&stored))
+ while (stored_enum->enumerate(stored_enum, (void**)&stored))
{
- supplied_iter->reset(supplied_iter);
+ proposals->reset_enumerator(proposals, supplied_enum);
- while (supplied_iter->iterate(supplied_iter, (void**)&supplied))
+ while (supplied_enum->enumerate(supplied_enum, (void**)&supplied))
{
selected = stored->select(stored, supplied, private);
if (selected)
{
/* they match, return */
- stored_iter->destroy(stored_iter);
- supplied_iter->destroy(supplied_iter);
+ stored_enum->destroy(stored_enum);
+ supplied_enum->destroy(supplied_enum);
DBG2(DBG_CFG, "received proposals: %#P", proposals);
DBG2(DBG_CFG, "configured proposals: %#P", this->proposals);
DBG2(DBG_CFG, "selected proposal: %P", selected);
@@ -166,8 +166,8 @@ METHOD(ike_cfg_t, select_proposal, proposal_t*,
}
}
/* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
- stored_iter->destroy(stored_iter);
- supplied_iter->destroy(supplied_iter);
+ stored_enum->destroy(stored_enum);
+ supplied_enum->destroy(supplied_enum);
DBG1(DBG_CFG, "received proposals: %#P", proposals);
DBG1(DBG_CFG, "configured proposals: %#P", this->proposals);
diff --git a/src/libcharon/config/peer_cfg.c b/src/libcharon/config/peer_cfg.c
index 6f0c87279..c623cbc9b 100644
--- a/src/libcharon/config/peer_cfg.c
+++ b/src/libcharon/config/peer_cfg.c
@@ -110,7 +110,7 @@ struct private_peer_cfg_t {
u_int32_t reauth_time;
/**
- * Time, which specifies the range of a random value substracted from above.
+ * Time, which specifies the range of a random value subtracted from above.
*/
u_int32_t jitter_time;
@@ -163,34 +163,26 @@ struct private_peer_cfg_t {
#endif /* ME */
};
-/**
- * Implementation of peer_cfg_t.get_name
- */
-static char *get_name(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_name, char*,
+ private_peer_cfg_t *this)
{
return this->name;
}
-/**
- * Implementation of peer_cfg_t.get_ike_version
- */
-static u_int get_ike_version(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_ike_version, u_int,
+ private_peer_cfg_t *this)
{
return this->ike_version;
}
-/**
- * Implementation of peer_cfg_t.get_ike_cfg
- */
-static ike_cfg_t* get_ike_cfg(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_ike_cfg, ike_cfg_t*,
+ private_peer_cfg_t *this)
{
return this->ike_cfg;
}
-/**
- * Implementation of peer_cfg_t.add_child_cfg.
- */
-static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg)
+METHOD(peer_cfg_t, add_child_cfg, void,
+ private_peer_cfg_t *this, child_cfg_t *child_cfg)
{
this->mutex->lock(this->mutex);
this->child_cfgs->insert_last(this->child_cfgs, child_cfg);
@@ -206,44 +198,39 @@ typedef struct {
mutex_t *mutex;
} child_cfg_enumerator_t;
-/**
- * Implementation of peer_cfg_t.remove_child_cfg.
- */
-static void remove_child_cfg(private_peer_cfg_t *this,
- child_cfg_enumerator_t *enumerator)
+METHOD(peer_cfg_t, remove_child_cfg, void,
+ private_peer_cfg_t *this, child_cfg_enumerator_t *enumerator)
{
this->child_cfgs->remove_at(this->child_cfgs, enumerator->wrapped);
}
-/**
- * Implementation of child_cfg_enumerator_t.destroy
- */
-static void child_cfg_enumerator_destroy(child_cfg_enumerator_t *this)
+METHOD(enumerator_t, child_cfg_enumerator_destroy, void,
+ child_cfg_enumerator_t *this)
{
this->mutex->unlock(this->mutex);
this->wrapped->destroy(this->wrapped);
free(this);
}
-/**
- * Implementation of child_cfg_enumerator_t.enumerate
- */
-static bool child_cfg_enumerate(child_cfg_enumerator_t *this, child_cfg_t **chd)
+METHOD(enumerator_t, child_cfg_enumerate, bool,
+ child_cfg_enumerator_t *this, child_cfg_t **chd)
{
return this->wrapped->enumerate(this->wrapped, chd);
}
-/**
- * Implementation of peer_cfg_t.create_child_cfg_enumerator.
- */
-static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*,
+ private_peer_cfg_t *this)
{
- child_cfg_enumerator_t *enumerator = malloc_thing(child_cfg_enumerator_t);
+ child_cfg_enumerator_t *enumerator;
- enumerator->public.enumerate = (void*)child_cfg_enumerate;
- enumerator->public.destroy = (void*)child_cfg_enumerator_destroy;
- enumerator->mutex = this->mutex;
- enumerator->wrapped = this->child_cfgs->create_enumerator(this->child_cfgs);
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)_child_cfg_enumerate,
+ .destroy = (void*)_child_cfg_enumerator_destroy,
+ },
+ .mutex = this->mutex,
+ .wrapped = this->child_cfgs->create_enumerator(this->child_cfgs),
+ );
this->mutex->lock(this->mutex);
return &enumerator->public;
@@ -292,13 +279,9 @@ static int get_ts_match(child_cfg_t *cfg, bool local,
return match;
}
-/**
- * Implementation of peer_cfg_t.select_child_cfg
- */
-static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
- linked_list_t *my_ts,
- linked_list_t *other_ts,
- host_t *my_host, host_t *other_host)
+METHOD(peer_cfg_t, select_child_cfg, child_cfg_t*,
+ private_peer_cfg_t *this, linked_list_t *my_ts, linked_list_t *other_ts,
+ host_t *my_host, host_t *other_host)
{
child_cfg_t *current, *found = NULL;
enumerator_t *enumerator;
@@ -334,34 +317,26 @@ static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
return found;
}
-/**
- * Implementation of peer_cfg_t.get_cert_policy.
- */
-static cert_policy_t get_cert_policy(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_cert_policy, cert_policy_t,
+ private_peer_cfg_t *this)
{
return this->cert_policy;
}
-/**
- * Implementation of peer_cfg_t.get_unique_policy.
- */
-static unique_policy_t get_unique_policy(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_unique_policy, unique_policy_t,
+ private_peer_cfg_t *this)
{
return this->unique;
}
-/**
- * Implementation of peer_cfg_t.get_keyingtries.
- */
-static u_int32_t get_keyingtries(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_keyingtries, u_int32_t,
+ private_peer_cfg_t *this)
{
return this->keyingtries;
}
-/**
- * Implementation of peer_cfg_t.get_rekey_time.
- */
-static u_int32_t get_rekey_time(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_rekey_time, u_int32_t,
+ private_peer_cfg_t *this)
{
if (this->rekey_time == 0)
{
@@ -374,10 +349,8 @@ static u_int32_t get_rekey_time(private_peer_cfg_t *this)
return this->rekey_time - (random() % this->jitter_time);
}
-/**
- * Implementation of peer_cfg_t.get_reauth_time.
- */
-static u_int32_t get_reauth_time(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_reauth_time, u_int32_t,
+ private_peer_cfg_t *this)
{
if (this->reauth_time == 0)
{
@@ -390,51 +363,38 @@ static u_int32_t get_reauth_time(private_peer_cfg_t *this)
return this->reauth_time - (random() % this->jitter_time);
}
-/**
- * Implementation of peer_cfg_t.get_over_time.
- */
-static u_int32_t get_over_time(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_over_time, u_int32_t,
+ private_peer_cfg_t *this)
{
return this->over_time;
}
-/**
- * Implementation of peer_cfg_t.use_mobike.
- */
-static bool use_mobike(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, use_mobike, bool,
+ private_peer_cfg_t *this)
{
return this->use_mobike;
}
-/**
- * Implements peer_cfg_t.get_dpd
- */
-static u_int32_t get_dpd(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_dpd, u_int32_t,
+ private_peer_cfg_t *this)
{
return this->dpd;
}
-/**
- * Implementation of peer_cfg_t.get_virtual_ip.
- */
-static host_t* get_virtual_ip(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_virtual_ip, host_t*,
+ private_peer_cfg_t *this)
{
return this->virtual_ip;
}
-/**
- * Implementation of peer_cfg_t.get_pool.
- */
-static char* get_pool(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_pool, char*,
+ private_peer_cfg_t *this)
{
return this->pool;
}
-/**
- * Implementation of peer_cfg_t.add_auth_cfg
- */
-static void add_auth_cfg(private_peer_cfg_t *this,
- auth_cfg_t *cfg, bool local)
+METHOD(peer_cfg_t, add_auth_cfg, void,
+ private_peer_cfg_t *this, auth_cfg_t *cfg, bool local)
{
if (local)
{
@@ -446,11 +406,8 @@ static void add_auth_cfg(private_peer_cfg_t *this,
}
}
-/**
- * Implementation of peer_cfg_t.create_auth_cfg_enumerator
- */
-static enumerator_t* create_auth_cfg_enumerator(private_peer_cfg_t *this,
- bool local)
+METHOD(peer_cfg_t, create_auth_cfg_enumerator, enumerator_t*,
+ private_peer_cfg_t *this, bool local)
{
if (local)
{
@@ -460,26 +417,20 @@ static enumerator_t* create_auth_cfg_enumerator(private_peer_cfg_t *this,
}
#ifdef ME
-/**
- * Implementation of peer_cfg_t.is_mediation.
- */
-static bool is_mediation(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, is_mediation, bool,
+ private_peer_cfg_t *this)
{
return this->mediation;
}
-/**
- * Implementation of peer_cfg_t.get_mediated_by.
- */
-static peer_cfg_t* get_mediated_by(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_mediated_by, peer_cfg_t*,
+ private_peer_cfg_t *this)
{
return this->mediated_by;
}
-/**
- * Implementation of peer_cfg_t.get_peer_id.
- */
-static identification_t* get_peer_id(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_peer_id, identification_t*,
+ private_peer_cfg_t *this)
{
return this->peer_id;
}
@@ -539,10 +490,8 @@ static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
return equal;
}
-/**
- * Implementation of peer_cfg_t.equals.
- */
-static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
+METHOD(peer_cfg_t, equals, bool,
+ private_peer_cfg_t *this, private_peer_cfg_t *other)
{
if (this == other)
{
@@ -580,19 +529,15 @@ static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
);
}
-/**
- * Implements peer_cfg_t.get_ref.
- */
-static peer_cfg_t* get_ref(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, get_ref, peer_cfg_t*,
+ private_peer_cfg_t *this)
{
ref_get(&this->refcount);
return &this->public;
}
-/**
- * Implements peer_cfg_t.destroy.
- */
-static void destroy(private_peer_cfg_t *this)
+METHOD(peer_cfg_t, destroy, void,
+ private_peer_cfg_t *this)
{
if (ref_put(&this->refcount))
{
@@ -627,48 +572,8 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
bool mediation, peer_cfg_t *mediated_by,
identification_t *peer_id)
{
- private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t);
-
- /* public functions */
- this->public.get_name = (char* (*) (peer_cfg_t *))get_name;
- this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version;
- this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg;
- this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg;
- this->public.remove_child_cfg = (void(*)(peer_cfg_t*, enumerator_t*))remove_child_cfg;
- this->public.create_child_cfg_enumerator = (enumerator_t* (*) (peer_cfg_t *))create_child_cfg_enumerator;
- this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg;
- this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
- this->public.get_unique_policy = (unique_policy_t (*) (peer_cfg_t *))get_unique_policy;
- this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
- this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time;
- this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time;
- this->public.get_over_time = (u_int32_t(*)(peer_cfg_t*))get_over_time;
- this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
- this->public.get_dpd = (u_int32_t (*) (peer_cfg_t *))get_dpd;
- this->public.get_virtual_ip = (host_t* (*) (peer_cfg_t *))get_virtual_ip;
- this->public.get_pool = (char*(*)(peer_cfg_t*))get_pool;
- this->public.add_auth_cfg = (void(*)(peer_cfg_t*, auth_cfg_t *cfg, bool local))add_auth_cfg;
- this->public.create_auth_cfg_enumerator = (enumerator_t*(*)(peer_cfg_t*, bool local))create_auth_cfg_enumerator;
- this->public.equals = (bool(*)(peer_cfg_t*, peer_cfg_t *other))equals;
- this->public.get_ref = (peer_cfg_t*(*)(peer_cfg_t *))get_ref;
- this->public.destroy = (void(*)(peer_cfg_t *))destroy;
-#ifdef ME
- this->public.is_mediation = (bool (*) (peer_cfg_t *))is_mediation;
- this->public.get_mediated_by = (peer_cfg_t* (*) (peer_cfg_t *))get_mediated_by;
- this->public.get_peer_id = (identification_t* (*) (peer_cfg_t *))get_peer_id;
-#endif /* ME */
+ private_peer_cfg_t *this;
- /* apply init values */
- this->name = strdup(name);
- this->ike_version = ike_version;
- this->ike_cfg = ike_cfg;
- this->child_cfgs = linked_list_create();
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
- this->cert_policy = cert_policy;
- this->unique = unique;
- this->keyingtries = keyingtries;
- this->rekey_time = rekey_time;
- this->reauth_time = reauth_time;
if (rekey_time && jitter_time > rekey_time)
{
jitter_time = rekey_time;
@@ -677,15 +582,58 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
{
jitter_time = reauth_time;
}
- this->jitter_time = jitter_time;
- this->over_time = over_time;
- this->use_mobike = mobike;
- this->dpd = dpd;
- this->virtual_ip = virtual_ip;
- this->pool = strdupnull(pool);
- this->local_auth = linked_list_create();
- this->remote_auth = linked_list_create();
- this->refcount = 1;
+
+ INIT(this,
+ .public = {
+ .get_name = _get_name,
+ .get_ike_version = _get_ike_version,
+ .get_ike_cfg = _get_ike_cfg,
+ .add_child_cfg = _add_child_cfg,
+ .remove_child_cfg = (void*)_remove_child_cfg,
+ .create_child_cfg_enumerator = _create_child_cfg_enumerator,
+ .select_child_cfg = _select_child_cfg,
+ .get_cert_policy = _get_cert_policy,
+ .get_unique_policy = _get_unique_policy,
+ .get_keyingtries = _get_keyingtries,
+ .get_rekey_time = _get_rekey_time,
+ .get_reauth_time = _get_reauth_time,
+ .get_over_time = _get_over_time,
+ .use_mobike = _use_mobike,
+ .get_dpd = _get_dpd,
+ .get_virtual_ip = _get_virtual_ip,
+ .get_pool = _get_pool,
+ .add_auth_cfg = _add_auth_cfg,
+ .create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
+ .equals = (void*)_equals,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+#ifdef ME
+ .is_mediation = _is_mediation,
+ .get_mediated_by = _get_mediated_by,
+ .get_peer_id = _get_peer_id,
+#endif /* ME */
+ },
+ .name = strdup(name),
+ .ike_version = ike_version,
+ .ike_cfg = ike_cfg,
+ .child_cfgs = linked_list_create(),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .cert_policy = cert_policy,
+ .unique = unique,
+ .keyingtries = keyingtries,
+ .rekey_time = rekey_time,
+ .reauth_time = reauth_time,
+ .jitter_time = jitter_time,
+ .over_time = over_time,
+ .use_mobike = mobike,
+ .dpd = dpd,
+ .virtual_ip = virtual_ip,
+ .pool = strdupnull(pool),
+ .local_auth = linked_list_create(),
+ .remote_auth = linked_list_create(),
+ .refcount = 1,
+ );
+
#ifdef ME
this->mediation = mediation;
this->mediated_by = mediated_by;
diff --git a/src/libcharon/config/peer_cfg.h b/src/libcharon/config/peer_cfg.h
index 723435cbb..f644fb547 100644
--- a/src/libcharon/config/peer_cfg.h
+++ b/src/libcharon/config/peer_cfg.h
@@ -82,8 +82,9 @@ extern enum_name_t *unique_policy_names;
* Configuration of a peer, specified by IDs.
*
* The peer config defines a connection between two given IDs. It contains
- * exactly one ike_cfg_t, which is use for initiation. Additionally, it contains
- * multiple child_cfg_t defining which CHILD_SAs are allowed for this peer.
+ * exactly one ike_cfg_t, which is used for initiation. Additionally, it
+ * contains multiple child_cfg_t defining which CHILD_SAs are allowed for this
+ * peer.
* @verbatim
+-------------------+ +---------------+
+---------------+ | peer_cfg | +---------------+ |
@@ -110,7 +111,7 @@ extern enum_name_t *unique_policy_names;
* peer. Each config is enforced using the multiple authentication extension
* (RFC4739).
* The remote authentication configs are handled as constraints. The peer has
- * to fullfill each of these rules (using multiple authentication, in any order)
+ * to fulfill each of these rules (using multiple authentication, in any order)
* to gain access to the configuration.
*/
struct peer_cfg_t {
@@ -127,7 +128,7 @@ struct peer_cfg_t {
/**
* Get the IKE version to use for initiating.
*
- * @return IKE major version
+ * @return IKE major version
*/
u_int (*get_ike_version)(peer_cfg_t *this);
@@ -328,14 +329,14 @@ struct peer_cfg_t {
* (rekeylifetime - random(0, jitter)).
*
* @param name name of the peer_cfg
- * @param ike_version which IKE version we sould use for this peer
+ * @param ike_version which IKE version we should use for this peer
* @param ike_cfg IKE config to use when acting as initiator
* @param cert_policy should we send a certificate payload?
* @param unique uniqueness of an IKE_SA
* @param keyingtries how many keying tries should be done before giving up
* @param rekey_time timeout before starting rekeying
* @param reauth_time timeout before starting reauthentication
- * @param jitter_time timerange to randomly substract from rekey/reauth time
+ * @param jitter_time timerange to randomly subtract from rekey/reauth time
* @param over_time maximum overtime before closing a rekeying/reauth SA
* @param mobike use MOBIKE (RFC4555) if peer supports it
* @param dpd DPD check interval, 0 to disable
@@ -344,7 +345,7 @@ struct peer_cfg_t {
* @param mediation TRUE if this is a mediation connection
* @param mediated_by peer_cfg_t of the mediation connection to mediate through
* @param peer_id ID that identifies our peer at the mediation server
- * @return peer_cfg_t object
+ * @return peer_cfg_t object
*/
peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
cert_policy_t cert_policy, unique_policy_t unique,
diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c
index 2251b82dd..d3c60a469 100644
--- a/src/libcharon/config/proposal.c
+++ b/src/libcharon/config/proposal.c
@@ -598,6 +598,9 @@ static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
case AUTH_CAMELLIA_XCBC_96:
prf = PRF_CAMELLIA128_XCBC;
break;
+ case AUTH_AES_CMAC_96:
+ prf = PRF_AES128_CMAC;
+ break;
default:
prf = PRF_UNDEFINED;
}
@@ -794,6 +797,7 @@ static void proposal_add_supported_ike(private_proposal_t *this)
case AUTH_HMAC_SHA2_512_256:
case AUTH_HMAC_MD5_96:
case AUTH_AES_XCBC_96:
+ case AUTH_AES_CMAC_96:
add_algorithm(this, INTEGRITY_ALGORITHM, integrity, 0);
break;
default:
@@ -813,6 +817,7 @@ static void proposal_add_supported_ike(private_proposal_t *this)
case PRF_HMAC_SHA2_512:
case PRF_HMAC_MD5:
case PRF_AES128_XCBC:
+ case PRF_AES128_CMAC:
add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0);
break;
default:
diff --git a/src/libcharon/config/proposal.h b/src/libcharon/config/proposal.h
index 9337518bf..8f54d7e6e 100644
--- a/src/libcharon/config/proposal.h
+++ b/src/libcharon/config/proposal.h
@@ -120,7 +120,7 @@ struct proposal_t {
* compared. If they have at least one algorithm of each type
* in common, a resulting proposal of this kind is created.
*
- * @param other proposal to compair agains
+ * @param other proposal to compare against
* @param private accepts algorithms allocated in a private range
* @return selected proposal, NULL if proposals don't match
*/
@@ -180,7 +180,7 @@ struct proposal_t {
*
* @param protocol protocol, such as PROTO_ESP
* @param number proposal number, as encoded in SA payload
- * @return proposal_t object
+ * @return proposal_t object
*/
proposal_t *proposal_create(protocol_id_t protocol, u_int number);
@@ -188,7 +188,7 @@ proposal_t *proposal_create(protocol_id_t protocol, u_int number);
* Create a default proposal if nothing further specified.
*
* @param protocol protocol, such as PROTO_ESP
- * @return proposal_t object
+ * @return proposal_t object
*/
proposal_t *proposal_create_default(protocol_id_t protocol);
@@ -203,7 +203,7 @@ proposal_t *proposal_create_default(protocol_id_t protocol);
*
* @param protocol protocol, such as PROTO_ESP
* @param algs algorithms as string
- * @return proposal_t object
+ * @return proposal_t object
*/
proposal_t *proposal_create_from_string(protocol_id_t protocol, const char *algs);
diff --git a/src/libcharon/control/controller.c b/src/libcharon/control/controller.c
index 5bc19d11b..0f247962b 100644
--- a/src/libcharon/control/controller.c
+++ b/src/libcharon/control/controller.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2007-2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -96,6 +97,7 @@ typedef struct interface_job_t interface_job_t;
* job for asynchronous listen operations
*/
struct interface_job_t {
+
/**
* job interface
*/
@@ -107,12 +109,9 @@ struct interface_job_t {
interface_listener_t listener;
};
-/**
- * listener log function
- */
-static bool listener_log(interface_listener_t *this, debug_t group,
- level_t level, int thread, ike_sa_t *ike_sa,
- char* format, va_list args)
+METHOD(listener_t, listener_log, bool,
+ interface_listener_t *this, debug_t group, level_t level, int thread,
+ ike_sa_t *ike_sa, char* format, va_list args)
{
if (this->ike_sa == ike_sa)
{
@@ -124,11 +123,14 @@ static bool listener_log(interface_listener_t *this, debug_t group,
return TRUE;
}
-/**
- * Implementation of listener_t.ike_state_change
- */
-static bool listener_ike_state(interface_listener_t *this, ike_sa_t *ike_sa,
- ike_sa_state_t state)
+METHOD(job_t, get_priority_medium, job_priority_t,
+ job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
+METHOD(listener_t, ike_state_change, bool,
+ interface_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
{
if (this->ike_sa == ike_sa)
{
@@ -160,11 +162,9 @@ static bool listener_ike_state(interface_listener_t *this, ike_sa_t *ike_sa,
return TRUE;
}
-/**
- * Implementation of listener_t.child_state_change
- */
-static bool listener_child_state(interface_listener_t *this, ike_sa_t *ike_sa,
- child_sa_t *child_sa, child_sa_state_t state)
+METHOD(listener_t, child_state_change, bool,
+ interface_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
+ child_sa_state_t state)
{
if (this->ike_sa == ike_sa)
{
@@ -191,10 +191,8 @@ static bool listener_child_state(interface_listener_t *this, ike_sa_t *ike_sa,
return TRUE;
}
-/**
- * cleanup job if job is never executed
- */
-static void recheckin(interface_job_t *job)
+METHOD(job_t, recheckin, void,
+ interface_job_t *job)
{
if (job->listener.ike_sa)
{
@@ -203,18 +201,15 @@ static void recheckin(interface_job_t *job)
}
}
-/**
- * Implementation of controller_t.create_ike_sa_iterator.
- */
-static enumerator_t* create_ike_sa_enumerator(controller_t *this)
+METHOD(controller_t, create_ike_sa_enumerator, enumerator_t*,
+ private_controller_t *this, bool wait)
{
- return charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager);
+ return charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager,
+ wait);
}
-/**
- * execute function for initiate
- */
-static status_t initiate_execute(interface_job_t *job)
+METHOD(job_t, initiate_execute, void,
+ interface_job_t *job)
{
ike_sa_t *ike_sa;
interface_listener_t *listener = &job->listener;
@@ -233,25 +228,26 @@ static status_t initiate_execute(interface_job_t *job)
if (ike_sa->initiate(ike_sa, listener->child_cfg, 0, NULL, NULL) == SUCCESS)
{
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
- return SUCCESS;
+ listener->status = SUCCESS;
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+ ike_sa);
+ listener->status = FAILED;
}
- charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
- return FAILED;
}
-/**
- * Implementation of controller_t.initiate.
- */
-static status_t initiate(private_controller_t *this,
- peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- controller_cb_t callback, void *param)
+METHOD(controller_t, initiate, status_t,
+ private_controller_t *this, peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
+ controller_cb_t callback, void *param, u_int timeout)
{
interface_job_t job = {
.listener = {
.public = {
- .log = (void*)listener_log,
- .ike_state_change = (void*)listener_ike_state,
- .child_state_change = (void*)listener_child_state,
+ .log = _listener_log,
+ .ike_state_change = _ike_state_change,
+ .child_state_change = _child_state_change,
},
.callback = callback,
.param = param,
@@ -260,22 +256,28 @@ static status_t initiate(private_controller_t *this,
.peer_cfg = peer_cfg,
},
.public = {
- .execute = (void*)initiate_execute,
- .destroy = (void*)recheckin,
+ .execute = _initiate_execute,
+ .get_priority = _get_priority_medium,
+ .destroy = _recheckin,
},
};
if (callback == NULL)
{
- return initiate_execute(&job);
+ initiate_execute(&job);
+ }
+ else
+ {
+ if (charon->bus->listen(charon->bus, &job.listener.public, &job.public,
+ timeout))
+ {
+ job.listener.status = OUT_OF_RES;
+ }
}
- charon->bus->listen(charon->bus, &job.listener.public, (job_t*)&job);
return job.listener.status;
}
-/**
- * execute function for terminate_ike
- */
-static status_t terminate_ike_execute(interface_job_t *job)
+METHOD(job_t, terminate_ike_execute, void,
+ interface_job_t *job)
{
interface_listener_t *listener = &job->listener;
ike_sa_t *ike_sa = listener->ike_sa;
@@ -286,25 +288,27 @@ static status_t terminate_ike_execute(interface_job_t *job)
{
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
/* delete failed */
- return FAILED;
+ listener->status = FAILED;
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+ ike_sa);
+ listener->status = SUCCESS;
}
- charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
- return SUCCESS;
}
-/**
- * Implementation of controller_t.terminate_ike.
- */
-static status_t terminate_ike(controller_t *this, u_int32_t unique_id,
- controller_cb_t callback, void *param)
+METHOD(controller_t, terminate_ike, status_t,
+ controller_t *this, u_int32_t unique_id,
+ controller_cb_t callback, void *param, u_int timeout)
{
ike_sa_t *ike_sa;
interface_job_t job = {
.listener = {
.public = {
- .log = (void*)listener_log,
- .ike_state_change = (void*)listener_ike_state,
- .child_state_change = (void*)listener_child_state,
+ .log = _listener_log,
+ .ike_state_change = _ike_state_change,
+ .child_state_change = _child_state_change,
},
.callback = callback,
.param = param,
@@ -312,8 +316,9 @@ static status_t terminate_ike(controller_t *this, u_int32_t unique_id,
.id = unique_id,
},
.public = {
- .execute = (void*)terminate_ike_execute,
- .destroy = (void*)recheckin,
+ .execute = _terminate_ike_execute,
+ .get_priority = _get_priority_medium,
+ .destroy = _recheckin,
},
};
@@ -328,18 +333,23 @@ static status_t terminate_ike(controller_t *this, u_int32_t unique_id,
if (callback == NULL)
{
- return terminate_ike_execute(&job);
+ terminate_ike_execute(&job);
+ }
+ else
+ {
+ if (charon->bus->listen(charon->bus, &job.listener.public, &job.public,
+ timeout))
+ {
+ job.listener.status = OUT_OF_RES;
+ }
+ /* checkin of the ike_sa happened in the thread that executed the job */
+ charon->bus->set_sa(charon->bus, NULL);
}
- charon->bus->listen(charon->bus, &job.listener.public, (job_t*)&job);
- /* checkin of the ike_sa happend in the thread that executed the job */
- charon->bus->set_sa(charon->bus, NULL);
return job.listener.status;
}
-/**
- * execute function for terminate_child
- */
-static status_t terminate_child_execute(interface_job_t *job)
+METHOD(job_t, terminate_child_execute, void,
+ interface_job_t *job)
{
interface_listener_t *listener = &job->listener;
ike_sa_t *ike_sa = listener->ike_sa;
@@ -350,27 +360,29 @@ static status_t terminate_child_execute(interface_job_t *job)
child_sa->get_spi(child_sa, TRUE)) != DESTROY_ME)
{
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
- return SUCCESS;
+ listener->status = SUCCESS;
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+ ike_sa);
+ listener->status = FAILED;
}
- charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
- return FAILED;
}
-/**
- * Implementation of controller_t.terminate_child.
- */
-static status_t terminate_child(controller_t *this, u_int32_t reqid,
- controller_cb_t callback, void *param)
+METHOD(controller_t, terminate_child, status_t,
+ controller_t *this, u_int32_t reqid,
+ controller_cb_t callback, void *param, u_int timeout)
{
ike_sa_t *ike_sa;
child_sa_t *child_sa;
- iterator_t *iterator;
+ enumerator_t *enumerator;
interface_job_t job = {
.listener = {
.public = {
- .log = (void*)listener_log,
- .ike_state_change = (void*)listener_ike_state,
- .child_state_change = (void*)listener_child_state,
+ .log = _listener_log,
+ .ike_state_change = _ike_state_change,
+ .child_state_change = _child_state_change,
},
.callback = callback,
.param = param,
@@ -378,8 +390,9 @@ static status_t terminate_child(controller_t *this, u_int32_t reqid,
.id = reqid,
},
.public = {
- .execute = (void*)terminate_child_execute,
- .destroy = (void*)recheckin,
+ .execute = _terminate_child_execute,
+ .get_priority = _get_priority_medium,
+ .destroy = _recheckin,
},
};
@@ -393,8 +406,8 @@ static status_t terminate_child(controller_t *this, u_int32_t reqid,
}
job.listener.ike_sa = ike_sa;
- iterator = ike_sa->create_child_sa_iterator(ike_sa);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
if (child_sa->get_state(child_sa) != CHILD_ROUTED &&
child_sa->get_reqid(child_sa) == reqid)
@@ -403,7 +416,7 @@ static status_t terminate_child(controller_t *this, u_int32_t reqid,
}
child_sa = NULL;
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
if (child_sa == NULL)
{
@@ -416,11 +429,18 @@ static status_t terminate_child(controller_t *this, u_int32_t reqid,
if (callback == NULL)
{
- return terminate_child_execute(&job);
+ terminate_child_execute(&job);
+ }
+ else
+ {
+ if (charon->bus->listen(charon->bus, &job.listener.public, &job.public,
+ timeout))
+ {
+ job.listener.status = OUT_OF_RES;
+ }
+ /* checkin of the ike_sa happened in the thread that executed the job */
+ charon->bus->set_sa(charon->bus, NULL);
}
- charon->bus->listen(charon->bus, &job.listener.public, (job_t*)&job);
- /* checkin of the ike_sa happend in the thread that executed the job */
- charon->bus->set_sa(charon->bus, NULL);
return job.listener.status;
}
@@ -428,15 +448,13 @@ static status_t terminate_child(controller_t *this, u_int32_t reqid,
* See header
*/
bool controller_cb_empty(void *param, debug_t group, level_t level,
- ike_sa_t *ike_sa, char *format, va_list args)
+ ike_sa_t *ike_sa, char *format, va_list args)
{
return TRUE;
}
-/**
- * Implementation of stroke_t.destroy.
- */
-static void destroy(private_controller_t *this)
+METHOD(controller_t, destroy, void,
+ private_controller_t *this)
{
free(this);
}
@@ -446,13 +464,17 @@ static void destroy(private_controller_t *this)
*/
controller_t *controller_create(void)
{
- private_controller_t *this = malloc_thing(private_controller_t);
+ private_controller_t *this;
- this->public.create_ike_sa_enumerator = (enumerator_t*(*)(controller_t*))create_ike_sa_enumerator;
- this->public.initiate = (status_t(*)(controller_t*,peer_cfg_t*,child_cfg_t*,controller_cb_t,void*))initiate;
- this->public.terminate_ike = (status_t(*)(controller_t*,u_int32_t,controller_cb_t, void*))terminate_ike;
- this->public.terminate_child = (status_t(*)(controller_t*,u_int32_t,controller_cb_t, void *param))terminate_child;
- this->public.destroy = (void (*)(controller_t*))destroy;
+ INIT(this,
+ .public = {
+ .create_ike_sa_enumerator = _create_ike_sa_enumerator,
+ .initiate = _initiate,
+ .terminate_ike = _terminate_ike,
+ .terminate_child = _terminate_child,
+ .destroy = _destroy,
+ },
+ );
return &this->public;
}
diff --git a/src/libcharon/control/controller.h b/src/libcharon/control/controller.h
index 31b69c78c..6adaef109 100644
--- a/src/libcharon/control/controller.h
+++ b/src/libcharon/control/controller.h
@@ -56,7 +56,7 @@ typedef struct controller_t controller_t;
*
* Passing NULL as callback to the managers function calls them asynchronously.
* If a callback is specified, they are called synchronously. There is a default
- * callback "controller_cb_empty" if you wan't to call a function
+ * callback "controller_cb_empty" if you want to call a function
* synchronously, but don't need a callback.
*/
struct controller_t {
@@ -65,11 +65,12 @@ struct controller_t {
* Create an enumerator for all IKE_SAs.
*
* The enumerator blocks the IKE_SA manager until it gets destroyed. Do
- * not call another interface/manager method while the iterator is alive.
+ * not call another interface/manager method while the enumerator is alive.
*
+ * @param wait TRUE to wait for checked out SAs, FALSE to skip
* @return enumerator, locks IKE_SA manager until destroyed
*/
- enumerator_t* (*create_ike_sa_enumerator)(controller_t *this);
+ enumerator_t* (*create_ike_sa_enumerator)(controller_t *this, bool wait);
/**
* Initiate a CHILD_SA, and if required, an IKE_SA.
@@ -82,14 +83,16 @@ struct controller_t {
* @param child_cfg child_cfg to set up CHILD_SA from
* @param cb logging callback
* @param param parameter to include in each call of cb
+ * @param timeout timeout in ms to wait for callbacks, 0 to disable
* @return
* - SUCCESS, if CHILD_SA established
* - FAILED, if setup failed
* - NEED_MORE, if callback returned FALSE
+ * - OUT_OF_RES if timed out
*/
status_t (*initiate)(controller_t *this,
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- controller_cb_t callback, void *param);
+ controller_cb_t callback, void *param, u_int timeout);
/**
* Terminate an IKE_SA and all of its CHILD_SAs.
@@ -101,13 +104,16 @@ struct controller_t {
* @param unique_id unique id of the IKE_SA to terminate.
* @param cb logging callback
* @param param parameter to include in each call of cb
+ * @param timeout timeout in ms to wait for callbacks, 0 to disable
* @return
* - SUCCESS, if CHILD_SA terminated
* - NOT_FOUND, if no such CHILD_SA found
* - NEED_MORE, if callback returned FALSE
+ * - OUT_OF_RES if timed out
*/
status_t (*terminate_ike)(controller_t *this, u_int32_t unique_id,
- controller_cb_t callback, void *param);
+ controller_cb_t callback, void *param,
+ u_int timeout);
/**
* Terminate a CHILD_SA.
@@ -115,13 +121,16 @@ struct controller_t {
* @param reqid reqid of the CHILD_SA to terminate
* @param cb logging callback
* @param param parameter to include in each call of cb
+ * @param timeout timeout in ms to wait for callbacks, 0 to disable
* @return
* - SUCCESS, if CHILD_SA terminated
* - NOT_FOUND, if no such CHILD_SA found
* - NEED_MORE, if callback returned FALSE
+ * - OUT_OF_RES if timed out
*/
status_t (*terminate_child)(controller_t *this, u_int32_t reqid,
- controller_cb_t callback, void *param);
+ controller_cb_t callback, void *param,
+ u_int timeout);
/**
* Destroy a controller_t instance.
diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c
index 796e455a7..3fb49d475 100644
--- a/src/libcharon/daemon.c
+++ b/src/libcharon/daemon.c
@@ -32,6 +32,7 @@
#include "daemon.h"
#include <library.h>
+#include <plugins/plugin.h>
#include <config/proposal.h>
#include <kernel/kernel_handler.h>
#include <processing/jobs/start_action_job.h>
@@ -104,8 +105,18 @@ static void destroy(private_daemon_t *this)
{
this->public.ike_sa_manager->flush(this->public.ike_sa_manager);
}
+ if (this->public.traps)
+ {
+ this->public.traps->flush(this->public.traps);
+ }
DESTROY_IF(this->public.receiver);
DESTROY_IF(this->public.sender);
+#ifdef ME
+ DESTROY_IF(this->public.connect_manager);
+ DESTROY_IF(this->public.mediation_manager);
+#endif /* ME */
+ /* make sure the cache is clear before unloading plugins */
+ lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
/* unload plugins to release threads */
lib->plugins->unload(lib->plugins);
#ifdef CAPABILITIES_LIBCAP
@@ -113,15 +124,10 @@ static void destroy(private_daemon_t *this)
#endif /* CAPABILITIES_LIBCAP */
DESTROY_IF(this->kernel_handler);
DESTROY_IF(this->public.traps);
+ DESTROY_IF(this->public.shunts);
DESTROY_IF(this->public.ike_sa_manager);
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);
@@ -195,27 +201,6 @@ METHOD(daemon_t, start, void,
DEFAULT_THREADS));
}
-/**
- * Log loaded plugins
- */
-static void print_plugins()
-{
- char buf[512];
- int len = 0;
- enumerator_t *enumerator;
- plugin_t *plugin;
-
- buf[0] = '\0';
- enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
- while (len < sizeof(buf) && enumerator->enumerate(enumerator, &plugin))
- {
- len += snprintf(&buf[len], sizeof(buf)-len, "%s ",
- plugin->get_name(plugin));
- }
- enumerator->destroy(enumerator);
- DBG1(DBG_DMN, "loaded plugins: %s", buf);
-}
-
METHOD(daemon_t, initialize, bool,
private_daemon_t *this)
{
@@ -236,8 +221,8 @@ METHOD(daemon_t, initialize, bool,
{
return FALSE;
}
-
- print_plugins();
+ DBG1(DBG_DMN, "loaded plugins: %s",
+ lib->plugins->loaded_plugins(lib->plugins));
this->public.ike_sa_manager = ike_sa_manager_create();
if (this->public.ike_sa_manager == NULL)
@@ -287,11 +272,10 @@ private_daemon_t *daemon_create()
charon = &this->public;
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.socket = socket_manager_create();
this->public.traps = trap_manager_create();
+ this->public.shunts = shunt_manager_create();
this->kernel_handler = kernel_handler_create();
#ifdef CAPABILITIES
@@ -322,9 +306,7 @@ void libcharon_deinit()
*/
bool libcharon_init()
{
- private_daemon_t *this;
-
- this = daemon_create();
+ daemon_create();
/* for uncritical pseudo random numbers */
srandom(time(NULL) + getpid());
diff --git a/src/libcharon/daemon.h b/src/libcharon/daemon.h
index 04f1fc249..2e01c8d9b 100644
--- a/src/libcharon/daemon.h
+++ b/src/libcharon/daemon.h
@@ -146,12 +146,9 @@ typedef struct daemon_t daemon_t;
#include <bus/listeners/sys_logger.h>
#include <sa/ike_sa_manager.h>
#include <sa/trap_manager.h>
+#include <sa/shunt_manager.h>
#include <config/backend_manager.h>
#include <sa/authenticators/eap/eap_manager.h>
-#include <sa/authenticators/eap/sim_manager.h>
-#include <tnc/imc/imc_manager.h>
-#include <tnc/imv/imv_manager.h>
-#include <tnc/tnccs/tnccs_manager.h>
#ifdef ME
#include <sa/connect_manager.h>
@@ -194,6 +191,11 @@ struct daemon_t {
trap_manager_t *traps;
/**
+ * Manager for shunt PASS|DROP policies
+ */
+ shunt_manager_t *shunts;
+
+ /**
* Manager for the different configuration backends.
*/
backend_manager_t *backends;
@@ -233,26 +235,6 @@ struct daemon_t {
*/
eap_manager_t *eap;
- /**
- * SIM manager to maintain (U)SIM cards/providers
- */
- sim_manager_t *sim;
-
- /**
- * TNC IMC manager controlling Integrity Measurement Collectors
- */
- imc_manager_t *imcs;
-
- /**
- * TNC IMV manager controlling Integrity Measurement Verifiers
- */
- imv_manager_t *imvs;
-
- /**
- * 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 ce3844361..60fa7e0c4 100644
--- a/src/libcharon/encoding/generator.c
+++ b/src/libcharon/encoding/generator.c
@@ -523,7 +523,7 @@ METHOD(generator_t, generate_payload, void,
payload_type_names, payload_type);
DBG3(DBG_ENC, "generated data for this payload %b",
this->buffer + offset_start,
- this->out_position - this->buffer - offset_start);
+ (u_int)(this->out_position - this->buffer - offset_start));
}
METHOD(generator_t, destroy, void,
diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c
index 214612fdb..2b5399294 100644
--- a/src/libcharon/encoding/message.c
+++ b/src/libcharon/encoding/message.c
@@ -63,13 +63,13 @@
typedef struct {
/* Payload type */
payload_type_t type;
- /* Minimal occurence of this payload. */
+ /* Minimal occurrence of this payload. */
size_t min_occurence;
- /* Max occurence of this payload. */
+ /* Max occurrence of this payload. */
size_t max_occurence;
/* TRUE if payload must be encrypted */
bool encrypted;
- /* If payload occurs, the message rule is fullfilled */
+ /* If payload occurs, the message rule is fulfilled */
bool sufficient;
} payload_rule_t;
@@ -861,9 +861,23 @@ static char* get_string(private_message_t *this, char *buf, int len)
len -= written;
if (payload->get_type(payload) == NOTIFY)
{
- notify_payload_t *notify = (notify_payload_t*)payload;
- written = snprintf(pos, len, "(%N)", notify_type_short_names,
- notify->get_notify_type(notify));
+ notify_payload_t *notify;
+ notify_type_t type;
+ chunk_t data;
+
+ notify = (notify_payload_t*)payload;
+ type = notify->get_notify_type(notify);
+ data = notify->get_notification_data(notify);
+ if (type == MS_NOTIFY_STATUS && data.len == 4)
+ {
+ written = snprintf(pos, len, "(%N(%d))", notify_type_short_names,
+ type, untoh32(data.ptr));
+ }
+ else
+ {
+ written = snprintf(pos, len, "(%N)", notify_type_short_names,
+ type);
+ }
if (written >= len || written < 0)
{
return buf;
@@ -1065,7 +1079,7 @@ METHOD(message_t, generate, status_t,
encryption_payload_t *encryption = NULL;
enumerator_t *enumerator;
chunk_t chunk;
- char str[256];
+ char str[BUF_LEN];
u_int32_t *lenpos;
bool *reserved;
int i;
@@ -1312,7 +1326,7 @@ static status_t decrypt_payloads(private_message_t *this, aead_t *aead)
DBG2(DBG_ENC, "found an encryption payload");
- if (enumerator->enumerate(enumerator, &payload))
+ if (this->payloads->has_more(this->payloads, enumerator))
{
DBG1(DBG_ENC, "encrypted payload is not last payload");
status = VERIFY_ERROR;
@@ -1405,7 +1419,7 @@ static status_t verify(private_message_t *this)
if (found > rule->max_occurence)
{
DBG1(DBG_ENC, "payload of type %N more than %d times (%d) "
- "occured in current message", payload_type_names,
+ "occurred in current message", payload_type_names,
type, rule->max_occurence, found);
enumerator->destroy(enumerator);
return VERIFY_ERROR;
@@ -1416,7 +1430,7 @@ static status_t verify(private_message_t *this)
if (!complete && found < rule->min_occurence)
{
- DBG1(DBG_ENC, "payload of type %N not occured %d times (%d)",
+ DBG1(DBG_ENC, "payload of type %N not occurred %d times (%d)",
payload_type_names, rule->type, rule->min_occurence, found);
return VERIFY_ERROR;
}
@@ -1434,7 +1448,7 @@ METHOD(message_t, parse_body, status_t,
status_t status = SUCCESS;
payload_t *payload;
payload_type_t type;
- char str[256];
+ char str[BUF_LEN];
type = this->first_payload;
diff --git a/src/libcharon/encoding/message.h b/src/libcharon/encoding/message.h
index 51197308c..0e78ea436 100644
--- a/src/libcharon/encoding/message.h
+++ b/src/libcharon/encoding/message.h
@@ -321,7 +321,7 @@ struct message_t {
/**
* Find a payload of a specific type.
*
- * Returns the first occurance.
+ * Returns the first occurrence.
*
* @param type type of the payload to find
* @return payload, or NULL if no such payload found
diff --git a/src/libcharon/encoding/parser.c b/src/libcharon/encoding/parser.c
index 32cefb9e7..e49210309 100644
--- a/src/libcharon/encoding/parser.c
+++ b/src/libcharon/encoding/parser.c
@@ -86,12 +86,6 @@ struct private_parser_t {
};
/**
- * Forward declaration
- */
-static status_t parse_payload(private_parser_t *this,
- payload_type_t payload_type, payload_t **payload);
-
-/**
* Log invalid length error
*/
static bool short_input(private_parser_t *this, int number)
@@ -320,7 +314,8 @@ static bool parse_list(private_parser_t *this, int rule_number,
DBG2(DBG_ENC, " %d bytes left, parsing recursively %N",
length, payload_type_names, payload_type);
- if (parse_payload(this, payload_type, &payload) != SUCCESS)
+ if (this->public.parse_payload(&this->public, payload_type,
+ &payload) != SUCCESS)
{
DBG1(DBG_ENC, " parsing of a %N substructure failed",
payload_type_names, payload_type);
@@ -363,11 +358,8 @@ static bool parse_chunk(private_parser_t *this, int rule_number,
return TRUE;
}
-/**
- * Implementation of parser_t.parse_payload.
- */
-static status_t parse_payload(private_parser_t *this,
- payload_type_t payload_type, payload_t **payload)
+METHOD(parser_t, parse_payload, status_t,
+ private_parser_t *this, payload_type_t payload_type, payload_t **payload)
{
payload_t *pld;
void *output;
@@ -385,7 +377,7 @@ static status_t parse_payload(private_parser_t *this,
payload_type_names, payload_type, this->input_roof - this->byte_pos);
DBG3(DBG_ENC, "parsing payload from %b",
- this->byte_pos, this->input_roof - this->byte_pos);
+ this->byte_pos, (u_int)(this->input_roof - this->byte_pos));
/* base pointer for output, avoids casting in every rule */
output = pld;
@@ -785,27 +777,21 @@ static status_t parse_payload(private_parser_t *this,
return SUCCESS;
}
-/**
- * Implementation of parser_t.get_remaining_byte_count.
- */
-static int get_remaining_byte_count (private_parser_t *this)
+METHOD(parser_t, get_remaining_byte_count, int,
+ private_parser_t *this)
{
return this->input_roof - this->byte_pos;
}
-/**
- * Implementation of parser_t.reset_context.
- */
-static void reset_context (private_parser_t *this)
+METHOD(parser_t, reset_context, void,
+ private_parser_t *this)
{
this->byte_pos = this->input;
this->bit_pos = 0;
}
-/**
- * Implementation of parser_t.destroy.
- */
-static void destroy(private_parser_t *this)
+METHOD(parser_t, destroy, void,
+ private_parser_t *this)
{
free(this);
}
@@ -815,17 +801,19 @@ static void destroy(private_parser_t *this)
*/
parser_t *parser_create(chunk_t data)
{
- private_parser_t *this = malloc_thing(private_parser_t);
-
- this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**))parse_payload;
- this->public.reset_context = (void(*)(parser_t*)) reset_context;
- this->public.get_remaining_byte_count = (int (*) (parser_t *))get_remaining_byte_count;
- this->public.destroy = (void(*)(parser_t*)) destroy;
-
- this->input = data.ptr;
- this->byte_pos = data.ptr;
- this->bit_pos = 0;
- this->input_roof = data.ptr + data.len;
+ private_parser_t *this;
+
+ INIT(this,
+ .public = {
+ .parse_payload = _parse_payload,
+ .reset_context = _reset_context,
+ .get_remaining_byte_count = _get_remaining_byte_count,
+ .destroy = _destroy,
+ },
+ .input = data.ptr,
+ .byte_pos = data.ptr,
+ .input_roof = data.ptr + data.len,
+ );
return &this->public;
}
diff --git a/src/libcharon/encoding/payloads/certreq_payload.c b/src/libcharon/encoding/payloads/certreq_payload.c
index 8e0836f0e..02015f273 100644
--- a/src/libcharon/encoding/payloads/certreq_payload.c
+++ b/src/libcharon/encoding/payloads/certreq_payload.c
@@ -111,8 +111,7 @@ METHOD(payload_t, verify, status_t,
{
if (this->encoding == ENC_X509_SIGNATURE)
{
- if (this->data.len < HASH_SIZE_SHA1 ||
- this->data.len % HASH_SIZE_SHA1)
+ if (this->data.len % HASH_SIZE_SHA1)
{
DBG1(DBG_ENC, "invalid X509 hash length (%d) in certreq",
this->data.len);
diff --git a/src/libcharon/encoding/payloads/cp_payload.h b/src/libcharon/encoding/payloads/cp_payload.h
index 7dcf58f7e..afae6091a 100644
--- a/src/libcharon/encoding/payloads/cp_payload.h
+++ b/src/libcharon/encoding/payloads/cp_payload.h
@@ -63,7 +63,7 @@ struct cp_payload_t {
payload_t payload_interface;
/**
- * Creates an iterator of stored configuration_attribute_t objects.
+ * Creates an enumerator of stored configuration_attribute_t objects.
*
* @return enumerator over configration_attribute_T
*/
diff --git a/src/libcharon/encoding/payloads/eap_payload.c b/src/libcharon/encoding/payloads/eap_payload.c
index eafb668b6..cacaef222 100644
--- a/src/libcharon/encoding/payloads/eap_payload.c
+++ b/src/libcharon/encoding/payloads/eap_payload.c
@@ -284,6 +284,18 @@ eap_payload_t *eap_payload_create_data(chunk_t data)
/*
* Described in header
*/
+eap_payload_t *eap_payload_create_data_own(chunk_t data)
+{
+ eap_payload_t *this = eap_payload_create();
+
+ this->set_data(this, data);
+ free(data.ptr);
+ return this;
+}
+
+/*
+ * Described in header
+ */
eap_payload_t *eap_payload_create_code(eap_code_t code, u_int8_t identifier)
{
chunk_t data;
diff --git a/src/libcharon/encoding/payloads/eap_payload.h b/src/libcharon/encoding/payloads/eap_payload.h
index 0bde4b15e..60d9c99d2 100644
--- a/src/libcharon/encoding/payloads/eap_payload.h
+++ b/src/libcharon/encoding/payloads/eap_payload.h
@@ -95,18 +95,27 @@ struct eap_payload_t {
/**
* Creates an empty eap_payload_t object.
*
- * @return eap_payload_t object
+ * @return eap_payload_t object
*/
eap_payload_t *eap_payload_create(void);
/**
* Creates an eap_payload_t object with data.
*
- * @return eap_payload_t object
+ * @param data data, gets cloned
+ * @return eap_payload_t object
*/
eap_payload_t *eap_payload_create_data(chunk_t data);
/**
+ * Creates an eap_payload_t object with data, owning the data.
+ *
+ * @param data data on heap, gets owned and freed
+ * @return eap_payload_t object
+ */
+eap_payload_t *eap_payload_create_data_own(chunk_t data);
+
+/**
* Creates an eap_payload_t object with a code.
*
* Could should be either EAP_SUCCESS/EAP_FAILURE, use
diff --git a/src/libcharon/encoding/payloads/encryption_payload.c b/src/libcharon/encoding/payloads/encryption_payload.c
index 3b23ea9fb..e7b8063b7 100644
--- a/src/libcharon/encoding/payloads/encryption_payload.c
+++ b/src/libcharon/encoding/payloads/encryption_payload.c
@@ -142,7 +142,7 @@ METHOD(payload_t, set_next_type, void,
}
/**
- * Compute the lenght of the whole payload
+ * Compute the length of the whole payload
*/
static void compute_length(private_encryption_payload_t *this)
{
diff --git a/src/libcharon/encoding/payloads/endpoint_notify.c b/src/libcharon/encoding/payloads/endpoint_notify.c
index faec1ea71..1ead0a052 100644
--- a/src/libcharon/encoding/payloads/endpoint_notify.c
+++ b/src/libcharon/encoding/payloads/endpoint_notify.c
@@ -76,6 +76,11 @@ ENUM(me_endpoint_type_names, HOST, RELAYED,
);
/**
+ * Forward declaration
+ */
+static private_endpoint_notify_t *endpoint_notify_create();
+
+/**
* Helper functions to parse integer values
*/
static status_t parse_uint8(u_int8_t **cur, u_int8_t *top, u_int8_t *val)
@@ -216,10 +221,8 @@ static chunk_t build_notification_data(private_endpoint_notify_t *this)
return data;
}
-/**
- * Implementation of endpoint_notify_t.build_notify
- */
-static notify_payload_t *build_notify(private_endpoint_notify_t *this)
+METHOD(endpoint_notify_t, build_notify, notify_payload_t*,
+ private_endpoint_notify_t *this)
{
chunk_t data;
notify_payload_t *notify;
@@ -233,64 +236,53 @@ static notify_payload_t *build_notify(private_endpoint_notify_t *this)
return notify;
}
-/**
- * Implementation of endpoint_notify_t.get_priority.
- */
-static u_int32_t get_priority(private_endpoint_notify_t *this)
+
+METHOD(endpoint_notify_t, get_priority, u_int32_t,
+ private_endpoint_notify_t *this)
{
return this->priority;
}
-/**
- * Implementation of endpoint_notify_t.set_priority.
- */
-static void set_priority(private_endpoint_notify_t *this, u_int32_t priority)
+METHOD(endpoint_notify_t, set_priority, void,
+ private_endpoint_notify_t *this, u_int32_t priority)
{
this->priority = priority;
}
-/**
- * Implementation of endpoint_notify_t.get_type.
- */
-static me_endpoint_type_t get_type(private_endpoint_notify_t *this)
+METHOD(endpoint_notify_t, get_type, me_endpoint_type_t,
+ private_endpoint_notify_t *this)
{
return this->type;
}
-/**
- * Implementation of endpoint_notify_t.get_family.
- */
-static me_endpoint_family_t get_family(private_endpoint_notify_t *this)
+METHOD(endpoint_notify_t, get_family, me_endpoint_family_t,
+ private_endpoint_notify_t *this)
{
return this->family;
}
-/**
- * Implementation of endpoint_notify_t.get_host.
- */
-static host_t *get_host(private_endpoint_notify_t *this)
+METHOD(endpoint_notify_t, get_host, host_t*,
+ private_endpoint_notify_t *this)
{
return this->endpoint;
}
-/**
- * Implementation of endpoint_notify_t.get_base.
- */
-static host_t *get_base(private_endpoint_notify_t *this)
+METHOD(endpoint_notify_t, get_base, host_t*,
+ private_endpoint_notify_t *this)
{
return (!this->base) ? this->endpoint : this->base;
}
-/**
- * Implementation of endpoint_notify_t.clone.
- */
-static endpoint_notify_t *_clone(private_endpoint_notify_t *this)
+METHOD(endpoint_notify_t, clone_, endpoint_notify_t*,
+ private_endpoint_notify_t *this)
{
- private_endpoint_notify_t *clone = (private_endpoint_notify_t*)endpoint_notify_create();
+ private_endpoint_notify_t *clone;
+ clone = endpoint_notify_create();
clone->priority = this->priority;
clone->type = this->type;
clone->family = this->family;
+
if (this->endpoint)
{
clone->endpoint = this->endpoint->clone(this->endpoint);
@@ -304,52 +296,47 @@ static endpoint_notify_t *_clone(private_endpoint_notify_t *this)
return &clone->public;
}
-/**
- * Implementation of endpoint_notify_t.destroy.
- */
-static status_t destroy(private_endpoint_notify_t *this)
+METHOD(endpoint_notify_t, destroy, void,
+ private_endpoint_notify_t *this)
{
DESTROY_IF(this->endpoint);
DESTROY_IF(this->base);
free(this);
- return SUCCESS;
}
-/*
- * Described in header
+/**
+ * Creates an empty endpoint notify
*/
-endpoint_notify_t *endpoint_notify_create()
+static private_endpoint_notify_t *endpoint_notify_create()
{
- private_endpoint_notify_t *this = malloc_thing(private_endpoint_notify_t);
-
- /* public functions */
- this->public.get_priority = (u_int32_t (*) (endpoint_notify_t *)) get_priority;
- this->public.set_priority = (void (*) (endpoint_notify_t *, u_int32_t)) set_priority;
- this->public.get_type = (me_endpoint_type_t (*) (endpoint_notify_t *)) get_type;
- this->public.get_family = (me_endpoint_family_t (*) (endpoint_notify_t *)) get_family;
- this->public.get_host = (host_t *(*) (endpoint_notify_t *)) get_host;
- this->public.get_base = (host_t *(*) (endpoint_notify_t *)) get_base;
- this->public.build_notify = (notify_payload_t *(*) (endpoint_notify_t *)) build_notify;
- this->public.clone = (endpoint_notify_t *(*) (endpoint_notify_t *)) _clone;
- this->public.destroy = (void (*) (endpoint_notify_t *)) destroy;
-
- /* set default values of the fields */
- this->priority = 0;
- this->family = NO_FAMILY;
- this->type = NO_TYPE;
- this->endpoint = NULL;
- this->base = NULL;
-
- return &this->public;
+ private_endpoint_notify_t *this;
+
+ INIT(this,
+ .public = {
+ .get_priority = _get_priority,
+ .set_priority = _set_priority,
+ .get_type = _get_type,
+ .get_family = _get_family,
+ .get_host = _get_host,
+ .get_base = _get_base,
+ .build_notify = _build_notify,
+ .clone = _clone_,
+ .destroy = _destroy,
+ },
+ .family = NO_FAMILY,
+ .type = NO_TYPE,
+ );
+
+ return this;
}
/**
* Described in header
*/
-endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type, host_t *host, host_t *base)
+endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type,
+ host_t *host, host_t *base)
{
- private_endpoint_notify_t *this = (private_endpoint_notify_t*)endpoint_notify_create();
-
+ private_endpoint_notify_t *this = endpoint_notify_create();
this->type = type;
switch(type)
@@ -406,13 +393,17 @@ endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type, hos
*/
endpoint_notify_t *endpoint_notify_create_from_payload(notify_payload_t *notify)
{
+ private_endpoint_notify_t *this;
+ chunk_t data;
+
if (notify->get_notify_type(notify) != ME_ENDPOINT)
{
return NULL;
}
- private_endpoint_notify_t *this = (private_endpoint_notify_t*)endpoint_notify_create();
- chunk_t data = notify->get_notification_data(notify);
+ this = endpoint_notify_create();
+ data = notify->get_notification_data(notify);
+
if (parse_notification_data(this, data) != SUCCESS)
{
destroy(this);
diff --git a/src/libcharon/encoding/payloads/endpoint_notify.h b/src/libcharon/encoding/payloads/endpoint_notify.h
index 120eef49a..853aadf3d 100644
--- a/src/libcharon/encoding/payloads/endpoint_notify.h
+++ b/src/libcharon/encoding/payloads/endpoint_notify.h
@@ -125,7 +125,7 @@ struct endpoint_notify_t {
/**
* Generates a notification payload from this endpoint.
*
- * @return built notify_payload_t
+ * @return built notify_payload_t
*/
notify_payload_t *(*build_notify) (endpoint_notify_t *this);
@@ -143,19 +143,12 @@ struct endpoint_notify_t {
};
/**
- * Creates an empty endpoint_notify_t object.
- *
- * @return created endpoint_notify_t object
- */
-endpoint_notify_t *endpoint_notify_create(void);
-
-
-/**
* Creates an endpoint_notify_t object from a host.
*
* @param type the endpoint type
* @param host host to base the notify on (gets cloned)
- * @param base base of the endpoint, applies only to reflexive endpoints (gets cloned)
+ * @param base base of the endpoint, applies only to reflexive
+ * endpoints (gets cloned)
* @return created endpoint_notify_t object
*/
endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type,
@@ -166,7 +159,7 @@ endpoint_notify_t *endpoint_notify_create_from_host(me_endpoint_type_t type,
*
* @param notify the notify payload
* @return - created endpoint_notify_t object
- * - NULL if invalid payload
+ * - NULL if invalid payload
*/
endpoint_notify_t *endpoint_notify_create_from_payload(notify_payload_t *notify);
diff --git a/src/libcharon/encoding/payloads/ike_header.c b/src/libcharon/encoding/payloads/ike_header.c
index 80dcee0cb..24d22f3a1 100644
--- a/src/libcharon/encoding/payloads/ike_header.c
+++ b/src/libcharon/encoding/payloads/ike_header.c
@@ -101,17 +101,18 @@ struct private_ike_header_t {
ENUM_BEGIN(exchange_type_names, EXCHANGE_TYPE_UNDEFINED, EXCHANGE_TYPE_UNDEFINED,
"EXCHANGE_TYPE_UNDEFINED");
-ENUM_NEXT(exchange_type_names, IKE_SA_INIT, INFORMATIONAL, EXCHANGE_TYPE_UNDEFINED,
+ENUM_NEXT(exchange_type_names, IKE_SA_INIT, IKE_SESSION_RESUME, EXCHANGE_TYPE_UNDEFINED,
"IKE_SA_INIT",
"IKE_AUTH",
"CREATE_CHILD_SA",
- "INFORMATIONAL");
+ "INFORMATIONAL",
+ "IKE_SESSION_RESUME");
#ifdef ME
-ENUM_NEXT(exchange_type_names, ME_CONNECT, ME_CONNECT, INFORMATIONAL,
+ENUM_NEXT(exchange_type_names, ME_CONNECT, ME_CONNECT, IKE_SESSION_RESUME,
"ME_CONNECT");
ENUM_END(exchange_type_names, ME_CONNECT);
#else
-ENUM_END(exchange_type_names, INFORMATIONAL);
+ENUM_END(exchange_type_names, IKE_SESSION_RESUME);
#endif /* ME */
/**
diff --git a/src/libcharon/encoding/payloads/ike_header.h b/src/libcharon/encoding/payloads/ike_header.h
index f52c852c5..5579a4961 100644
--- a/src/libcharon/encoding/payloads/ike_header.h
+++ b/src/libcharon/encoding/payloads/ike_header.h
@@ -80,6 +80,11 @@ enum exchange_type_t{
* INFORMATIONAL.
*/
INFORMATIONAL = 37,
+
+ /**
+ * IKE_SESSION_RESUME (RFC 5723).
+ */
+ IKE_SESSION_RESUME = 38,
#ifdef ME
/**
* ME_CONNECT
diff --git a/src/libcharon/encoding/payloads/notify_payload.c b/src/libcharon/encoding/payloads/notify_payload.c
index 77f15ec6d..e03d1af67 100644
--- a/src/libcharon/encoding/payloads/notify_payload.c
+++ b/src/libcharon/encoding/payloads/notify_payload.c
@@ -56,7 +56,9 @@ ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTIC
"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, EAP_ONLY_AUTHENTICATION, ME_CONNECT_FAILED,
+ENUM_NEXT(notify_type_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
+ "MS_NOTIFY_STATUS");
+ENUM_NEXT(notify_type_names, INITIAL_CONTACT, PSK_CONFIRM, MS_NOTIFY_STATUS,
"INITIAL_CONTACT",
"SET_WINDOW_SIZE",
"ADDITIONAL_TS_POSSIBLE",
@@ -90,18 +92,28 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, EAP_ONLY_AUTHENTICATION, ME_CONNEC
"LINK_ID",
"USE_WESP_MODE",
"ROHC_SUPPORTED",
- "EAP_ONLY_AUTHENTICATION");
-ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
+ "EAP_ONLY_AUTHENTICATION",
+ "CHILDLESS_IKEV2_SUPPORTED",
+ "QUICK_CRASH_DETECTION",
+ "IKEV2_MESSAGE_ID_SYNC_SUPPORTED",
+ "IKEV2_REPLAY_COUNTER_SYNC_SUPPORTED",
+ "IKEV2_MESSAGE_ID_SYNC",
+ "IPSEC_REPLAY_COUNTER_SYNC",
+ "SECURE PASSWORD_METHOD",
+ "PSK_PERSIST",
+ "PSK_CONFIRM");
+ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, PSK_CONFIRM,
"USE_BEET_MODE");
-ENUM_NEXT(notify_type_names, ME_MEDIATION, ME_RESPONSE, USE_BEET_MODE,
+ENUM_NEXT(notify_type_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE,
"ME_MEDIATION",
"ME_ENDPOINT",
"ME_CALLBACK",
"ME_CONNECTID",
"ME_CONNECTKEY",
"ME_CONNECTAUTH",
- "ME_RESPONSE");
-ENUM_END(notify_type_names, ME_RESPONSE);
+ "ME_RESPONSE",
+ "RADIUS_ATTRIBUTE",);
+ENUM_END(notify_type_names, RADIUS_ATTRIBUTE);
ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
@@ -135,11 +147,13 @@ ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUT
"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, EAP_ONLY_AUTHENTICATION, ME_CONNECT_FAILED,
+ENUM_NEXT(notify_type_short_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
+ "MS_STATUS");
+ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, PSK_CONFIRM, MS_NOTIFY_STATUS,
"INIT_CONTACT",
"SET_WINSIZE",
"ADD_TS_POSS",
- "IPCOMP_SUPP",
+ "IPCOMP_SUP",
"NATD_S_IP",
"NATD_D_IP",
"COOKIE",
@@ -169,18 +183,28 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, EAP_ONLY_AUTHENTICATION, ME_
"LINK_ID",
"WESP_MODE",
"ROHC_SUP",
- "EAP_ONLY");
-ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
+ "EAP_ONLY",
+ "CHDLESS_SUP",
+ "CRASH_DET",
+ "MSG_ID_SYN_SUP",
+ "RPL_CTR_SYN_SUP",
+ "MSG_ID_SYN",
+ "RPL_CTR_SYN",
+ "SEC_PASSWD",
+ "PSK_PST",
+ "PSK_CFM");
+ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, PSK_CONFIRM,
"BEET_MODE");
-ENUM_NEXT(notify_type_short_names, ME_MEDIATION, ME_RESPONSE, USE_BEET_MODE,
+ENUM_NEXT(notify_type_short_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE,
"ME_MED",
"ME_EP",
"ME_CB",
"ME_CID",
"ME_CKEY",
"ME_CAUTH",
- "ME_R");
-ENUM_END(notify_type_short_names, ME_RESPONSE);
+ "ME_R",
+ "RADIUS");
+ENUM_END(notify_type_short_names, RADIUS_ATTRIBUTE);
typedef struct private_notify_payload_t private_notify_payload_t;
diff --git a/src/libcharon/encoding/payloads/notify_payload.h b/src/libcharon/encoding/payloads/notify_payload.h
index 8abc236e1..ced282700 100644
--- a/src/libcharon/encoding/payloads/notify_payload.h
+++ b/src/libcharon/encoding/payloads/notify_payload.h
@@ -71,6 +71,9 @@ enum notify_type_t {
/* IKE-ME, private use */
ME_CONNECT_FAILED = 8192,
+ /* Windows error code */
+ MS_NOTIFY_STATUS = 12345,
+
/* notify status messages */
INITIAL_CONTACT = 16384,
SET_WINDOW_SIZE = 16385,
@@ -115,7 +118,20 @@ enum notify_type_t {
ROHC_SUPPORTED = 16416,
/* EAP-only authentication, RFC 5998 */
EAP_ONLY_AUTHENTICATION = 16417,
-
+ /* Childless initiation of IKEv2 SA, RFC 6023 */
+ CHILDLESS_IKEV2_SUPPORTED = 16418,
+ /* Quick crash detection for IKE, RFC 6290 */
+ QUICK_CRASH_DETECTION = 16419,
+ /* High availability of IKEv2/IPsec, RFC 6311 */
+ IKEV2_MESSAGE_ID_SYNC_SUPPORTED = 16420,
+ IKEV2_REPLAY_COUNTER_SYNC_SUPPORTED = 16421,
+ IKEV2_MESSAGE_ID_SYNC = 16422,
+ IPSEC_REPLAY_COUNTER_SYNC = 16423,
+ /* Secure password methods, RFC 6467 */
+ SECURE_PASSWORD_METHOD = 16424,
+ /* PACE - draft-kuegler-ipsecme-pace-ikev2 */
+ PSK_PERSIST = 16425,
+ PSK_CONFIRM = 16426,
/* BEET mode, not even a draft yet. private use */
USE_BEET_MODE = 40961,
/* IKE-ME, private use */
@@ -125,7 +141,9 @@ enum notify_type_t {
ME_CONNECTID = 40965,
ME_CONNECTKEY = 40966,
ME_CONNECTAUTH = 40967,
- ME_RESPONSE = 40968
+ ME_RESPONSE = 40968,
+ /* RADIUS attribute received/to send to a AAA backend */
+ RADIUS_ATTRIBUTE = 40969,
};
/**
diff --git a/src/libcharon/encoding/payloads/payload.c b/src/libcharon/encoding/payloads/payload.c
index d1e677db7..a2c0a4385 100644
--- a/src/libcharon/encoding/payloads/payload.c
+++ b/src/libcharon/encoding/payloads/payload.c
@@ -39,7 +39,8 @@
ENUM_BEGIN(payload_type_names, NO_PAYLOAD, NO_PAYLOAD,
"NO_PAYLOAD");
-ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, NO_PAYLOAD,
+ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION,
+ GENERIC_SECURE_PASSWORD_METHOD, NO_PAYLOAD,
"SECURITY_ASSOCIATION",
"KEY_EXCHANGE",
"ID_INITIATOR",
@@ -55,9 +56,10 @@ ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, N
"TRAFFIC_SELECTOR_RESPONDER",
"ENCRYPTED",
"CONFIGURATION",
- "EXTENSIBLE_AUTHENTICATION");
+ "EXTENSIBLE_AUTHENTICATION",
+ "GENERIC_SECURE_PASSWORD_METHOD");
#ifdef ME
-ENUM_NEXT(payload_type_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION,
+ENUM_NEXT(payload_type_names, ID_PEER, ID_PEER, GENERIC_SECURE_PASSWORD_METHOD,
"ID_PEER");
ENUM_NEXT(payload_type_names, HEADER, CONFIGURATION_ATTRIBUTE, ID_PEER,
"HEADER",
@@ -67,7 +69,8 @@ ENUM_NEXT(payload_type_names, HEADER, CONFIGURATION_ATTRIBUTE, ID_PEER,
"TRAFFIC_SELECTOR_SUBSTRUCTURE",
"CONFIGURATION_ATTRIBUTE");
#else
-ENUM_NEXT(payload_type_names, HEADER, CONFIGURATION_ATTRIBUTE, EXTENSIBLE_AUTHENTICATION,
+ENUM_NEXT(payload_type_names, HEADER, CONFIGURATION_ATTRIBUTE,
+ GENERIC_SECURE_PASSWORD_METHOD,
"HEADER",
"PROPOSAL_SUBSTRUCTURE",
"TRANSFORM_SUBSTRUCTURE",
@@ -80,7 +83,8 @@ ENUM_END(payload_type_names, CONFIGURATION_ATTRIBUTE);
/* short forms of payload names */
ENUM_BEGIN(payload_type_short_names, NO_PAYLOAD, NO_PAYLOAD,
"--");
-ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, NO_PAYLOAD,
+ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION,
+ GENERIC_SECURE_PASSWORD_METHOD, NO_PAYLOAD,
"SA",
"KE",
"IDi",
@@ -96,9 +100,11 @@ ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICAT
"TSr",
"E",
"CP",
- "EAP");
+ "EAP",
+ "GSPM");
#ifdef ME
-ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION,
+ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER,
+ GENERIC_SECURE_PASSWORD_METHOD,
"IDp");
ENUM_NEXT(payload_type_short_names, HEADER, CONFIGURATION_ATTRIBUTE, ID_PEER,
"HDR",
@@ -108,7 +114,8 @@ ENUM_NEXT(payload_type_short_names, HEADER, CONFIGURATION_ATTRIBUTE, ID_PEER,
"TSSUB",
"CPATTR");
#else
-ENUM_NEXT(payload_type_short_names, HEADER, CONFIGURATION_ATTRIBUTE, EXTENSIBLE_AUTHENTICATION,
+ENUM_NEXT(payload_type_short_names, HEADER, CONFIGURATION_ATTRIBUTE,
+ GENERIC_SECURE_PASSWORD_METHOD,
"HDR",
"PROP",
"TRANS",
diff --git a/src/libcharon/encoding/payloads/payload.h b/src/libcharon/encoding/payloads/payload.h
index 0f407ff42..a9af29b5b 100644
--- a/src/libcharon/encoding/payloads/payload.h
+++ b/src/libcharon/encoding/payloads/payload.h
@@ -79,7 +79,7 @@ enum payload_type_t{
AUTHENTICATION = 39,
/**
- * Nonces, for initator and responder (Ni, Nr, N)
+ * Nonces, for initiator and responder (Ni, Nr, N)
*/
NONCE = 40,
@@ -123,6 +123,11 @@ enum payload_type_t{
*/
EXTENSIBLE_AUTHENTICATION = 48,
+ /**
+ * Generic Secure Password Method (GSPM).
+ */
+ GENERIC_SECURE_PASSWORD_METHOD = 49,
+
#ifdef ME
/**
* Identification payload for peers has a value from
diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c
index f39c3b0e6..4753d574d 100644
--- a/src/libcharon/encoding/payloads/proposal_substructure.c
+++ b/src/libcharon/encoding/payloads/proposal_substructure.c
@@ -407,7 +407,7 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(
this = (private_proposal_substructure_t*)proposal_substructure_create();
- /* encryption algorithm is only availble in ESP */
+ /* encryption algorithm is only available in ESP */
enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM);
while (enumerator->enumerate(enumerator, &alg, &key_size))
{
diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c
index db20d052f..010f63cfd 100644
--- a/src/libcharon/encoding/payloads/sa_payload.c
+++ b/src/libcharon/encoding/payloads/sa_payload.c
@@ -106,7 +106,6 @@ METHOD(payload_t, verify, status_t,
status_t status = SUCCESS;
enumerator_t *enumerator;
proposal_substructure_t *substruct;
- bool first = TRUE;
/* check proposal numbering */
enumerator = this->proposals->create_enumerator(this->proposals);
@@ -115,16 +114,6 @@ METHOD(payload_t, verify, status_t,
current_number = substruct->get_proposal_number(substruct);
if (current_number < expected_number)
{
- if (current_number != expected_number + 1)
- {
- DBG1(DBG_ENC, "proposal number is %d, expected %d or %d",
- current_number, expected_number, expected_number + 1);
- status = FAILED;
- break;
- }
- }
- else if (current_number < expected_number)
- {
DBG1(DBG_ENC, "proposal number smaller than previous");
status = FAILED;
break;
@@ -136,7 +125,6 @@ METHOD(payload_t, verify, status_t,
DBG1(DBG_ENC, "PROPOSAL_SUBSTRUCTURE verification failed");
break;
}
- first = FALSE;
expected_number = current_number;
}
enumerator->destroy(enumerator);
diff --git a/src/libcharon/encoding/payloads/transform_substructure.c b/src/libcharon/encoding/payloads/transform_substructure.c
index 0428da726..3f04b3539 100644
--- a/src/libcharon/encoding/payloads/transform_substructure.c
+++ b/src/libcharon/encoding/payloads/transform_substructure.c
@@ -84,7 +84,7 @@ encoding_rule_t transform_substructure_encodings[] = {
{ U_INT_8, offsetof(private_transform_substructure_t, transform_type) },
/* 1 Reserved Byte */
{ RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[1]) },
- /* tranform ID is a number of 8 bit */
+ /* transform ID is a number of 8 bit */
{ U_INT_16, offsetof(private_transform_substructure_t, transform_id) },
/* Attributes are stored in a transform attribute,
offset points to a linked_list_t pointer */
diff --git a/src/libcharon/encoding/payloads/transform_substructure.h b/src/libcharon/encoding/payloads/transform_substructure.h
index c961700a4..102dbb3d3 100644
--- a/src/libcharon/encoding/payloads/transform_substructure.h
+++ b/src/libcharon/encoding/payloads/transform_substructure.h
@@ -118,7 +118,7 @@ transform_substructure_t *transform_substructure_create(void);
*
* @param type type of transform to create
* @param id transform id specifc for the transform type
- * @param key_length key length for key lenght attribute, 0 to omit
+ * @param key_length key length for key length attribute, 0 to omit
* @return transform_substructure_t object
*/
transform_substructure_t *transform_substructure_create_type(
diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c
index d9e39fe43..51fccb1ac 100644
--- a/src/libcharon/kernel/kernel_handler.c
+++ b/src/libcharon/kernel/kernel_handler.c
@@ -125,6 +125,8 @@ METHOD(kernel_listener_t, roam, bool,
private_kernel_handler_t *this, bool address)
{
job_t *job;
+ DBG2(DBG_KNL, "creating roam job %s", address ? "due to address/link change"
+ : "due to route change");
job = (job_t*)roam_job_create(address);
lib->processor->queue_job(lib->processor, job);
return TRUE;
diff --git a/src/libcharon/network/receiver.c b/src/libcharon/network/receiver.c
index d8cebe192..cfb1408ef 100644
--- a/src/libcharon/network/receiver.c
+++ b/src/libcharon/network/receiver.c
@@ -30,6 +30,8 @@
/** lifetime of a cookie, in seconds */
#define COOKIE_LIFETIME 10
+/** time we wait before disabling cookies */
+#define COOKIE_CALMDOWN_DELAY 10
/** how many times to reuse the secret */
#define COOKIE_REUSE 10000
/** default value for private_receiver_t.cookie_threshold */
@@ -96,11 +98,26 @@ struct private_receiver_t {
u_int32_t cookie_threshold;
/**
+ * timestamp of last cookie requested
+ */
+ time_t last_cookie;
+
+ /**
* how many half open IKE_SAs per peer before blocking
*/
u_int32_t block_threshold;
/**
+ * Drop IKE_SA_INIT requests if processor job load exceeds this limit
+ */
+ u_int init_limit_job_load;
+
+ /**
+ * Drop IKE_SA_INIT requests if half open IKE_SA count exceeds this limit
+ */
+ u_int init_limit_half_open;
+
+ /**
* Delay for receiving incoming packets, to simulate larger RTT
*/
int receive_delay;
@@ -215,55 +232,146 @@ static bool cookie_verify(private_receiver_t *this, message_t *message,
}
/**
- * check if cookies are required, and if so, a valid cookie is included
+ * Check if a valid cookie found
*/
-static bool cookie_required(private_receiver_t *this, message_t *message)
+static bool check_cookie(private_receiver_t *this, message_t *message)
{
- bool failed = FALSE;
-
- if (charon->ike_sa_manager->get_half_open_count(charon->ike_sa_manager,
- NULL) >= this->cookie_threshold)
+ packet_t *packet;
+ chunk_t data;
+
+ /* check for a cookie. We don't use our parser here and do it
+ * quick and dirty for performance reasons.
+ * we assume the cookie is the first payload (which is a MUST), and
+ * the cookie's SPI length is zero. */
+ packet = message->get_packet(message);
+ data = packet->get_data(packet);
+ if (data.len <
+ IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH +
+ sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher) ||
+ *(data.ptr + 16) != NOTIFY ||
+ *(u_int16_t*)(data.ptr + IKE_HEADER_LENGTH + 6) != htons(COOKIE))
{
- /* check for a cookie. We don't use our parser here and do it
- * quick and dirty for performance reasons.
- * we assume the cookie is the first payload (which is a MUST), and
- * the cookie's SPI length is zero. */
- packet_t *packet = message->get_packet(message);
- chunk_t data = packet->get_data(packet);
- if (data.len <
- IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH +
- sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher) ||
- *(data.ptr + 16) != NOTIFY ||
- *(u_int16_t*)(data.ptr + IKE_HEADER_LENGTH + 6) != htons(COOKIE))
- {
- /* no cookie found */
- failed = TRUE;
- }
- else
- {
- data.ptr += IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH;
- data.len = sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher);
- if (!cookie_verify(this, message, data))
- {
- DBG2(DBG_NET, "found cookie, but content invalid");
- failed = TRUE;
- }
- }
+ /* no cookie found */
+ packet->destroy(packet);
+ return FALSE;
+ }
+ data.ptr += IKE_HEADER_LENGTH + NOTIFY_PAYLOAD_HEADER_LENGTH;
+ data.len = sizeof(u_int32_t) + this->hasher->get_hash_size(this->hasher);
+ if (!cookie_verify(this, message, data))
+ {
+ DBG2(DBG_NET, "found cookie, but content invalid");
packet->destroy(packet);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Check if we currently require cookies
+ */
+static bool cookie_required(private_receiver_t *this,
+ u_int half_open, u_int32_t now)
+{
+ if (this->cookie_threshold && half_open >= this->cookie_threshold)
+ {
+ this->last_cookie = now;
+ return TRUE;
+ }
+ if (now < this->last_cookie + COOKIE_CALMDOWN_DELAY)
+ {
+ /* We don't disable cookies unless we haven't seen IKE_SA_INITs
+ * for COOKIE_CALMDOWN_DELAY seconds. This avoids jittering between
+ * cookie on / cookie off states, which is problematic. Consider the
+ * following: A legitimiate initiator sends a IKE_SA_INIT while we
+ * are under a DoS attack. If we toggle our cookie behavior,
+ * multiple retransmits of this IKE_SA_INIT might get answered with
+ * and without cookies. The initiator goes on and retries with
+ * a cookie, but it can't know if the completing IKE_SA_INIT response
+ * is to its IKE_SA_INIT request with or without cookies. This is
+ * problematic, as the cookie is part of AUTH payload data.
+ */
+ this->last_cookie = now;
+ return TRUE;
}
- return failed;
+ return FALSE;
}
/**
- * check if peer has to many half open IKE_SAs
+ * Check if we should drop IKE_SA_INIT because of cookie/overload checking
*/
-static bool peer_too_aggressive(private_receiver_t *this, message_t *message)
+static bool drop_ike_sa_init(private_receiver_t *this, message_t *message)
{
- if (charon->ike_sa_manager->get_half_open_count(charon->ike_sa_manager,
- message->get_source(message)) >= this->block_threshold)
+ u_int half_open;
+ u_int32_t now;
+
+ now = time_monotonic(NULL);
+ half_open = charon->ike_sa_manager->get_half_open_count(
+ charon->ike_sa_manager, NULL);
+
+ /* check for cookies */
+ if (cookie_required(this, half_open, now) && !check_cookie(this, message))
+ {
+ chunk_t cookie;
+
+ cookie = cookie_build(this, message, now - this->secret_offset,
+ chunk_from_thing(this->secret));
+ DBG2(DBG_NET, "received packet from: %#H to %#H",
+ message->get_source(message),
+ message->get_destination(message));
+ DBG2(DBG_NET, "sending COOKIE notify to %H",
+ message->get_source(message));
+ send_notify(message, COOKIE, cookie);
+ chunk_free(&cookie);
+ if (++this->secret_used > COOKIE_REUSE)
+ {
+ /* create new cookie */
+ DBG1(DBG_NET, "generating new cookie secret after %d uses",
+ this->secret_used);
+ memcpy(this->secret_old, this->secret, SECRET_LENGTH);
+ this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret);
+ this->secret_switch = now;
+ this->secret_used = 0;
+ }
+ return TRUE;
+ }
+
+ /* check if peer has too many IKE_SAs half open */
+ if (this->block_threshold &&
+ charon->ike_sa_manager->get_half_open_count(charon->ike_sa_manager,
+ message->get_source(message)) >= this->block_threshold)
+ {
+ DBG1(DBG_NET, "ignoring IKE_SA setup from %H, "
+ "peer too aggressive", message->get_source(message));
+ return TRUE;
+ }
+
+ /* check if global half open IKE_SA limit reached */
+ if (this->init_limit_half_open &&
+ half_open >= this->init_limit_half_open)
{
+ DBG1(DBG_NET, "ignoring IKE_SA setup from %H, half open IKE_SA "
+ "count of %d exceeds limit of %d", message->get_source(message),
+ half_open, this->init_limit_half_open);
return TRUE;
}
+
+ /* check if job load acceptable */
+ if (this->init_limit_job_load)
+ {
+ u_int jobs = 0, i;
+
+ for (i = 0; i < JOB_PRIO_MAX; i++)
+ {
+ jobs += lib->processor->get_job_load(lib->processor, i);
+ }
+ if (jobs > this->init_limit_job_load)
+ {
+ DBG1(DBG_NET, "ignoring IKE_SA setup from %H, job load of %d "
+ "exceeds limit of %d", message->get_source(message),
+ jobs, this->init_limit_job_load);
+ return TRUE;
+ }
+ }
return FALSE;
}
@@ -314,39 +422,8 @@ static job_requeue_t receive_packets(private_receiver_t *this)
if (message->get_request(message) &&
message->get_exchange_type(message) == IKE_SA_INIT)
{
- /* check for cookies */
- if (this->cookie_threshold && cookie_required(this, message))
- {
- u_int32_t now = time_monotonic(NULL);
- chunk_t cookie = cookie_build(this, message, now - this->secret_offset,
- chunk_from_thing(this->secret));
-
- DBG2(DBG_NET, "received packet from: %#H to %#H",
- message->get_source(message),
- message->get_destination(message));
- DBG2(DBG_NET, "sending COOKIE notify to %H",
- message->get_source(message));
- send_notify(message, COOKIE, cookie);
- chunk_free(&cookie);
- if (++this->secret_used > COOKIE_REUSE)
- {
- /* create new cookie */
- DBG1(DBG_NET, "generating new cookie secret after %d uses",
- this->secret_used);
- memcpy(this->secret_old, this->secret, SECRET_LENGTH);
- this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret);
- this->secret_switch = now;
- this->secret_used = 0;
- }
- message->destroy(message);
- return JOB_REQUEUE_DIRECT;
- }
-
- /* check if peer has not too many IKE_SAs half open */
- if (this->block_threshold && peer_too_aggressive(this, message))
+ if (drop_ike_sa_init(this, message))
{
- DBG1(DBG_NET, "ignoring IKE_SA setup from %H, "
- "peer too aggressive", message->get_source(message));
message->destroy(message);
return JOB_REQUEUE_DIRECT;
}
@@ -408,6 +485,10 @@ receiver_t *receiver_create()
this->block_threshold = lib->settings->get_int(lib->settings,
"charon.block_threshold", BLOCK_THRESHOLD_DEFAULT);
}
+ this->init_limit_job_load = lib->settings->get_int(lib->settings,
+ "charon.init_limit_job_load", 0);
+ this->init_limit_half_open = lib->settings->get_int(lib->settings,
+ "charon.init_limit_half_open", 0);
this->receive_delay = lib->settings->get_int(lib->settings,
"charon.receive_delay", 0);
this->receive_delay_type = lib->settings->get_int(lib->settings,
@@ -435,8 +516,8 @@ receiver_t *receiver_create()
this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret);
memcpy(this->secret_old, this->secret, SECRET_LENGTH);
- this->job = callback_job_create((callback_job_cb_t)receive_packets,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive_packets,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
diff --git a/src/libcharon/network/receiver.h b/src/libcharon/network/receiver.h
index 690d8dbab..1d9d4871e 100644
--- a/src/libcharon/network/receiver.h
+++ b/src/libcharon/network/receiver.h
@@ -30,7 +30,7 @@ typedef struct receiver_t receiver_t;
/**
* Receives packets from the socket and adds them to the job queue.
*
- * The receiver starts a thread, wich reads on the blocking socket. A received
+ * The receiver starts a thread, which reads on the blocking socket. A received
* packet is preparsed and a process_message_job is queued in the job queue.
*
* To endure DoS attacks, cookies are enabled when to many IKE_SAs are half
@@ -38,7 +38,7 @@ typedef struct receiver_t receiver_t;
* method in RFC4306. We do not include a nonce, because we think the advantage
* we gain does not justify the overhead to parse the whole message.
* Instead of VersionIdOfSecret, we include a timestamp. This allows us to
- * find out wich key was used for cookie creation. Further, we can set a
+ * find out which key was used for cookie creation. Further, we can set a
* lifetime for the cookie, which allows us to reuse the secret for a longer
* time.
* COOKIE = time | sha1( IPi | SPIi | time | secret )
diff --git a/src/libcharon/network/sender.c b/src/libcharon/network/sender.c
index 4177fb3e1..4df930b15 100644
--- a/src/libcharon/network/sender.c
+++ b/src/libcharon/network/sender.c
@@ -183,8 +183,8 @@ sender_t * sender_create()
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.got = condvar_create(CONDVAR_TYPE_DEFAULT),
.sent = condvar_create(CONDVAR_TYPE_DEFAULT),
- .job = callback_job_create((callback_job_cb_t)send_packets,
- this, NULL, NULL),
+ .job = callback_job_create_with_prio((callback_job_cb_t)send_packets,
+ this, NULL, NULL, JOB_PRIO_CRITICAL),
.send_delay = lib->settings->get_int(lib->settings,
"charon.send_delay", 0),
.send_delay_type = lib->settings->get_int(lib->settings,
diff --git a/src/libcharon/network/socket.c b/src/libcharon/network/socket.c
new file mode 100644
index 000000000..cdb14b4a0
--- /dev/null
+++ b/src/libcharon/network/socket.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 "socket.h"
+
+#include <daemon.h>
+
+/**
+ * See header
+ */
+bool socket_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data)
+{
+ if (reg)
+ {
+ charon->socket->add_socket(charon->socket, (socket_constructor_t)data);
+ }
+ else
+ {
+ charon->socket->remove_socket(charon->socket,
+ (socket_constructor_t)data);
+ }
+ return TRUE;
+}
diff --git a/src/libcharon/network/socket.h b/src/libcharon/network/socket.h
index 51b26920f..be875035b 100644
--- a/src/libcharon/network/socket.h
+++ b/src/libcharon/network/socket.h
@@ -29,6 +29,7 @@ typedef struct socket_t socket_t;
#include <library.h>
#include <network/packet.h>
#include <utils/enumerator.h>
+#include <plugins/plugin.h>
/**
* Constructor prototype for sockets.
@@ -72,4 +73,18 @@ struct socket_t {
void (*destroy) (socket_t *this);
};
+/**
+ * Helper function to (un-)register socket interfaces from plugin features.
+ *
+ * This function is a plugin_feature_callback_t and can be used with the
+ * PLUGIN_CALLBACK macro to register an socket interface constructor.
+ *
+ * @param plugin plugin registering the socket interface
+ * @param feature associated plugin feature
+ * @param reg TRUE to register, FALSE to unregister
+ * @param data data passed to callback, a socket_constructor_t
+ */
+bool socket_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data);
+
#endif /** SOCKET_H_ @}*/
diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in
index 57aab1db7..3139e20b0 100644
--- a/src/libcharon/plugins/addrblock/Makefile.in
+++ b/src/libcharon/plugins/addrblock/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/android/Makefile.in b/src/libcharon/plugins/android/Makefile.in
index 08248da12..50e5f638e 100644
--- a/src/libcharon/plugins/android/Makefile.in
+++ b/src/libcharon/plugins/android/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/android/android_handler.c b/src/libcharon/plugins/android/android_handler.c
index ec3ff7a51..a53962f16 100644
--- a/src/libcharon/plugins/android/android_handler.c
+++ b/src/libcharon/plugins/android/android_handler.c
@@ -1,6 +1,6 @@
/*
+ * Copyright (C) 2010-2011 Tobias Brunner
* Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -36,9 +36,20 @@ struct private_android_handler_t {
* List of registered DNS servers
*/
linked_list_t *dns;
+
+ /**
+ * Whether the VPN frontend is used
+ */
+ bool frontend;
};
/**
+ * Prefixes to be used when installing DNS servers
+ */
+#define DNS_PREFIX_DEFAULT "net"
+#define DNS_PREFIX_FRONTEND "vpn"
+
+/**
* Struct to store a pair of old and installed DNS servers
*/
typedef struct {
@@ -70,12 +81,13 @@ bool filter_dns_pair(void *data, dns_pair_t **in, host_t **out)
/**
* Read DNS server property with a given index
*/
-host_t *get_dns_server(int index)
+host_t *get_dns_server(private_android_handler_t *this, int index)
{
host_t *dns = NULL;
- char key[10], value[PROPERTY_VALUE_MAX];
+ char key[10], value[PROPERTY_VALUE_MAX],
+ *prefix = this->frontend ? DNS_PREFIX_FRONTEND : DNS_PREFIX_DEFAULT;
- if (snprintf(key, sizeof(key), "vpn.dns%d", index) >= sizeof(key))
+ if (snprintf(key, sizeof(key), "%s.dns%d", prefix, index) >= sizeof(key))
{
return NULL;
}
@@ -90,11 +102,12 @@ host_t *get_dns_server(int index)
/**
* Set DNS server property with a given index
*/
-bool set_dns_server(int index, host_t *dns)
+bool set_dns_server(private_android_handler_t *this, int index, host_t *dns)
{
- char key[10], value[PROPERTY_VALUE_MAX];
+ char key[10], value[PROPERTY_VALUE_MAX],
+ *prefix = this->frontend ? DNS_PREFIX_FRONTEND : DNS_PREFIX_DEFAULT;
- if (snprintf(key, sizeof(key), "vpn.dns%d", index) >= sizeof(key))
+ if (snprintf(key, sizeof(key), "%s.dns%d", prefix, index) >= sizeof(key))
{
return FALSE;
}
@@ -136,8 +149,8 @@ METHOD(attribute_handler_t, handle, bool,
pair = malloc_thing(dns_pair_t);
pair->dns = dns;
index = this->dns->get_count(this->dns) + 1;
- pair->old = get_dns_server(index);
- set_dns_server(index, dns);
+ pair->old = get_dns_server(this, index);
+ set_dns_server(this, index, dns);
this->dns->insert_last(this->dns, pair);
return TRUE;
}
@@ -164,7 +177,7 @@ METHOD(attribute_handler_t, release, void,
if (chunk_equals(pair->dns->get_address(pair->dns), data))
{
this->dns->remove_at(this->dns, enumerator);
- set_dns_server(index, pair->old);
+ set_dns_server(this, index, pair->old);
destroy_dns_pair(pair);
}
}
@@ -204,7 +217,7 @@ METHOD(android_handler_t, destroy, void,
/**
* See header
*/
-android_handler_t *android_handler_create()
+android_handler_t *android_handler_create(bool frontend)
{
private_android_handler_t *this;
@@ -218,6 +231,7 @@ android_handler_t *android_handler_create()
.destroy = _destroy,
},
.dns = linked_list_create(),
+ .frontend = frontend,
);
return &this->public;
diff --git a/src/libcharon/plugins/android/android_handler.h b/src/libcharon/plugins/android/android_handler.h
index af620505b..0170958ee 100644
--- a/src/libcharon/plugins/android/android_handler.h
+++ b/src/libcharon/plugins/android/android_handler.h
@@ -1,6 +1,6 @@
/*
+ * Copyright (C) 2010-2011 Tobias Brunner
* Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -44,7 +44,9 @@ struct android_handler_t {
/**
* Create a android_handler instance.
+ *
+ * @param frontend TRUE if the VPN frontend is used
*/
-android_handler_t *android_handler_create();
+android_handler_t *android_handler_create(bool frontend);
#endif /** ANDROID_HANDLER_H_ @}*/
diff --git a/src/libcharon/plugins/android/android_logger.c b/src/libcharon/plugins/android/android_logger.c
index 43c56e656..f7624b2c7 100644
--- a/src/libcharon/plugins/android/android_logger.c
+++ b/src/libcharon/plugins/android/android_logger.c
@@ -47,18 +47,19 @@ METHOD(listener_t, log_, bool,
{
if (level <= this->level)
{
+ int prio = level > 1 ? ANDROID_LOG_DEBUG : ANDROID_LOG_INFO;
char sgroup[16], buffer[8192];
char *current = buffer, *next;
snprintf(sgroup, sizeof(sgroup), "%N", debug_names, group);
vsnprintf(buffer, sizeof(buffer), format, args);
while (current)
- { /* log each line seperately */
+ { /* log each line separately */
next = strchr(current, '\n');
if (next)
{
*(next++) = '\0';
}
- __android_log_print(ANDROID_LOG_INFO, "charon", "%.2d[%s] %s\n",
+ __android_log_print(prio, "charon", "%.2d[%s] %s\n",
thread, sgroup, current);
current = next;
}
diff --git a/src/libcharon/plugins/android/android_plugin.c b/src/libcharon/plugins/android/android_plugin.c
index 54a7017a1..091f34a8e 100644
--- a/src/libcharon/plugins/android/android_plugin.c
+++ b/src/libcharon/plugins/android/android_plugin.c
@@ -92,21 +92,16 @@ plugin_t *android_plugin_create()
},
},
.logger = android_logger_create(),
- .handler = android_handler_create(),
.creds = android_creds_create(),
);
+ this->service = android_service_create(this->creds);
+ this->handler = android_handler_create(this->service != NULL);
+
charon->bus->add_listener(charon->bus, &this->logger->listener);
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
- this->service = android_service_create(this->creds);
- if (!this->service)
- {
- destroy(this);
- return NULL;
- }
-
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/certexpire/Makefile.am b/src/libcharon/plugins/certexpire/Makefile.am
new file mode 100644
index 000000000..9aa0daad3
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/Makefile.am
@@ -0,0 +1,19 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = -rdynamic \
+ -DIPSEC_PIDDIR=\"${piddir}\"
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-certexpire.la
+else
+plugin_LTLIBRARIES = libstrongswan-certexpire.la
+endif
+
+libstrongswan_certexpire_la_SOURCES = certexpire_plugin.h certexpire_plugin.c \
+ certexpire_listener.h certexpire_listener.c \
+ certexpire_export.h certexpire_export.c \
+ certexpire_cron.h certexpire_cron.c
+
+libstrongswan_certexpire_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/certexpire/Makefile.in b/src/libcharon/plugins/certexpire/Makefile.in
new file mode 100644
index 000000000..929cce20c
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/Makefile.in
@@ -0,0 +1,621 @@
+# 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/certexpire
+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_certexpire_la_LIBADD =
+am_libstrongswan_certexpire_la_OBJECTS = certexpire_plugin.lo \
+ certexpire_listener.lo certexpire_export.lo certexpire_cron.lo
+libstrongswan_certexpire_la_OBJECTS = \
+ $(am_libstrongswan_certexpire_la_OBJECTS)
+libstrongswan_certexpire_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_certexpire_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_certexpire_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_certexpire_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_certexpire_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_certexpire_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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
+
+AM_CFLAGS = -rdynamic \
+ -DIPSEC_PIDDIR=\"${piddir}\"
+
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-certexpire.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-certexpire.la
+libstrongswan_certexpire_la_SOURCES = certexpire_plugin.h certexpire_plugin.c \
+ certexpire_listener.h certexpire_listener.c \
+ certexpire_export.h certexpire_export.c \
+ certexpire_cron.h certexpire_cron.c
+
+libstrongswan_certexpire_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/certexpire/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/certexpire/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-certexpire.la: $(libstrongswan_certexpire_la_OBJECTS) $(libstrongswan_certexpire_la_DEPENDENCIES)
+ $(libstrongswan_certexpire_la_LINK) $(am_libstrongswan_certexpire_la_rpath) $(libstrongswan_certexpire_la_OBJECTS) $(libstrongswan_certexpire_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certexpire_cron.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certexpire_export.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certexpire_listener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/certexpire_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/certexpire/certexpire_cron.c b/src/libcharon/plugins/certexpire/certexpire_cron.c
new file mode 100644
index 000000000..e8cd4bfd8
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/certexpire_cron.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 "certexpire_cron.h"
+
+#include <time.h>
+
+#include <debug.h>
+#include <processing/jobs/callback_job.h>
+
+typedef struct private_certexpire_cron_t private_certexpire_cron_t;
+
+/**
+ * Private data of an certexpire_cron_t object.
+ */
+struct private_certexpire_cron_t {
+
+ /**
+ * Public certexpire_cron_t interface.
+ */
+ certexpire_cron_t public;
+
+ /**
+ * time when to run export job
+ */
+ struct {
+ bool m[60];
+ bool h[24];
+ bool d[32];
+ bool my[13];
+ bool dw[8];
+ } cron;
+
+ /**
+ * Callback function to execute
+ */
+ certexpire_cron_job_t job;
+
+ /**
+ * Data to pass to callback
+ */
+ void *data;
+};
+
+/**
+ * Check if we should execute the export job
+ */
+static job_requeue_t check_cron(private_certexpire_cron_t *this)
+{
+ struct tm tm;
+ time_t t;
+
+ t = time(NULL);
+ localtime_r(&t, &tm);
+
+ /* recheck every minute at second 0 */
+ lib->scheduler->schedule_job(lib->scheduler,
+ (job_t*)callback_job_create_with_prio((callback_job_cb_t)check_cron,
+ this, NULL, NULL, JOB_PRIO_CRITICAL), 60 - tm.tm_sec);
+
+ /* skip this minute if we had a large negative time shift */
+ if (tm.tm_sec <= 30)
+ {
+ if (this->cron.m[tm.tm_min] &&
+ this->cron.h[tm.tm_hour] &&
+ this->cron.d[tm.tm_mday] &&
+ this->cron.my[tm.tm_mon + 1] &&
+ (this->cron.dw[tm.tm_wday] ||
+ (this->cron.dw[7] && tm.tm_wday == 0)))
+ {
+ this->job(this->data);
+ }
+ }
+ return JOB_REQUEUE_NONE;
+}
+
+/**
+ * Parse a cron range component into boolean fields
+ */
+static void parse_ranges(bool *fields, char *label, int mi, int ma, char *range)
+{
+ enumerator_t *enumerator;
+ int from, to, i;
+
+ if (streq(range, "*"))
+ {
+ for (i = mi; i <= ma; i++)
+ {
+ fields[i] = TRUE;
+ }
+ }
+ else
+ {
+ enumerator = enumerator_create_token(range, ",", "");
+ while (enumerator->enumerate(enumerator, &range))
+ {
+ switch (sscanf(range, "%d-%d", &from, &to))
+ {
+ case 1: /* single value */
+ if (from >= mi && from <= ma)
+ {
+ fields[from] = TRUE;
+ }
+ else
+ {
+ DBG1(DBG_CFG, "ignoring cron %s %d, out of range",
+ label, from);
+ }
+ break;
+ case 2: /* range */
+ if (from < mi)
+ {
+ DBG1(DBG_CFG, "cron %s out of range, shortening start "
+ "from %d to %d", label, from, mi);
+ from = mi;
+ }
+ if (to > ma)
+ {
+ DBG1(DBG_CFG, "cron %s out of range, shortening end "
+ "from %d to %d", label, to, ma);
+ to = ma;
+ }
+ for (i = from; i <= to; i++)
+ {
+ fields[i] = TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ DBG3(DBG_CFG, "cron job with enabled %ss:", label);
+ for (i = mi; i <= ma; i++)
+ {
+ if (fields[i])
+ {
+ DBG3(DBG_CFG, " %d", i);
+ }
+ }
+}
+
+/**
+ * Start cron processing, if configured
+ */
+static void start_cron(private_certexpire_cron_t *this, char *cron)
+{
+ enumerator_t *enumerator;
+ int i = 0;
+
+ enumerator = enumerator_create_token(cron, " ", " ");
+ for (i = 0; i < 5; i++)
+ {
+ if (!enumerator->enumerate(enumerator, &cron))
+ {
+ DBG1(DBG_CFG, "cron misses a field, using '*'");
+ cron = "*";
+ }
+ switch (i)
+ {
+ case 0:
+ parse_ranges(this->cron.m, "minute", 0, 59, cron);
+ break;
+ case 1:
+ parse_ranges(this->cron.h, "hour", 0, 23, cron);
+ break;
+ case 2:
+ parse_ranges(this->cron.d, "day", 1, 31, cron);
+ break;
+ case 3:
+ parse_ranges(this->cron.my, "month", 1, 12, cron);
+ break;
+ case 4:
+ parse_ranges(this->cron.dw, "weekday", 0, 7, cron);
+ break;
+ default:
+ break;
+ }
+ }
+ if (enumerator->enumerate(enumerator, &cron))
+ {
+ DBG1(DBG_CFG, "ignoring extra fields in cron");
+ }
+ enumerator->destroy(enumerator);
+
+ check_cron(this);
+}
+
+METHOD(certexpire_cron_t, destroy, void,
+ private_certexpire_cron_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+certexpire_cron_t *certexpire_cron_create(char *cron, certexpire_cron_job_t job,
+ void *data)
+{
+ private_certexpire_cron_t *this;
+
+ INIT(this,
+ .public = {
+ .destroy = _destroy,
+ },
+ .job = job,
+ .data = data,
+ );
+
+ start_cron(this, cron);
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/certexpire/certexpire_cron.h b/src/libcharon/plugins/certexpire/certexpire_cron.h
new file mode 100644
index 000000000..0d6623d7f
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/certexpire_cron.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 certexpire_cron certexpire_cron
+ * @{ @ingroup certexpire
+ */
+
+#ifndef CERTEXPIRE_CRON_H_
+#define CERTEXPIRE_CRON_H_
+
+typedef struct certexpire_cron_t certexpire_cron_t;
+
+/**
+ * Callback function invoked by cron.
+ *
+ * @param data user specified callback data
+ */
+typedef void (*certexpire_cron_job_t)(void *data);
+
+/**
+ * Cron style job scheduling.
+ */
+struct certexpire_cron_t {
+
+ /**
+ * Destroy a certexpire_cron_t.
+ *
+ * It currently is not possible to savely cancel a cron job. Make sure
+ * any scheduled jobs have been canceled before cleaning up.
+ */
+ void (*destroy)(certexpire_cron_t *this);
+};
+
+/**
+ * Create a certexpire_cron instance.
+ *
+ * The cron string takes numeric arguments only, but supports ranges (1-5)
+ * and selections (1,3,5), or a combination, space separated:
+ * minute hour day month weekday
+ * minute, 0-59
+ * hour, 0-23
+ * day, 1-31
+ * month, 1-12
+ * weekday, 0-7 (0 == 7 == sunday)
+ * man crontab(5) for details.
+ *
+ * @param cron cron style scheduling string
+ * @param job callback function to invoke
+ * @param data user data to pass to job
+ */
+certexpire_cron_t *certexpire_cron_create(char *cron, certexpire_cron_job_t job,
+ void *data);
+
+#endif /** CERTEXPIRE_CRON_H_ @}*/
diff --git a/src/libcharon/plugins/certexpire/certexpire_export.c b/src/libcharon/plugins/certexpire/certexpire_export.c
new file mode 100644
index 000000000..c73b0beda
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/certexpire_export.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 "certexpire_export.h"
+
+#include "certexpire_cron.h"
+
+#include <time.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <debug.h>
+#include <utils/hashtable.h>
+#include <threading/mutex.h>
+#include <credentials/certificates/x509.h>
+
+typedef struct private_certexpire_export_t private_certexpire_export_t;
+
+/**
+ * Private data of an certexpire_export_t object.
+ */
+struct private_certexpire_export_t {
+
+ /**
+ * Public certexpire_export_t interface.
+ */
+ certexpire_export_t public;
+
+ /**
+ * hashtable caching local trustchains, mapping entry_t => entry_t
+ */
+ hashtable_t *local;
+
+ /**
+ * hashtable caching remote trustchains, mapping entry_t => entry_t
+ */
+ hashtable_t *remote;
+
+ /**
+ * Mutex to lock hashtables
+ */
+ mutex_t *mutex;
+
+ /**
+ * Cronjob for export
+ */
+ certexpire_cron_t *cron;
+
+ /**
+ * strftime() format to generate local CSV file
+ */
+ char *local_path;
+
+ /**
+ * strftime() format to generate remote CSV file
+ */
+ char *remote_path;
+
+ /**
+ * stftime() format of the exported expiration date
+ */
+ char *format;
+
+ /**
+ * CSV field separator
+ */
+ char *separator;
+
+ /**
+ * TRUE to use fixed field count, CA at end
+ */
+ bool fixed_fields;
+
+ /**
+ * String to use in empty fields, if using fixed_fields
+ */
+ char *empty_string;
+};
+
+/**
+ * Maximum number of expiration dates we store (for subject + IM CAs + CA)
+ */
+#define MAX_TRUSTCHAIN_LENGTH 7
+
+/**
+ * Hashtable entry
+ */
+typedef struct {
+ /** certificate subject as subjectAltName or CN of a DN */
+ char id[128];
+ /** list of expiration dates, 0 if no certificate */
+ time_t expire[MAX_TRUSTCHAIN_LENGTH];
+} entry_t;
+
+/**
+ * Hashtable hash function
+ */
+static u_int hash(entry_t *key)
+{
+ return chunk_hash(chunk_create(key->id, strlen(key->id)));
+}
+
+/**
+ * Hashtable equals function
+ */
+static bool equals(entry_t *a, entry_t *b)
+{
+ return streq(a->id, b->id);
+}
+
+/**
+ * Export a single trustchain to a path
+ */
+static void export_csv(private_certexpire_export_t *this, char *path,
+ hashtable_t *chains)
+{
+ enumerator_t *enumerator;
+ char buf[PATH_MAX];
+ entry_t *entry;
+ FILE *file;
+ struct tm tm;
+ time_t t;
+ int i;
+
+ t = time(NULL);
+ localtime_r(&t, &tm);
+
+ strftime(buf, sizeof(buf), path, &tm);
+ file = fopen(buf, "a");
+ if (file)
+ {
+ DBG1(DBG_CFG, "exporting expiration dates of %d trustchain%s to '%s'",
+ chains->get_count(chains),
+ chains->get_count(chains) == 1 ? "" : "s", buf);
+ this->mutex->lock(this->mutex);
+ enumerator = chains->create_enumerator(chains);
+ while (enumerator->enumerate(enumerator, NULL, &entry))
+ {
+ fprintf(file, "%s%s", entry->id, this->separator);
+ for (i = 0; i < MAX_TRUSTCHAIN_LENGTH; i++)
+ {
+ if (entry->expire[i])
+ {
+ localtime_r(&entry->expire[i], &tm);
+ strftime(buf, sizeof(buf), this->format, &tm);
+ fprintf(file, "%s", buf);
+ }
+ if (i == MAX_TRUSTCHAIN_LENGTH - 1)
+ {
+ fprintf(file, "\n");
+ }
+ else if (entry->expire[i])
+ {
+ fprintf(file, "%s", this->separator);
+ }
+ else if (this->fixed_fields)
+ {
+ fprintf(file, "%s%s", this->empty_string, this->separator);
+ }
+ }
+ chains->remove_at(chains, enumerator);
+ free(entry);
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ fclose(file);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "opening CSV file '%s' failed: %s", buf, strerror(errno));
+ }
+}
+
+/**
+ * Export cached trustchain expiration dates to CSV files
+ */
+static void cron_export(private_certexpire_export_t *this)
+{
+ if (this->local_path)
+ {
+ export_csv(this, this->local_path, this->local);
+ }
+ if (this->remote_path)
+ {
+ export_csv(this, this->remote_path, this->remote);
+ }
+}
+
+METHOD(certexpire_export_t, add, void,
+ private_certexpire_export_t *this, linked_list_t *trustchain, bool local)
+{
+ enumerator_t *enumerator;
+ certificate_t *cert;
+ int count;
+
+ /* don't store expiration dates if no path configured */
+ if (local)
+ {
+ if (!this->local_path)
+ {
+ return;
+ }
+ }
+ else
+ {
+ if (!this->remote_path)
+ {
+ return;
+ }
+ }
+
+ count = min(trustchain->get_count(trustchain), MAX_TRUSTCHAIN_LENGTH) - 1;
+
+ enumerator = trustchain->create_enumerator(trustchain);
+ /* get subject cert */
+ if (enumerator->enumerate(enumerator, &cert))
+ {
+ identification_t *id;
+ entry_t *entry;
+ int i;
+
+ INIT(entry);
+
+ /* prefer FQDN subjectAltName... */
+ if (cert->get_type(cert) == CERT_X509)
+ {
+ x509_t *x509 = (x509_t*)cert;
+ enumerator_t *sans;
+
+ sans = x509->create_subjectAltName_enumerator(x509);
+ while (sans->enumerate(sans, &id))
+ {
+ if (id->get_type(id) == ID_FQDN)
+ {
+ snprintf(entry->id, sizeof(entry->id), "%Y", id);
+ break;
+ }
+ }
+ sans->destroy(sans);
+ }
+ /* fallback to CN of DN */
+ if (!entry->id[0])
+ {
+ enumerator_t *parts;
+ id_part_t part;
+ chunk_t data;
+
+ id = cert->get_subject(cert);
+ parts = id->create_part_enumerator(id);
+ while (parts->enumerate(parts, &part, &data))
+ {
+ if (part == ID_PART_RDN_CN)
+ {
+ snprintf(entry->id, sizeof(entry->id), "%.*s",
+ (int)data.len, data.ptr);
+ break;
+ }
+ }
+ parts->destroy(parts);
+ }
+ /* no usable identity? skip */
+ if (!entry->id[0])
+ {
+ enumerator->destroy(enumerator);
+ free(entry);
+ return;
+ }
+
+ /* get intermediate CA expiration dates */
+ cert->get_validity(cert, NULL, NULL, &entry->expire[0]);
+ for (i = 1; i < count && enumerator->enumerate(enumerator, &cert); i++)
+ {
+ cert->get_validity(cert, NULL, NULL, &entry->expire[i]);
+ }
+ /* get CA expiration date, as last array entry */
+ if (enumerator->enumerate(enumerator, &cert))
+ {
+ cert->get_validity(cert, NULL, NULL,
+ &entry->expire[MAX_TRUSTCHAIN_LENGTH - 1]);
+ }
+ this->mutex->lock(this->mutex);
+ if (local)
+ {
+ entry = this->local->put(this->local, entry, entry);
+ }
+ else
+ {
+ entry = this->remote->put(this->remote, entry, entry);
+ }
+ this->mutex->unlock(this->mutex);
+ if (entry)
+ {
+ free(entry);
+ }
+ if (!this->cron)
+ { /* export directly if no cron job defined */
+ if (local)
+ {
+ export_csv(this, this->local_path, this->local);
+ }
+ else
+ {
+ export_csv(this, this->remote_path, this->remote);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(certexpire_export_t, destroy, void,
+ private_certexpire_export_t *this)
+{
+ entry_t *key, *value;
+ enumerator_t *enumerator;
+
+ enumerator = this->local->create_enumerator(this->local);
+ while (enumerator->enumerate(enumerator, &key, &value))
+ {
+ free(value);
+ }
+ enumerator->destroy(enumerator);
+ enumerator = this->remote->create_enumerator(this->remote);
+ while (enumerator->enumerate(enumerator, &key, &value))
+ {
+ free(value);
+ }
+ enumerator->destroy(enumerator);
+
+ this->local->destroy(this->local);
+ this->remote->destroy(this->remote);
+ DESTROY_IF(this->cron);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/**
+ * See header
+ */
+certexpire_export_t *certexpire_export_create()
+{
+ private_certexpire_export_t *this;
+ char *cron;
+
+ INIT(this,
+ .public = {
+ .add = _add,
+ .destroy = _destroy,
+ },
+ .local = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 4),
+ .remote = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 32),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .local_path = lib->settings->get_str(lib->settings,
+ "charon.plugins.certexpire.csv.local", NULL),
+ .remote_path = lib->settings->get_str(lib->settings,
+ "charon.plugins.certexpire.csv.remote", NULL),
+ .separator = lib->settings->get_str(lib->settings,
+ "charon.plugins.certexpire.csv.separator", ","),
+ .format = lib->settings->get_str(lib->settings,
+ "charon.plugins.certexpire.csv.format", "%d:%m:%Y"),
+ .fixed_fields = lib->settings->get_bool(lib->settings,
+ "charon.plugins.certexpire.csv.fixed_fields", TRUE),
+ .empty_string = lib->settings->get_str(lib->settings,
+ "charon.plugins.certexpire.csv.empty_string", ""),
+ );
+
+ cron = lib->settings->get_str(lib->settings,
+ "charon.plugins.certexpire.csv.cron", NULL);
+ if (cron)
+ {
+ this->cron = certexpire_cron_create(cron,
+ (certexpire_cron_job_t)cron_export, this);
+ }
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/certexpire/certexpire_export.h b/src/libcharon/plugins/certexpire/certexpire_export.h
new file mode 100644
index 000000000..64281d0bd
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/certexpire_export.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 certexpire_export certexpire_export
+ * @{ @ingroup certexpire
+ */
+
+#ifndef CERTEXPIRE_EXPORT_H_
+#define CERTEXPIRE_EXPORT_H_
+
+typedef struct certexpire_export_t certexpire_export_t;
+
+#include <utils/linked_list.h>
+
+/**
+ * Caches and exports trustchain information to CSV files.
+ */
+struct certexpire_export_t {
+
+ /**
+ * Add trustchain to cache for export.
+ *
+ * @param trustchain trustchain, sorted list of certificate_t
+ * @param local TRUE for own chain, FALSE for remote chain
+ */
+ void (*add)(certexpire_export_t *this, linked_list_t *trustchain, bool local);
+
+ /**
+ * Destroy a certexpire_export_t.
+ */
+ void (*destroy)(certexpire_export_t *this);
+};
+
+/**
+ * Create a certexpire_export instance.
+ */
+certexpire_export_t *certexpire_export_create();
+
+#endif /** CERTEXPIRE_EXPORT_H_ @}*/
diff --git a/src/libcharon/plugins/certexpire/certexpire_listener.c b/src/libcharon/plugins/certexpire/certexpire_listener.c
new file mode 100644
index 000000000..4c9c6ff3b
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/certexpire_listener.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 "certexpire_listener.h"
+
+#include <daemon.h>
+
+typedef struct private_certexpire_listener_t private_certexpire_listener_t;
+
+/**
+ * Private data of an certexpire_listener_t object.
+ */
+struct private_certexpire_listener_t {
+
+ /**
+ * Public certexpire_listener_t interface.
+ */
+ certexpire_listener_t public;
+
+ /**
+ * Export facility
+ */
+ certexpire_export_t *export;
+};
+
+METHOD(listener_t, authorize, bool,
+ private_certexpire_listener_t *this, ike_sa_t *ike_sa,
+ bool final, bool *success)
+{
+ enumerator_t *rounds, *enumerator;
+ certificate_t *cert, *ca = NULL;
+ linked_list_t *trustchain;
+ auth_cfg_t *auth;
+ auth_rule_t rule;
+
+ /* Check all rounds in final hook, as local authentication data are
+ * not completely available after round-invocation. */
+ if (!final)
+ {
+ return TRUE;
+ }
+
+ /* collect local certificates */
+ trustchain = linked_list_create();
+ rounds = ike_sa->create_auth_cfg_enumerator(ike_sa, TRUE);
+ while (rounds->enumerate(rounds, &auth))
+ {
+ cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+ if (cert)
+ {
+ trustchain->insert_last(trustchain, cert);
+
+ enumerator = auth->create_enumerator(auth);
+ while (enumerator->enumerate(enumerator, &rule, &cert))
+ {
+ if (rule == AUTH_RULE_IM_CERT)
+ {
+ trustchain->insert_last(trustchain, cert);
+ }
+ if (rule == AUTH_RULE_CA_CERT)
+ {
+ /* the last CA cert is the one used in the trustchain.
+ * Previous CA certificates have been received as cert
+ * requests. */
+ ca = cert;
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (ca)
+ {
+ trustchain->insert_last(trustchain, ca);
+ }
+ }
+ }
+ rounds->destroy(rounds);
+ this->export->add(this->export, trustchain, TRUE);
+ trustchain->destroy(trustchain);
+
+ /* collect remote certificates */
+ trustchain = linked_list_create();
+ rounds = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE);
+ while (rounds->enumerate(rounds, &auth))
+ {
+ cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+ if (cert)
+ {
+ trustchain->insert_last(trustchain, cert);
+
+ enumerator = auth->create_enumerator(auth);
+ while (enumerator->enumerate(enumerator, &rule, &cert))
+ {
+ if (rule == AUTH_RULE_IM_CERT)
+ {
+ trustchain->insert_last(trustchain, cert);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ cert = auth->get(auth, AUTH_RULE_CA_CERT);
+ if (cert)
+ {
+ trustchain->insert_last(trustchain, cert);
+ }
+ }
+ }
+ rounds->destroy(rounds);
+ this->export->add(this->export, trustchain, FALSE);
+ trustchain->destroy(trustchain);
+ return TRUE;
+}
+
+METHOD(certexpire_listener_t, destroy, void,
+ private_certexpire_listener_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+certexpire_listener_t *certexpire_listener_create(certexpire_export_t *export)
+{
+ private_certexpire_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .authorize = _authorize,
+ },
+ .destroy = _destroy,
+ },
+ .export = export,
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/certexpire/certexpire_listener.h b/src/libcharon/plugins/certexpire/certexpire_listener.h
new file mode 100644
index 000000000..8601ff585
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/certexpire_listener.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 certexpire_listener certexpire_listener
+ * @{ @ingroup certexpire
+ */
+
+#ifndef CERTEXPIRE_LISTENER_H_
+#define CERTEXPIRE_LISTENER_H_
+
+#include <bus/listeners/listener.h>
+
+#include "certexpire_export.h"
+
+typedef struct certexpire_listener_t certexpire_listener_t;
+
+/**
+ * Listener collecting certificate expire information after authentication.
+ */
+struct certexpire_listener_t {
+
+ /**
+ * Implements listener_t interface.
+ */
+ listener_t listener;
+
+ /**
+ * Destroy a certexpire_listener_t.
+ */
+ void (*destroy)(certexpire_listener_t *this);
+};
+
+/**
+ * Create a certexpire_listener instance.
+ *
+ * @param export facility exporting collected trustchains
+ * @return listener instance
+ */
+certexpire_listener_t *certexpire_listener_create(certexpire_export_t *export);
+
+#endif /** CERTEXPIRE_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/certexpire/certexpire_plugin.c b/src/libcharon/plugins/certexpire/certexpire_plugin.c
new file mode 100644
index 000000000..2b4c0b68b
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/certexpire_plugin.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 "certexpire_plugin.h"
+
+#include "certexpire_listener.h"
+#include "certexpire_export.h"
+
+#include <daemon.h>
+
+typedef struct private_certexpire_plugin_t private_certexpire_plugin_t;
+
+/**
+ * Private data of certexpire plugin
+ */
+struct private_certexpire_plugin_t {
+
+ /**
+ * Implements plugin interface
+ */
+ certexpire_plugin_t public;
+
+ /**
+ * Listener collecting expire information
+ */
+ certexpire_listener_t *listener;
+
+ /**
+ * Cache and export trustchain expire information
+ */
+ certexpire_export_t *export;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_certexpire_plugin_t *this)
+{
+ return "certexpire";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_certexpire_plugin_t *this)
+{
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ this->listener->destroy(this->listener);
+ this->export->destroy(this->export);
+ free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *certexpire_plugin_create()
+{
+ private_certexpire_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .export = certexpire_export_create(),
+ );
+ this->listener = certexpire_listener_create(this->export),
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/certexpire/certexpire_plugin.h b/src/libcharon/plugins/certexpire/certexpire_plugin.h
new file mode 100644
index 000000000..bcb5606f5
--- /dev/null
+++ b/src/libcharon/plugins/certexpire/certexpire_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 certexpire certexpire
+ * @ingroup cplugins
+ *
+ * @defgroup certexpire_plugin certexpire_plugin
+ * @{ @ingroup certexpire
+ */
+
+#ifndef CERTEXPIRE_PLUGIN_H_
+#define CERTEXPIRE_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct certexpire_plugin_t certexpire_plugin_t;
+
+/**
+ * Plugin exporting expiration dates of used certificates to CSV files.
+ */
+struct certexpire_plugin_t {
+
+ /**
+ * Implements plugin interface.
+ */
+ plugin_t plugin;
+};
+
+#endif /** CERTEXPIRE_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/coupling/Makefile.in b/src/libcharon/plugins/coupling/Makefile.in
index a3104e4c0..df4420b04 100644
--- a/src/libcharon/plugins/coupling/Makefile.in
+++ b/src/libcharon/plugins/coupling/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in
index 7853659df..089afd39d 100644
--- a/src/libcharon/plugins/dhcp/Makefile.in
+++ b/src/libcharon/plugins/dhcp/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c
index c98d50554..5d98e5b8d 100644
--- a/src/libcharon/plugins/dhcp/dhcp_socket.c
+++ b/src/libcharon/plugins/dhcp/dhcp_socket.c
@@ -760,8 +760,8 @@ dhcp_socket_t *dhcp_socket_create()
return NULL;
}
- this->job = callback_job_create((callback_job_cb_t)receive_dhcp,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive_dhcp,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
diff --git a/src/libcharon/plugins/duplicheck/Makefile.in b/src/libcharon/plugins/duplicheck/Makefile.in
index 8cffa2f10..87984a182 100644
--- a/src/libcharon/plugins/duplicheck/Makefile.in
+++ b/src/libcharon/plugins/duplicheck/Makefile.in
@@ -202,6 +202,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -210,6 +213,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -226,11 +230,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -274,6 +280,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/duplicheck/duplicheck_notify.c b/src/libcharon/plugins/duplicheck/duplicheck_notify.c
index 4e7618235..b86f1ef3d 100644
--- a/src/libcharon/plugins/duplicheck/duplicheck_notify.c
+++ b/src/libcharon/plugins/duplicheck/duplicheck_notify.c
@@ -203,8 +203,8 @@ duplicheck_notify_t *duplicheck_notify_create()
destroy(this);
return NULL;
}
- this->job = callback_job_create((callback_job_cb_t)receive,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
diff --git a/src/libcharon/plugins/duplicheck/duplicheck_plugin.c b/src/libcharon/plugins/duplicheck/duplicheck_plugin.c
index 5bc1a14af..df28e7f12 100644
--- a/src/libcharon/plugins/duplicheck/duplicheck_plugin.c
+++ b/src/libcharon/plugins/duplicheck/duplicheck_plugin.c
@@ -66,7 +66,7 @@ plugin_t *duplicheck_plugin_create()
private_duplicheck_plugin_t *this;
if (!lib->settings->get_bool(lib->settings,
- "charon.plugins.duplicheck.enabled", TRUE))
+ "charon.plugins.duplicheck.enable", TRUE))
{
return NULL;
}
diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in
index 666e22957..e7a3d780a 100644
--- a/src/libcharon/plugins/eap_aka/Makefile.in
+++ b/src/libcharon/plugins/eap_aka/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/eap_aka/eap_aka_peer.c b/src/libcharon/plugins/eap_aka/eap_aka_peer.c
index df0c4c5b4..8c392405e 100644
--- a/src/libcharon/plugins/eap_aka/eap_aka_peer.c
+++ b/src/libcharon/plugins/eap_aka/eap_aka_peer.c
@@ -20,6 +20,7 @@
#include <simaka_message.h>
#include <simaka_crypto.h>
+#include <simaka_manager.h>
typedef struct private_eap_aka_peer_t private_eap_aka_peer_t;
@@ -34,6 +35,11 @@ struct private_eap_aka_peer_t {
eap_aka_peer_t public;
/**
+ * AKA backend manager
+ */
+ simaka_manager_t *mgr;
+
+ /**
* EAP-AKA crypto helper
*/
simaka_crypto_t *crypto;
@@ -91,7 +97,7 @@ static eap_payload_t* create_client_error(private_eap_aka_peer_t *this)
encoded = htons(AKA_UNABLE_TO_PROCESS);
message->add_attribute(message, AT_CLIENT_ERROR_CODE,
chunk_create((char*)&encoded, sizeof(encoded)));
- out = message->generate(message, chunk_empty);
+ out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
return out;
}
@@ -140,7 +146,7 @@ static status_t process_identity(private_eap_aka_peer_t *this,
switch (id_req)
{
case AT_ANY_ID_REQ:
- this->reauth = charon->sim->card_get_reauth(charon->sim,
+ this->reauth = this->mgr->card_get_reauth(this->mgr,
this->permanent, this->mk, &this->counter);
if (this->reauth)
{
@@ -149,8 +155,8 @@ static status_t process_identity(private_eap_aka_peer_t *this,
}
/* FALL */
case AT_FULLAUTH_ID_REQ:
- this->pseudonym = charon->sim->card_get_pseudonym(charon->sim,
- this->permanent);
+ this->pseudonym = this->mgr->card_get_pseudonym(this->mgr,
+ this->permanent);
if (this->pseudonym)
{
id = this->pseudonym->get_encoding(this->pseudonym);
@@ -169,7 +175,7 @@ static status_t process_identity(private_eap_aka_peer_t *this,
{
message->add_attribute(message, AT_IDENTITY, id);
}
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
return NEED_MORE;
@@ -220,10 +226,10 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
return NEED_MORE;
}
- status = charon->sim->card_get_quintuplet(charon->sim, this->permanent,
+ status = this->mgr->card_get_quintuplet(this->mgr, this->permanent,
rand.ptr, autn.ptr, ck, ik, res, &res_len);
if (status == INVALID_STATE &&
- charon->sim->card_resync(charon->sim, this->permanent, rand.ptr, auts))
+ this->mgr->card_resync(this->mgr, this->permanent, rand.ptr, auts))
{
DBG1(DBG_IKE, "received SQN invalid, sending %N",
simaka_subtype_names, AKA_SYNCHRONIZATION_FAILURE);
@@ -231,7 +237,8 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
AKA_SYNCHRONIZATION_FAILURE, this->crypto);
message->add_attribute(message, AT_AUTS,
chunk_create(auts, AKA_AUTS_LEN));
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message,
+ chunk_empty));
message->destroy(message);
return NEED_MORE;
}
@@ -241,7 +248,8 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
this->permanent, simaka_subtype_names, AKA_AUTHENTICATION_REJECT);
message = simaka_message_create(FALSE, in->get_identifier(in), EAP_AKA,
AKA_AUTHENTICATION_REJECT, this->crypto);
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message,
+ chunk_empty));
message->destroy(message);
return NEED_MORE;
}
@@ -274,13 +282,13 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
case AT_NEXT_REAUTH_ID:
this->counter = 0;
id = identification_create_from_data(data);
- charon->sim->card_set_reauth(charon->sim, this->permanent, id,
- this->mk, this->counter);
+ this->mgr->card_set_reauth(this->mgr, this->permanent, id,
+ this->mk, this->counter);
id->destroy(id);
break;
case AT_NEXT_PSEUDONYM:
id = identification_create_from_data(data);
- charon->sim->card_set_pseudonym(charon->sim, this->permanent, id);
+ this->mgr->card_set_pseudonym(this->mgr, this->permanent, id);
id->destroy(id);
break;
default:
@@ -292,7 +300,7 @@ static status_t process_challenge(private_eap_aka_peer_t *this,
message = simaka_message_create(FALSE, this->identifier, EAP_AKA,
AKA_CHALLENGE, this->crypto);
message->add_attribute(message, AT_RES, chunk_create(res, res_len));
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
return NEED_MORE;
}
@@ -389,13 +397,13 @@ static status_t process_reauthentication(private_eap_aka_peer_t *this,
identification_t *reauth;
reauth = identification_create_from_data(data);
- charon->sim->card_set_reauth(charon->sim, this->permanent, reauth,
- this->mk, this->counter);
+ this->mgr->card_set_reauth(this->mgr, this->permanent, reauth,
+ this->mk, this->counter);
reauth->destroy(reauth);
}
}
message->add_attribute(message, AT_COUNTER, counter);
- *out = message->generate(message, nonce);
+ *out = eap_payload_create_data_own(message->generate(message, nonce));
message->destroy(message);
return NEED_MORE;
}
@@ -446,7 +454,8 @@ static status_t process_notification(private_eap_aka_peer_t *this,
{ /* empty notification reply */
message = simaka_message_create(FALSE, this->identifier, EAP_AKA,
AKA_NOTIFICATION, this->crypto);
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message,
+ chunk_empty));
message->destroy(message);
}
else
@@ -466,7 +475,7 @@ METHOD(eap_method_t, process, status_t,
/* store received EAP message identifier */
this->identifier = in->get_identifier(in);
- message = simaka_message_create_from_payload(in, this->crypto);
+ message = simaka_message_create_from_payload(in->get_data(in), this->crypto);
if (!message)
{
*out = create_client_error(this);
@@ -578,7 +587,8 @@ eap_aka_peer_t *eap_aka_peer_create(identification_t *server,
.destroy = _destroy,
},
},
- .crypto = simaka_crypto_create(),
+ .crypto = simaka_crypto_create(EAP_AKA),
+ .mgr = lib->get(lib, "aka-manager"),
);
if (!this->crypto)
diff --git a/src/libcharon/plugins/eap_aka/eap_aka_peer.h b/src/libcharon/plugins/eap_aka/eap_aka_peer.h
index 65a210406..974ba2721 100644
--- a/src/libcharon/plugins/eap_aka/eap_aka_peer.h
+++ b/src/libcharon/plugins/eap_aka/eap_aka_peer.h
@@ -26,7 +26,7 @@ typedef struct eap_aka_peer_t eap_aka_peer_t;
#include <sa/authenticators/eap/eap_method.h>
/**
- * Implementation of the eap_method_t interface using EAP-AKA as a client.
+ * EAP-AKA peer implementation.
*/
struct eap_aka_peer_t {
diff --git a/src/libcharon/plugins/eap_aka/eap_aka_plugin.c b/src/libcharon/plugins/eap_aka/eap_aka_plugin.c
index 394a14b59..83805d727 100644
--- a/src/libcharon/plugins/eap_aka/eap_aka_plugin.c
+++ b/src/libcharon/plugins/eap_aka/eap_aka_plugin.c
@@ -19,20 +19,61 @@
#include "eap_aka_server.h"
#include <daemon.h>
+#include <simaka_manager.h>
+
+typedef struct private_eap_aka_plugin_t private_eap_aka_plugin_t;
+
+/**
+ * Private data of an eap_sim_plugin_t object.
+ */
+struct private_eap_aka_plugin_t {
+
+ /**
+ * Public interface.
+ */
+ eap_aka_plugin_t public;
+
+ /**
+ * EAP-AKA backend manager
+ */
+ simaka_manager_t *mgr;
+};
METHOD(plugin_t, get_name, char*,
- eap_aka_plugin_t *this)
+ private_eap_aka_plugin_t *this)
{
return "eap-aka";
}
+METHOD(plugin_t, get_features, int,
+ private_eap_aka_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_PROVIDE(CUSTOM, "aka-manager"),
+ PLUGIN_CALLBACK(eap_method_register, eap_aka_server_create),
+ PLUGIN_PROVIDE(EAP_SERVER, EAP_AKA),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(PRF, PRF_FIPS_SHA1_160),
+ PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA1_128),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_CALLBACK(eap_method_register, eap_aka_peer_create),
+ PLUGIN_PROVIDE(EAP_PEER, EAP_AKA),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(PRF, PRF_FIPS_SHA1_160),
+ PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA1_128),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
- eap_aka_plugin_t *this)
+ private_eap_aka_plugin_t *this)
{
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_aka_server_create);
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_aka_peer_create);
+ lib->set(lib, "aka-manager", NULL);
+ this->mgr->destroy(this->mgr);
free(this);
}
@@ -41,21 +82,19 @@ METHOD(plugin_t, destroy, void,
*/
plugin_t *eap_aka_plugin_create()
{
- eap_aka_plugin_t *this;
+ private_eap_aka_plugin_t *this;
INIT(this,
- .plugin = {
- .get_name = _get_name,
- .reload = (void*)return_false,
- .destroy = _destroy,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
},
+ .mgr = simaka_manager_create(),
);
+ lib->set(lib, "aka-manager", this->mgr);
- charon->eap->add_method(charon->eap, EAP_AKA, 0, EAP_SERVER,
- (eap_constructor_t)eap_aka_server_create);
- charon->eap->add_method(charon->eap, EAP_AKA, 0, EAP_PEER,
- (eap_constructor_t)eap_aka_peer_create);
-
- return &this->plugin;
+ return &this->public.plugin;
}
-
diff --git a/src/libcharon/plugins/eap_aka/eap_aka_plugin.h b/src/libcharon/plugins/eap_aka/eap_aka_plugin.h
index d011904b3..8d4fbadfa 100644
--- a/src/libcharon/plugins/eap_aka/eap_aka_plugin.h
+++ b/src/libcharon/plugins/eap_aka/eap_aka_plugin.h
@@ -33,6 +33,11 @@ typedef struct eap_aka_plugin_t eap_aka_plugin_t;
*
* EAP-AKA uses 3rd generation mobile phone standard authentication
* mechanism for authentication, as defined RFC4187.
+ *
+ * This plugin implements the protocol level of EAP-AKA and uses simaka_card_t
+ * and simaka_provider_t backends to provide triplets. It registers a
+ * simaka_manager_t on the library as "aka-manager", other plugins can use it
+ * to provide the required backends.
*/
struct eap_aka_plugin_t {
diff --git a/src/libcharon/plugins/eap_aka/eap_aka_server.c b/src/libcharon/plugins/eap_aka/eap_aka_server.c
index bf0020ad8..d8e85ceef 100644
--- a/src/libcharon/plugins/eap_aka/eap_aka_server.c
+++ b/src/libcharon/plugins/eap_aka/eap_aka_server.c
@@ -20,6 +20,7 @@
#include <simaka_message.h>
#include <simaka_crypto.h>
+#include <simaka_manager.h>
/** length of the AT_NONCE_S value */
#define NONCE_LEN 16
@@ -37,6 +38,11 @@ struct private_eap_aka_server_t {
eap_aka_server_t public;
/**
+ * AKA backend manager
+ */
+ simaka_manager_t *mgr;
+
+ /**
* EAP-AKA crypto helper
*/
simaka_crypto_t *crypto;
@@ -133,7 +139,7 @@ static status_t identity(private_eap_aka_server_t *this, eap_payload_t **out)
{
message->add_attribute(message, AT_PERMANENT_ID_REQ, chunk_empty);
}
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
this->pending = AKA_IDENTITY;
@@ -152,7 +158,7 @@ static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out)
chunk_t data, mk;
identification_t *id;
- if (!charon->sim->provider_get_quintuplet(charon->sim, this->permanent,
+ if (!this->mgr->provider_get_quintuplet(this->mgr, this->permanent,
rand, xres, &xres_len, ck, ik, autn))
{
if (this->use_pseudonym)
@@ -183,24 +189,21 @@ static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out)
AKA_CHALLENGE, this->crypto);
message->add_attribute(message, AT_RAND, this->rand);
message->add_attribute(message, AT_AUTN, chunk_create(autn, AKA_AUTN_LEN));
- id = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk.ptr);
+ id = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk.ptr);
if (id)
{
message->add_attribute(message, AT_NEXT_REAUTH_ID,
id->get_encoding(id));
id->destroy(id);
}
- else
+ id = this->mgr->provider_gen_pseudonym(this->mgr, this->permanent);
+ if (id)
{
- id = charon->sim->provider_gen_pseudonym(charon->sim, this->permanent);
- if (id)
- {
- message->add_attribute(message, AT_NEXT_PSEUDONYM,
- id->get_encoding(id));
- id->destroy(id);
- }
+ message->add_attribute(message, AT_NEXT_PSEUDONYM,
+ id->get_encoding(id));
+ id->destroy(id);
}
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
free(mk.ptr);
@@ -237,14 +240,14 @@ static status_t reauthenticate(private_eap_aka_server_t *this,
AKA_REAUTHENTICATION, this->crypto);
message->add_attribute(message, AT_COUNTER, this->counter);
message->add_attribute(message, AT_NONCE_S, this->nonce);
- next = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk);
+ next = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk);
if (next)
{
message->add_attribute(message, AT_NEXT_REAUTH_ID,
next->get_encoding(next));
next->destroy(next);
}
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
this->pending = SIM_REAUTHENTICATION;
@@ -310,8 +313,7 @@ static status_t process_identity(private_eap_aka_server_t *this,
char mk[HASH_SIZE_SHA1];
u_int16_t counter;
- permanent = charon->sim->provider_is_reauth(charon->sim, id,
- mk, &counter);
+ permanent = this->mgr->provider_is_reauth(this->mgr, id, mk, &counter);
if (permanent)
{
this->permanent->destroy(this->permanent);
@@ -325,7 +327,7 @@ static status_t process_identity(private_eap_aka_server_t *this,
}
if (this->use_pseudonym)
{
- permanent = charon->sim->provider_is_pseudonym(charon->sim, id);
+ permanent = this->mgr->provider_is_pseudonym(this->mgr, id);
if (permanent)
{
this->permanent->destroy(this->permanent);
@@ -506,8 +508,8 @@ static status_t process_synchronize(private_eap_aka_server_t *this,
return FAILED;
}
- if (!charon->sim->provider_resync(charon->sim, this->permanent,
- this->rand.ptr, auts.ptr))
+ if (!this->mgr->provider_resync(this->mgr, this->permanent,
+ this->rand.ptr, auts.ptr))
{
DBG1(DBG_IKE, "no AKA provider found supporting "
"resynchronization for '%Y'", this->permanent);
@@ -564,7 +566,7 @@ METHOD(eap_method_t, process, status_t,
simaka_message_t *message;
status_t status;
- message = simaka_message_create_from_payload(in, this->crypto);
+ message = simaka_message_create_from_payload(in->get_data(in), this->crypto);
if (!message)
{
return FAILED;
@@ -676,7 +678,8 @@ eap_aka_server_t *eap_aka_server_create(identification_t *server,
.destroy = _destroy,
},
},
- .crypto = simaka_crypto_create(),
+ .crypto = simaka_crypto_create(EAP_AKA),
+ .mgr = lib->get(lib, "aka-manager"),
);
if (!this->crypto)
diff --git a/src/libcharon/plugins/eap_aka/eap_aka_server.h b/src/libcharon/plugins/eap_aka/eap_aka_server.h
index d48fc4c34..5ab1c4dfd 100644
--- a/src/libcharon/plugins/eap_aka/eap_aka_server.h
+++ b/src/libcharon/plugins/eap_aka/eap_aka_server.h
@@ -26,7 +26,7 @@ typedef struct eap_aka_server_t eap_aka_server_t;
#include <sa/authenticators/eap/eap_method.h>
/**
- * Implementation of the eap_method_t interface using EAP-AKA as server.
+ * EAP-AKA server implementation.
*/
struct eap_aka_server_t {
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am
index 598799e2a..b4d6dc1d2 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am
+++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.am
@@ -1,13 +1,17 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic
+libstrongswan_eap_aka_3gpp2_la_LDFLAGS = -module -avoid-version
+libstrongswan_eap_aka_3gpp2_la_LIBADD = -lgmp
+
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-eap-aka-3gpp2.la
else
plugin_LTLIBRARIES = libstrongswan-eap-aka-3gpp2.la
+libstrongswan_eap_aka_3gpp2_la_LIBADD += $(top_builddir)/src/libsimaka/libsimaka.la
endif
libstrongswan_eap_aka_3gpp2_la_SOURCES = \
@@ -15,6 +19,3 @@ libstrongswan_eap_aka_3gpp2_la_SOURCES = \
eap_aka_3gpp2_card.h eap_aka_3gpp2_card.c \
eap_aka_3gpp2_provider.h eap_aka_3gpp2_provider.c \
eap_aka_3gpp2_functions.h eap_aka_3gpp2_functions.c
-
-libstrongswan_eap_aka_3gpp2_la_LDFLAGS = -module -avoid-version
-libstrongswan_eap_aka_3gpp2_la_LIBADD = -lgmp
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
index 1fe86a2bb..b0890fb39 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
+++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in
@@ -34,6 +34,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@MONOLITHIC_FALSE@am__append_1 = $(top_builddir)/src/libsimaka/libsimaka.la
subdir = src/libcharon/plugins/eap_aka_3gpp2
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -74,7 +75,7 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_eap_aka_3gpp2_la_DEPENDENCIES =
+libstrongswan_eap_aka_3gpp2_la_DEPENDENCIES = $(am__append_1)
am_libstrongswan_eap_aka_3gpp2_la_OBJECTS = eap_aka_3gpp2_plugin.lo \
eap_aka_3gpp2_card.lo eap_aka_3gpp2_provider.lo \
eap_aka_3gpp2_functions.lo
@@ -196,6 +197,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -204,6 +208,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -220,11 +225,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -268,6 +275,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -279,9 +287,11 @@ 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/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic
+libstrongswan_eap_aka_3gpp2_la_LDFLAGS = -module -avoid-version
+libstrongswan_eap_aka_3gpp2_la_LIBADD = -lgmp $(am__append_1)
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-aka-3gpp2.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-aka-3gpp2.la
libstrongswan_eap_aka_3gpp2_la_SOURCES = \
@@ -290,8 +300,6 @@ libstrongswan_eap_aka_3gpp2_la_SOURCES = \
eap_aka_3gpp2_provider.h eap_aka_3gpp2_provider.c \
eap_aka_3gpp2_functions.h eap_aka_3gpp2_functions.c
-libstrongswan_eap_aka_3gpp2_la_LDFLAGS = -module -avoid-version
-libstrongswan_eap_aka_3gpp2_la_LIBADD = -lgmp
all: all-am
.SUFFIXES:
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c
index 5c0fe38ad..cec06fbd7 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c
+++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.c
@@ -51,14 +51,10 @@ struct private_eap_aka_3gpp2_card_t {
bool eap_aka_3gpp2_get_k(identification_t *id, char k[AKA_K_LEN]);
void eap_aka_3gpp2_get_sqn(char sqn[AKA_SQN_LEN], int offset);
-/**
- * Implementation of sim_card_t.get_quintuplet
- */
-static status_t get_quintuplet(private_eap_aka_3gpp2_card_t *this,
- identification_t *id, char rand[AKA_RAND_LEN],
- char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
- char ik[AKA_IK_LEN], char res[AKA_RES_MAX],
- int *res_len)
+METHOD(simaka_card_t, get_quintuplet, status_t,
+ private_eap_aka_3gpp2_card_t *this, identification_t *id,
+ char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
+ char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len)
{
char *amf, *mac;
char k[AKA_K_LEN], ak[AKA_AK_LEN], sqn[AKA_SQN_LEN], xmac[AKA_MAC_LEN];
@@ -112,11 +108,9 @@ static status_t get_quintuplet(private_eap_aka_3gpp2_card_t *this,
return SUCCESS;
}
-/**
- * Implementation of sim_card_t.resync
- */
-static bool resync(private_eap_aka_3gpp2_card_t *this, identification_t *id,
- char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
+METHOD(simaka_card_t, resync, bool,
+ private_eap_aka_3gpp2_card_t *this, identification_t *id,
+ char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
{
char amf[AKA_AMF_LEN], k[AKA_K_LEN], aks[AKA_AK_LEN], macs[AKA_MAC_LEN];
@@ -138,10 +132,8 @@ static bool resync(private_eap_aka_3gpp2_card_t *this, identification_t *id,
return TRUE;
}
-/**
- * Implementation of eap_aka_3gpp2_card_t.destroy.
- */
-static void destroy(private_eap_aka_3gpp2_card_t *this)
+METHOD(eap_aka_3gpp2_card_t, destroy, void,
+ private_eap_aka_3gpp2_card_t *this)
{
free(this);
}
@@ -151,25 +143,30 @@ static void destroy(private_eap_aka_3gpp2_card_t *this)
*/
eap_aka_3gpp2_card_t *eap_aka_3gpp2_card_create(eap_aka_3gpp2_functions_t *f)
{
- private_eap_aka_3gpp2_card_t *this = malloc_thing(private_eap_aka_3gpp2_card_t);
-
- this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false;
- this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len))get_quintuplet;
- this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))resync;
- this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *id))return_null;
- this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))nop;
- this->public.card.get_reauth = (identification_t*(*)(sim_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))return_null;
- this->public.card.set_reauth = (void(*)(sim_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))nop;
- this->public.destroy = (void(*)(eap_aka_3gpp2_card_t*))destroy;
-
- this->f = f;
- this->seq_check = lib->settings->get_bool(lib->settings,
+ private_eap_aka_3gpp2_card_t *this;
+
+ INIT(this,
+ .public = {
+ .card = {
+ .get_triplet = (void*)return_false,
+ .get_quintuplet = _get_quintuplet,
+ .resync = _resync,
+ .get_pseudonym = (void*)return_null,
+ .set_pseudonym = (void*)nop,
+ .get_reauth = (void*)return_null,
+ .set_reauth = (void*)nop,
+ },
+ .destroy = _destroy,
+ },
+ .f = f,
+ .seq_check = lib->settings->get_bool(lib->settings,
"charon.plugins.eap-aka-3gpp2.seq_check",
#ifdef SEQ_CHECK /* handle legacy compile time configuration as default */
- TRUE);
+ TRUE),
#else /* !SEQ_CHECK */
- FALSE);
+ FALSE),
#endif /* SEQ_CHECK */
+ );
eap_aka_3gpp2_get_sqn(this->sqn, 0);
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.h b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.h
index b95bc52af..eb6b1f75f 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.h
+++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_card.h
@@ -23,7 +23,7 @@
#include "eap_aka_3gpp2_functions.h"
-#include <sa/authenticators/eap/sim_manager.h>
+#include <simaka_card.h>
typedef struct eap_aka_3gpp2_card_t eap_aka_3gpp2_card_t;
@@ -33,9 +33,9 @@ typedef struct eap_aka_3gpp2_card_t eap_aka_3gpp2_card_t;
struct eap_aka_3gpp2_card_t {
/**
- * Implements sim_card_t interface
+ * Implements simaka_card_t interface
*/
- sim_card_t card;
+ simaka_card_t card;
/**
* Destroy a eap_aka_3gpp2_card_t.
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c
index 1d3d246d1..d000bebbb 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c
+++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.c
@@ -284,9 +284,10 @@ static void f5x(prf_t *prf, u_char f, u_char k[AKA_K_LEN],
/**
* Calculate MAC from RAND, SQN, AMF using K
*/
-static void f1(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
- u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN],
- u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN])
+METHOD(eap_aka_3gpp2_functions_t, f1, void,
+ private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
+ u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN],
+ u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN])
{
f1x(this->prf, F1, k, rand, sqn, amf, mac);
DBG3(DBG_IKE, "MAC %b", mac, AKA_MAC_LEN);
@@ -295,9 +296,10 @@ static void f1(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
/**
* Calculate MACS from RAND, SQN, AMF using K
*/
-static void f1star(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
- u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN],
- u_char amf[AKA_AMF_LEN], u_char macs[AKA_MAC_LEN])
+METHOD(eap_aka_3gpp2_functions_t, f1star, void,
+ private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
+ u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN],
+ u_char amf[AKA_AMF_LEN], u_char macs[AKA_MAC_LEN])
{
f1x(this->prf, F1STAR, k, rand, sqn, amf, macs);
DBG3(DBG_IKE, "MACS %b", macs, AKA_MAC_LEN);
@@ -306,8 +308,9 @@ static void f1star(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
/**
* Calculate RES from RAND using K
*/
-static void f2(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
- u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX])
+METHOD(eap_aka_3gpp2_functions_t, f2, void,
+ private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
+ u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX])
{
fx(this->prf, F2, k, rand, res);
DBG3(DBG_IKE, "RES %b", res, AKA_RES_MAX);
@@ -316,8 +319,9 @@ static void f2(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
/**
* Calculate CK from RAND using K
*/
-static void f3(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
- u_char rand[AKA_RAND_LEN], u_char ck[AKA_CK_LEN])
+METHOD(eap_aka_3gpp2_functions_t, f3, void,
+ private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
+ u_char rand[AKA_RAND_LEN], u_char ck[AKA_CK_LEN])
{
fx(this->prf, F3, k, rand, ck);
DBG3(DBG_IKE, "CK %b", ck, AKA_CK_LEN);
@@ -326,8 +330,9 @@ static void f3(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
/**
* Calculate IK from RAND using K
*/
-static void f4(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
- u_char rand[AKA_RAND_LEN], u_char ik[AKA_IK_LEN])
+METHOD(eap_aka_3gpp2_functions_t, f4, void,
+ private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
+ u_char rand[AKA_RAND_LEN], u_char ik[AKA_IK_LEN])
{
fx(this->prf, F4, k, rand, ik);
DBG3(DBG_IKE, "IK %b", ik, AKA_IK_LEN);
@@ -336,8 +341,9 @@ static void f4(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
/**
* Calculate AK from a RAND using K
*/
-static void f5(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
- u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN])
+METHOD(eap_aka_3gpp2_functions_t, f5, void,
+ private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
+ u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN])
{
f5x(this->prf, F5, k, rand, ak);
DBG3(DBG_IKE, "AK %b", ak, AKA_AK_LEN);
@@ -346,18 +352,16 @@ static void f5(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
/**
* Calculate AKS from a RAND using K
*/
-static void f5star(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
- u_char rand[AKA_RAND_LEN], u_char aks[AKA_AK_LEN])
+METHOD(eap_aka_3gpp2_functions_t, f5star, void,
+ private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
+ u_char rand[AKA_RAND_LEN], u_char aks[AKA_AK_LEN])
{
f5x(this->prf, F5STAR, k, rand, aks);
DBG3(DBG_IKE, "AKS %b", aks, AKA_AK_LEN);
}
-
-/**
- * Implementation of eap_aka_3gpp2_functions_t.destroy.
- */
-static void destroy(private_eap_aka_3gpp2_functions_t *this)
+METHOD(eap_aka_3gpp2_functions_t, destroy, void,
+ private_eap_aka_3gpp2_functions_t *this)
{
this->prf->destroy(this->prf);
free(this);
@@ -370,18 +374,19 @@ eap_aka_3gpp2_functions_t *eap_aka_3gpp2_functions_create()
{
private_eap_aka_3gpp2_functions_t *this;
- this = malloc_thing(private_eap_aka_3gpp2_functions_t);
-
- this->public.f1 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN]))f1;
- this->public.f1star = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], u_char amf[AKA_AMF_LEN], u_char macs[AKA_MAC_LEN]))f1star;
- this->public.f2 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX]))f2;
- this->public.f3 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ck[AKA_CK_LEN]))f3;
- this->public.f4 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ik[AKA_IK_LEN]))f4;
- this->public.f5 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN]))f5;
- this->public.f5star = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char aks[AKA_AK_LEN]))f5star;
- this->public.destroy = (void(*)(eap_aka_3gpp2_functions_t*))destroy;
-
- this->prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1);
+ INIT(this,
+ .public = {
+ .f1 = _f1,
+ .f1star = _f1star,
+ .f2 = _f2,
+ .f3 = _f3,
+ .f4 = _f4,
+ .f5 = _f5,
+ .f5star = _f5star,
+ .destroy = _destroy,
+ },
+ .prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1),
+ );
if (!this->prf)
{
DBG1(DBG_CFG, "%N not supported, unable to use 3GPP2 algorithm",
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h
index 95c6da6a9..855efec3e 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h
+++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_functions.h
@@ -21,7 +21,7 @@
#ifndef EAP_AKA_3GPP2_FUNCTIONS_H_
#define EAP_AKA_3GPP2_FUNCTIONS_H_
-#include <sa/authenticators/eap/sim_manager.h>
+#include <simaka_manager.h>
#define AKA_SQN_LEN 6
#define AKA_K_LEN 16
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c
index ef5f62e34..d7d0d0507 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c
+++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_plugin.c
@@ -54,14 +54,71 @@ METHOD(plugin_t, get_name, char*,
return "eap-aka-3gpp2";
}
-METHOD(plugin_t, destroy, void,
- private_eap_aka_3gpp2_t *this)
+/**
+ * Try to instanciate 3gpp2 functions and card/provider backends
+ */
+static bool register_functions(private_eap_aka_3gpp2_t *this,
+ plugin_feature_t *feature, bool reg, void *data)
{
- charon->sim->remove_card(charon->sim, &this->card->card);
- charon->sim->remove_provider(charon->sim, &this->provider->provider);
+ if (reg)
+ {
+ this->functions = eap_aka_3gpp2_functions_create();
+ if (!this->functions)
+ {
+ return FALSE;
+ }
+ this->card = eap_aka_3gpp2_card_create(this->functions);
+ this->provider = eap_aka_3gpp2_provider_create(this->functions);
+ return TRUE;
+ }
this->card->destroy(this->card);
this->provider->destroy(this->provider);
this->functions->destroy(this->functions);
+ this->card = NULL;
+ this->provider = NULL;
+ this->functions = NULL;
+ return TRUE;
+}
+
+/**
+ * Callback providing our card to register
+ */
+static simaka_card_t* get_card(private_eap_aka_3gpp2_t *this)
+{
+ return &this->card->card;
+}
+
+/**
+ * Callback providing our provider to register
+ */
+static simaka_provider_t* get_provider(private_eap_aka_3gpp2_t *this)
+{
+ return &this->provider->provider;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_eap_aka_3gpp2_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK((void*)register_functions, NULL),
+ PLUGIN_PROVIDE(CUSTOM, "eap-aka-3gpp2-functions"),
+ PLUGIN_DEPENDS(PRF, PRF_KEYED_SHA1),
+ PLUGIN_CALLBACK(simaka_manager_register, get_card),
+ PLUGIN_PROVIDE(CUSTOM, "aka-card"),
+ PLUGIN_DEPENDS(CUSTOM, "aka-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "eap-aka-3gpp2-functions"),
+ PLUGIN_CALLBACK(simaka_manager_register, get_provider),
+ PLUGIN_PROVIDE(CUSTOM, "aka-provider"),
+ PLUGIN_DEPENDS(CUSTOM, "aka-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "eap-aka-3gpp2-functions"),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_eap_aka_3gpp2_t *this)
+{
free(this);
}
@@ -76,24 +133,12 @@ plugin_t *eap_aka_3gpp2_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
- .functions = eap_aka_3gpp2_functions_create(),
);
- if (!this->functions)
- {
- free(this);
- return NULL;
- }
- this->card = eap_aka_3gpp2_card_create(this->functions);
- this->provider = eap_aka_3gpp2_provider_create(this->functions);
-
- charon->sim->add_card(charon->sim, &this->card->card);
- charon->sim->add_provider(charon->sim, &this->provider->provider);
-
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c
index a9767ad91..b2b43da2a 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c
+++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.c
@@ -80,14 +80,10 @@ void eap_aka_3gpp2_get_sqn(char sqn[AKA_SQN_LEN], int offset)
memcpy(sqn + 4, &time.tv_usec, 2);
}
-/**
- * Implementation of usim_provider_t.get_quintuplet
- */
-static bool get_quintuplet(private_eap_aka_3gpp2_provider_t *this,
- identification_t *id, char rand[AKA_RAND_LEN],
- char xres[AKA_RES_MAX], int *xres_len,
- char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
- char autn[AKA_AUTN_LEN])
+METHOD(simaka_provider_t, get_quintuplet, bool,
+ private_eap_aka_3gpp2_provider_t *this, identification_t *id,
+ char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len,
+ char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN])
{
rng_t *rng;
char mac[AKA_MAC_LEN], ak[AKA_AK_LEN], k[AKA_K_LEN];
@@ -131,12 +127,9 @@ static bool get_quintuplet(private_eap_aka_3gpp2_provider_t *this,
return TRUE;
}
-/**
- * Implementation of usim_provider_t.resync
- */
-static bool resync(private_eap_aka_3gpp2_provider_t *this,
- identification_t *id, char rand[AKA_RAND_LEN],
- char auts[AKA_AUTS_LEN])
+METHOD(simaka_provider_t, resync, bool,
+ private_eap_aka_3gpp2_provider_t *this, identification_t *id,
+ char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
{
char *sqn, *macs;
char aks[AKA_AK_LEN], k[AKA_K_LEN], amf[AKA_AMF_LEN], xmacs[AKA_MAC_LEN];
@@ -169,10 +162,8 @@ static bool resync(private_eap_aka_3gpp2_provider_t *this,
return TRUE;
}
-/**
- * Implementation of eap_aka_3gpp2_provider_t.destroy.
- */
-static void destroy(private_eap_aka_3gpp2_provider_t *this)
+METHOD(eap_aka_3gpp2_provider_t, destroy, void,
+ private_eap_aka_3gpp2_provider_t *this)
{
free(this);
}
@@ -183,18 +174,23 @@ static void destroy(private_eap_aka_3gpp2_provider_t *this)
eap_aka_3gpp2_provider_t *eap_aka_3gpp2_provider_create(
eap_aka_3gpp2_functions_t *f)
{
- private_eap_aka_3gpp2_provider_t *this = malloc_thing(private_eap_aka_3gpp2_provider_t);
-
- this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false;
- this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))get_quintuplet;
- this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))resync;
- this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null;
- this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null;
- this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))return_null;
- this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))return_null;
- this->public.destroy = (void(*)(eap_aka_3gpp2_provider_t*))destroy;
-
- this->f = f;
+ private_eap_aka_3gpp2_provider_t *this;
+
+ INIT(this,
+ .public = {
+ .provider = {
+ .get_triplet = (void*)return_false,
+ .get_quintuplet = _get_quintuplet,
+ .resync = _resync,
+ .is_pseudonym = (void*)return_null,
+ .gen_pseudonym = (void*)return_null,
+ .is_reauth = (void*)return_null,
+ .gen_reauth = (void*)return_null,
+ },
+ .destroy = _destroy,
+ },
+ .f = f,
+ );
/* use an offset to accept clock skew between client/server without resync */
eap_aka_3gpp2_get_sqn(this->sqn, 180);
diff --git a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.h b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.h
index 22ac0a96e..0e1af8554 100644
--- a/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.h
+++ b/src/libcharon/plugins/eap_aka_3gpp2/eap_aka_3gpp2_provider.h
@@ -23,7 +23,7 @@
#include "eap_aka_3gpp2_functions.h"
-#include <sa/authenticators/eap/sim_manager.h>
+#include <simaka_provider.h>
typedef struct eap_aka_3gpp2_provider_t eap_aka_3gpp2_provider_t;
@@ -33,9 +33,9 @@ typedef struct eap_aka_3gpp2_provider_t eap_aka_3gpp2_provider_t;
struct eap_aka_3gpp2_provider_t {
/**
- * Implements sim_provider_t interface.
+ * Implements simaka_provider_t interface.
*/
- sim_provider_t provider;
+ simaka_provider_t provider;
/**
* Destroy a eap_aka_3gpp2_provider_t.
diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in
index 4f555a982..b3f989e38 100644
--- a/src/libcharon/plugins/eap_gtc/Makefile.in
+++ b/src/libcharon/plugins/eap_gtc/Makefile.in
@@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -201,6 +204,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -217,11 +221,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c b/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c
index c40ce60eb..bd70b757a 100644
--- a/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c
+++ b/src/libcharon/plugins/eap_gtc/eap_gtc_plugin.c
@@ -28,13 +28,22 @@ METHOD(plugin_t, get_name, char*,
return "eap-gtc";
}
+METHOD(plugin_t, get_features, int,
+ eap_gtc_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(eap_method_register, eap_gtc_create_server),
+ PLUGIN_PROVIDE(EAP_SERVER, EAP_GTC),
+ PLUGIN_CALLBACK(eap_method_register, eap_gtc_create_peer),
+ PLUGIN_PROVIDE(EAP_PEER, EAP_GTC),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
eap_gtc_plugin_t *this)
{
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_gtc_create_server);
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_gtc_create_peer);
free(this);
}
@@ -48,7 +57,7 @@ plugin_t *eap_gtc_plugin_create()
INIT(this,
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
);
diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in
index 9dc4602ff..b348b5fb5 100644
--- a/src/libcharon/plugins/eap_identity/Makefile.in
+++ b/src/libcharon/plugins/eap_identity/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/eap_identity/eap_identity_plugin.c b/src/libcharon/plugins/eap_identity/eap_identity_plugin.c
index 3297416b2..b09e51568 100644
--- a/src/libcharon/plugins/eap_identity/eap_identity_plugin.c
+++ b/src/libcharon/plugins/eap_identity/eap_identity_plugin.c
@@ -24,13 +24,22 @@ METHOD(plugin_t, get_name, char*,
return "eap-identity";
}
+METHOD(plugin_t, get_features, int,
+ eap_identity_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(eap_method_register, eap_identity_create_server),
+ PLUGIN_PROVIDE(EAP_SERVER, EAP_IDENTITY),
+ PLUGIN_CALLBACK(eap_method_register, eap_identity_create_peer),
+ PLUGIN_PROVIDE(EAP_PEER, EAP_IDENTITY),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
eap_identity_plugin_t *this)
{
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_identity_create_server);
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_identity_create_peer);
free(this);
}
@@ -44,16 +53,11 @@ plugin_t *eap_identity_plugin_create()
INIT(this,
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
);
- charon->eap->add_method(charon->eap, EAP_IDENTITY, 0, EAP_SERVER,
- (eap_constructor_t)eap_identity_create_server);
- charon->eap->add_method(charon->eap, EAP_IDENTITY, 0, EAP_PEER,
- (eap_constructor_t)eap_identity_create_peer);
-
return &this->plugin;
}
diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in
index e828fbc3e..209753b2d 100644
--- a/src/libcharon/plugins/eap_md5/Makefile.in
+++ b/src/libcharon/plugins/eap_md5/Makefile.in
@@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -201,6 +204,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -217,11 +221,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/eap_md5/eap_md5_plugin.c b/src/libcharon/plugins/eap_md5/eap_md5_plugin.c
index fe5ae51bf..d045e02bf 100644
--- a/src/libcharon/plugins/eap_md5/eap_md5_plugin.c
+++ b/src/libcharon/plugins/eap_md5/eap_md5_plugin.c
@@ -24,13 +24,26 @@ METHOD(plugin_t, get_name, char*,
return "eap-md5";
}
+METHOD(plugin_t, get_features, int,
+ eap_md5_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(eap_method_register, eap_md5_create_server),
+ PLUGIN_PROVIDE(EAP_SERVER, EAP_MD5),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_CALLBACK(eap_method_register, eap_md5_create_peer),
+ PLUGIN_PROVIDE(EAP_PEER, EAP_MD5),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
eap_md5_plugin_t *this)
{
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_md5_create_server);
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_md5_create_peer);
free(this);
}
@@ -44,16 +57,11 @@ plugin_t *eap_md5_plugin_create()
INIT(this,
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
);
- charon->eap->add_method(charon->eap, EAP_MD5, 0, EAP_SERVER,
- (eap_constructor_t)eap_md5_create_server);
- charon->eap->add_method(charon->eap, EAP_MD5, 0, EAP_PEER,
- (eap_constructor_t)eap_md5_create_peer);
-
return &this->plugin;
}
diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in
index 4986fdce3..6d3d7f8db 100644
--- a/src/libcharon/plugins/eap_mschapv2/Makefile.in
+++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
index 1dd94f6fb..9dfc69205 100644
--- a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
+++ b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2.c
@@ -814,7 +814,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, retriable;
+ int message_len, error = 0;
chunk_t challenge = chunk_empty;
data = in->get_data(in);
@@ -842,8 +842,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
}
else if (strneq(token, "R=", 2))
{
- token += 2;
- retriable = atoi(token);
+ /* ignore retriable */
}
else if (strneq(token, "C=", 2))
{
@@ -860,9 +859,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
}
else if (strneq(token, "V=", 2))
{
- int version;
- token += 2;
- version = atoi(token);
+ /* ignore version */
}
else if (strneq(token, "M=", 2))
{
diff --git a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c
index e809b14b6..6fd96708a 100644
--- a/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c
+++ b/src/libcharon/plugins/eap_mschapv2/eap_mschapv2_plugin.c
@@ -25,13 +25,30 @@ METHOD(plugin_t, get_name, char*,
return "eap-mschapv2";
}
+METHOD(plugin_t, get_features, int,
+ eap_mschapv2_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(eap_method_register, eap_mschapv2_create_server),
+ PLUGIN_PROVIDE(EAP_SERVER, EAP_MSCHAPV2),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_DES_ECB, 8),
+ PLUGIN_DEPENDS(HASHER, HASH_MD4),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_CALLBACK(eap_method_register, eap_mschapv2_create_peer),
+ PLUGIN_PROVIDE(EAP_PEER, EAP_MSCHAPV2),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_DES_ECB, 8),
+ PLUGIN_DEPENDS(HASHER, HASH_MD4),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
eap_mschapv2_plugin_t *this)
{
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_mschapv2_create_server);
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_mschapv2_create_peer);
free(this);
}
@@ -45,16 +62,11 @@ plugin_t *eap_mschapv2_plugin_create()
INIT(this,
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
);
- charon->eap->add_method(charon->eap, EAP_MSCHAPV2, 0, EAP_SERVER,
- (eap_constructor_t)eap_mschapv2_create_server);
- charon->eap->add_method(charon->eap, EAP_MSCHAPV2, 0, EAP_PEER,
- (eap_constructor_t)eap_mschapv2_create_peer);
-
return &this->plugin;
}
diff --git a/src/libcharon/plugins/eap_peap/Makefile.in b/src/libcharon/plugins/eap_peap/Makefile.in
index 0ed4a3dcf..4f860e175 100644
--- a/src/libcharon/plugins/eap_peap/Makefile.in
+++ b/src/libcharon/plugins/eap_peap/Makefile.in
@@ -196,6 +196,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -204,6 +207,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -220,11 +224,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -268,6 +274,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/eap_peap/eap_peap.c b/src/libcharon/plugins/eap_peap/eap_peap.c
index 5bae0fa9b..bd426bba7 100644
--- a/src/libcharon/plugins/eap_peap/eap_peap.c
+++ b/src/libcharon/plugins/eap_peap/eap_peap.c
@@ -166,7 +166,8 @@ static eap_peap_t *eap_peap_create(private_eap_peap_t * this,
"charon.plugins.eap-peap.max_message_count", MAX_MESSAGE_COUNT);
include_length = lib->settings->get_bool(lib->settings,
"charon.plugins.eap-peap.include_length", FALSE);
- tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_PEAP, application);
+ tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_PEAP,
+ application, NULL);
this->tls_eap = tls_eap_create(EAP_PEAP, tls, frag_size, max_msg_count,
include_length);
if (!this->tls_eap)
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_avp.c b/src/libcharon/plugins/eap_peap/eap_peap_avp.c
index 06e5222d9..10f6ec11c 100644
--- a/src/libcharon/plugins/eap_peap/eap_peap_avp.c
+++ b/src/libcharon/plugins/eap_peap/eap_peap_avp.c
@@ -25,6 +25,8 @@ static const chunk_t MS_AVP_Success = chunk_from_chars(
0x80, 0x03, 0x00, 0x02, 0x00, 0x01);
static const chunk_t MS_AVP_Failure = chunk_from_chars(
0x80, 0x03, 0x00, 0x02, 0x00, 0x02);
+static const chunk_t MS_SoH_Request = chunk_from_chars(
+ 0x00, 0x01, 0x37, 0x00, 0x00, 0x00, 0x21, 0x00, 0x02, 0x00, 0x00);
typedef struct private_eap_peap_avp_t private_eap_peap_avp_t;
@@ -45,7 +47,7 @@ struct private_eap_peap_avp_t {
};
METHOD(eap_peap_avp_t, build, void,
- private_eap_peap_avp_t *this, tls_writer_t *writer, chunk_t data)
+ private_eap_peap_avp_t *this, bio_writer_t *writer, chunk_t data)
{
u_int8_t code;
eap_packet_t *pkt;
@@ -62,6 +64,19 @@ METHOD(eap_peap_avp_t, build, void,
writer->write_uint8(writer, EAP_MSTLV);
avp_data = (pkt->code == EAP_SUCCESS) ? MS_AVP_Success : MS_AVP_Failure;
}
+ /**
+ * Still trying to form a correct MS SoH Request
+ *
+ else if (pkt->type == EAP_MSCHAPV2)
+ {
+ code = (this->is_server) ? EAP_REQUEST : EAP_RESPONSE;
+ writer->write_uint8(writer, code);
+ writer->write_uint8(writer, pkt->identifier);
+ writer->write_uint16(writer, 16);
+ writer->write_uint8(writer, EAP_EXPANDED);
+ avp_data = MS_SoH_Request;
+ }
+ */
else
{
avp_data = chunk_skip(data, 4);
@@ -70,7 +85,7 @@ METHOD(eap_peap_avp_t, build, void,
}
METHOD(eap_peap_avp_t, process, status_t,
- private_eap_peap_avp_t* this, tls_reader_t *reader, chunk_t *data,
+ private_eap_peap_avp_t* this, bio_reader_t *reader, chunk_t *data,
u_int8_t identifier)
{
u_int8_t code;
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_avp.h b/src/libcharon/plugins/eap_peap/eap_peap_avp.h
index db22f0f8f..98c5f1912 100644
--- a/src/libcharon/plugins/eap_peap/eap_peap_avp.h
+++ b/src/libcharon/plugins/eap_peap/eap_peap_avp.h
@@ -25,8 +25,8 @@ typedef struct eap_peap_avp_t eap_peap_avp_t;
#include <library.h>
-#include <tls_reader.h>
-#include <tls_writer.h>
+#include <bio/bio_reader.h>
+#include <bio/bio_writer.h>
/**
* EAP-PEAP Attribute-Value Pair (AVP) handler.
@@ -44,7 +44,7 @@ struct eap_peap_avp_t {
* - FAILED if AVP processing failed
* - NEED_MORE if another invocation of process/build needed
*/
- status_t (*process)(eap_peap_avp_t *this, tls_reader_t *reader,
+ status_t (*process)(eap_peap_avp_t *this, bio_reader_t *reader,
chunk_t *data, u_int8_t identifier);
/**
@@ -53,7 +53,7 @@ struct eap_peap_avp_t {
* @param writer TLS data buffer to write to
* @param data EAP Message to send
*/
- void (*build)(eap_peap_avp_t *this, tls_writer_t *writer, chunk_t data);
+ void (*build)(eap_peap_avp_t *this, bio_writer_t *writer, chunk_t data);
/**
* Destroy a eap_peap_application_t.
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_peer.c b/src/libcharon/plugins/eap_peap/eap_peap_peer.c
index ca2af4fee..72e201fb6 100644
--- a/src/libcharon/plugins/eap_peap/eap_peap_peer.c
+++ b/src/libcharon/plugins/eap_peap/eap_peap_peer.c
@@ -63,7 +63,7 @@ struct private_eap_peap_peer_t {
};
METHOD(tls_application_t, process, status_t,
- private_eap_peap_peer_t *this, tls_reader_t *reader)
+ private_eap_peap_peer_t *this, bio_reader_t *reader)
{
chunk_t data = chunk_empty;
status_t status;
@@ -185,7 +185,7 @@ METHOD(tls_application_t, process, status_t,
}
METHOD(tls_application_t, build, status_t,
- private_eap_peap_peer_t *this, tls_writer_t *writer)
+ private_eap_peap_peer_t *this, bio_writer_t *writer)
{
chunk_t data;
eap_code_t code;
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_plugin.c b/src/libcharon/plugins/eap_peap/eap_peap_plugin.c
index bac5f2d3e..e8deee9e1 100644
--- a/src/libcharon/plugins/eap_peap/eap_peap_plugin.c
+++ b/src/libcharon/plugins/eap_peap/eap_peap_plugin.c
@@ -25,13 +25,31 @@ METHOD(plugin_t, get_name, char*,
return "eap-peap";
}
+METHOD(plugin_t, get_features, int,
+ eap_peap_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(eap_method_register, eap_peap_create_server),
+ PLUGIN_PROVIDE(EAP_SERVER, EAP_PEAP),
+ PLUGIN_DEPENDS(EAP_SERVER, EAP_IDENTITY),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_CALLBACK(eap_method_register, eap_peap_create_peer),
+ PLUGIN_PROVIDE(EAP_PEER, EAP_PEAP),
+ PLUGIN_DEPENDS(EAP_PEER, EAP_IDENTITY),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
eap_peap_plugin_t *this)
{
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_peap_create_server);
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_peap_create_peer);
free(this);
}
@@ -45,15 +63,10 @@ plugin_t *eap_peap_plugin_create()
INIT(this,
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
);
- charon->eap->add_method(charon->eap, EAP_PEAP, 0, EAP_SERVER,
- (eap_constructor_t)eap_peap_create_server);
- charon->eap->add_method(charon->eap, EAP_PEAP, 0, EAP_PEER,
- (eap_constructor_t)eap_peap_create_peer);
-
return &this->plugin;
}
diff --git a/src/libcharon/plugins/eap_peap/eap_peap_server.c b/src/libcharon/plugins/eap_peap/eap_peap_server.c
index 3fabc3575..4acdd9f07 100644
--- a/src/libcharon/plugins/eap_peap/eap_peap_server.c
+++ b/src/libcharon/plugins/eap_peap/eap_peap_server.c
@@ -158,7 +158,7 @@ static status_t start_phase2_tnc(private_eap_peap_server_t *this)
}
METHOD(tls_application_t, process, status_t,
- private_eap_peap_server_t *this, tls_reader_t *reader)
+ private_eap_peap_server_t *this, bio_reader_t *reader)
{
chunk_t data = chunk_empty;
status_t status;
@@ -330,7 +330,7 @@ METHOD(tls_application_t, process, status_t,
}
METHOD(tls_application_t, build, status_t,
- private_eap_peap_server_t *this, tls_writer_t *writer)
+ private_eap_peap_server_t *this, bio_writer_t *writer)
{
chunk_t data;
eap_code_t code;
diff --git a/src/libcharon/plugins/eap_radius/Makefile.am b/src/libcharon/plugins/eap_radius/Makefile.am
index afc50bced..181497ab5 100644
--- a/src/libcharon/plugins/eap_radius/Makefile.am
+++ b/src/libcharon/plugins/eap_radius/Makefile.am
@@ -1,21 +1,21 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libradius
AM_CFLAGS = -rdynamic
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-eap-radius.la
else
+libstrongswan_eap_radius_la_LIBADD = $(top_builddir)/src/libradius/libradius.la
plugin_LTLIBRARIES = libstrongswan-eap-radius.la
endif
libstrongswan_eap_radius_la_SOURCES = \
eap_radius_plugin.h eap_radius_plugin.c \
eap_radius.h eap_radius.c \
- radius_server.h radius_server.c \
- radius_socket.h radius_socket.c \
- radius_client.h radius_client.c \
- radius_message.h radius_message.c
+ eap_radius_accounting.h eap_radius_accounting.c \
+ eap_radius_dae.h eap_radius_dae.c \
+ eap_radius_forward.h eap_radius_forward.c
libstrongswan_eap_radius_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in
index 740c64055..0bef44042 100644
--- a/src/libcharon/plugins/eap_radius/Makefile.in
+++ b/src/libcharon/plugins/eap_radius/Makefile.in
@@ -74,10 +74,11 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_eap_radius_la_LIBADD =
+@MONOLITHIC_FALSE@libstrongswan_eap_radius_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libradius/libradius.la
am_libstrongswan_eap_radius_la_OBJECTS = eap_radius_plugin.lo \
- eap_radius.lo radius_server.lo radius_socket.lo \
- radius_client.lo radius_message.lo
+ eap_radius.lo eap_radius_accounting.lo eap_radius_dae.lo \
+ eap_radius_forward.lo
libstrongswan_eap_radius_la_OBJECTS = \
$(am_libstrongswan_eap_radius_la_OBJECTS)
libstrongswan_eap_radius_la_LINK = $(LIBTOOL) --tag=CC \
@@ -196,6 +197,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -204,6 +208,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -220,11 +225,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -268,6 +275,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -279,18 +287,18 @@ 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/libcharon -I$(top_srcdir)/src/libradius
AM_CFLAGS = -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-radius.la
+@MONOLITHIC_FALSE@libstrongswan_eap_radius_la_LIBADD = $(top_builddir)/src/libradius/libradius.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-radius.la
libstrongswan_eap_radius_la_SOURCES = \
eap_radius_plugin.h eap_radius_plugin.c \
eap_radius.h eap_radius.c \
- radius_server.h radius_server.c \
- radius_socket.h radius_socket.c \
- radius_client.h radius_client.c \
- radius_message.h radius_message.c
+ eap_radius_accounting.h eap_radius_accounting.c \
+ eap_radius_dae.h eap_radius_dae.c \
+ eap_radius_forward.h eap_radius_forward.c
libstrongswan_eap_radius_la_LDFLAGS = -module -avoid-version
all: all-am
@@ -377,11 +385,10 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_radius.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_radius_accounting.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_radius_dae.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_radius_forward.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_radius_plugin.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_client.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_message.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_server.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_socket.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/libcharon/plugins/eap_radius/eap_radius.c b/src/libcharon/plugins/eap_radius/eap_radius.c
index dfe0e2e09..c0a3703b6 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius.c
@@ -14,14 +14,14 @@
*/
#include "eap_radius.h"
+#include "eap_radius_plugin.h"
+#include "eap_radius_forward.h"
-#include "radius_message.h"
-#include "radius_client.h"
+#include <radius_message.h>
+#include <radius_client.h>
#include <daemon.h>
-#define TUNNEL_TYPE_ESP 9
-
typedef struct private_eap_radius_t private_eap_radius_t;
/**
@@ -162,7 +162,7 @@ METHOD(eap_method_t, initiate, status_t,
status_t status = FAILED;
chunk_t username;
- request = radius_message_create_request();
+ request = radius_message_create(RMC_ACCESS_REQUEST);
username = chunk_create(this->id_prefix, strlen(this->id_prefix));
username = chunk_cata("cc", username, this->peer->get_encoding(this->peer));
request->add(request, RAT_USER_NAME, username);
@@ -175,16 +175,22 @@ METHOD(eap_method_t, initiate, status_t,
{
add_eap_identity(this, request);
}
+ eap_radius_forward_from_ike(request);
response = this->client->request(this->client, request);
if (response)
{
+ eap_radius_forward_to_ike(response);
if (radius2ike(this, response, out))
{
status = NEED_MORE;
}
response->destroy(response);
}
+ else
+ {
+ charon->bus->alert(charon->bus, ALERT_RADIUS_NOT_RESPONDING);
+ }
request->destroy(request);
return status;
}
@@ -253,7 +259,7 @@ static void process_filter_id(private_eap_radius_t *this, radius_message_t *msg)
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);
+ is_esp_tunnel = (tunnel_type == RADIUS_TUNNEL_TYPE_ESP);
break;
case RAT_FILTER_ID:
filter_id = data;
@@ -282,6 +288,31 @@ static void process_filter_id(private_eap_radius_t *this, radius_message_t *msg)
}
}
+/**
+ * Handle Session-Timeout attribte
+ */
+static void process_timeout(private_eap_radius_t *this, radius_message_t *msg)
+{
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ chunk_t data;
+ int type;
+
+ enumerator = msg->create_enumerator(msg);
+ while (enumerator->enumerate(enumerator, &type, &data))
+ {
+ if (type == RAT_SESSION_TIMEOUT && data.len == 4)
+ {
+ ike_sa = charon->bus->get_sa(charon->bus);
+ if (ike_sa)
+ {
+ ike_sa->set_auth_lifetime(ike_sa, untoh32(data.ptr));
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
METHOD(eap_method_t, process, status_t,
private_eap_radius_t *this, eap_payload_t *in, eap_payload_t **out)
{
@@ -289,22 +320,25 @@ METHOD(eap_method_t, process, status_t,
status_t status = FAILED;
chunk_t data;
- request = radius_message_create_request();
+ request = radius_message_create(RMC_ACCESS_REQUEST);
request->add(request, RAT_USER_NAME, this->peer->get_encoding(this->peer));
data = in->get_data(in);
DBG3(DBG_IKE, "%N payload %B", eap_type_names, this->type, &data);
-
- /* fragment data suitable for RADIUS (not more than 253 bytes) */
- while (data.len > 253)
+
+ /* fragment data suitable for RADIUS */
+ while (data.len > MAX_RADIUS_ATTRIBUTE_SIZE)
{
- request->add(request, RAT_EAP_MESSAGE, chunk_create(data.ptr, 253));
- data = chunk_skip(data, 253);
+ request->add(request, RAT_EAP_MESSAGE,
+ chunk_create(data.ptr,MAX_RADIUS_ATTRIBUTE_SIZE));
+ data = chunk_skip(data, MAX_RADIUS_ATTRIBUTE_SIZE);
}
request->add(request, RAT_EAP_MESSAGE, data);
+ eap_radius_forward_from_ike(request);
response = this->client->request(this->client, request);
if (response)
{
+ eap_radius_forward_to_ike(response);
switch (response->get_code(response))
{
case RMC_ACCESS_CHALLENGE:
@@ -324,6 +358,7 @@ METHOD(eap_method_t, process, status_t,
{
process_filter_id(this, response);
}
+ process_timeout(this, response);
DBG1(DBG_IKE, "RADIUS authentication of '%Y' successful",
this->peer);
status = SUCCESS;
@@ -427,7 +462,7 @@ eap_radius_t *eap_radius_create(identification_t *server, identification_t *peer
"charon.plugins.eap-radius.filter_id", FALSE),
);
- this->client = radius_client_create();
+ this->client = eap_radius_create_client();
if (!this->client)
{
free(this);
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
new file mode 100644
index 000000000..45be22704
--- /dev/null
+++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 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_radius_accounting.h"
+#include "eap_radius_plugin.h"
+
+#include <time.h>
+
+#include <radius_message.h>
+#include <radius_client.h>
+#include <daemon.h>
+#include <utils/hashtable.h>
+#include <threading/mutex.h>
+
+typedef struct private_eap_radius_accounting_t private_eap_radius_accounting_t;
+
+/**
+ * Private data of an eap_radius_accounting_t object.
+ */
+struct private_eap_radius_accounting_t {
+
+ /**
+ * Public eap_radius_accounting_t interface.
+ */
+ eap_radius_accounting_t public;
+
+ /**
+ * Hashtable with sessions, IKE_SA unique id => entry_t
+ */
+ hashtable_t *sessions;
+
+ /**
+ * Mutex to lock sessions
+ */
+ mutex_t *mutex;
+
+ /**
+ * Session ID prefix
+ */
+ u_int32_t prefix;
+};
+
+/**
+ * Hashtable entry with usage stats
+ */
+typedef struct {
+ /** RADIUS accounting session ID */
+ char sid[16];
+ /** number of octets sent */
+ u_int64_t sent;
+ /** number of octets received */
+ u_int64_t received;
+ /** session creation time */
+ time_t created;
+} entry_t;
+
+/**
+ * Accounting message status types
+ */
+typedef enum {
+ ACCT_STATUS_START = 1,
+ ACCT_STATUS_STOP = 2,
+ ACCT_STATUS_INTERIM_UPDATE = 3,
+ ACCT_STATUS_ACCOUNTING_ON = 7,
+ ACCT_STATUS_ACCOUNTING_OFF = 8,
+} radius_acct_status_t;
+
+/**
+ * Hashtable hash function
+ */
+static u_int hash(uintptr_t key)
+{
+ return key;
+}
+
+/**
+ * Hashtable equals function
+ */
+static bool equals(uintptr_t a, uintptr_t b)
+{
+ return a == b;
+}
+
+/**
+ * Update usage counter when a CHILD_SA rekeys/goes down
+ */
+static void update_usage(private_eap_radius_accounting_t *this,
+ ike_sa_t *ike_sa, child_sa_t *child_sa)
+{
+ u_int64_t sent, received;
+ entry_t *entry;
+
+ child_sa->get_usestats(child_sa, FALSE, NULL, &sent);
+ child_sa->get_usestats(child_sa, TRUE, NULL, &received);
+
+ this->mutex->lock(this->mutex);
+ entry = this->sessions->get(this->sessions,
+ (void*)(uintptr_t)ike_sa->get_unique_id(ike_sa));
+ if (entry)
+ {
+ entry->sent += sent;
+ entry->received += received;
+ }
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Send a RADIUS message, wait for response
+ */
+static bool send_message(private_eap_radius_accounting_t *this,
+ radius_message_t *request)
+{
+ radius_message_t *response;
+ radius_client_t *client;
+ bool ack = FALSE;
+
+ client = eap_radius_create_client();
+ if (client)
+ {
+ response = client->request(client, request);
+ if (response)
+ {
+ ack = response->get_code(response) == RMC_ACCOUNTING_RESPONSE;
+ response->destroy(response);
+ }
+ else
+ {
+ charon->bus->alert(charon->bus, ALERT_RADIUS_NOT_RESPONDING);
+ }
+ client->destroy(client);
+ }
+ return ack;
+}
+
+/**
+ * Add common IKE_SA parameters to RADIUS account message
+ */
+static void add_ike_sa_parameters(radius_message_t *message, ike_sa_t *ike_sa)
+{
+ host_t *vip;
+ char buf[64];
+ chunk_t data;
+
+ snprintf(buf, sizeof(buf), "%Y", ike_sa->get_other_eap_id(ike_sa));
+ message->add(message, RAT_USER_NAME, chunk_create(buf, strlen(buf)));
+ snprintf(buf, sizeof(buf), "%#H", ike_sa->get_other_host(ike_sa));
+ message->add(message, RAT_CALLING_STATION_ID, chunk_create(buf, strlen(buf)));
+ vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
+ if (vip && vip->get_family(vip) == AF_INET)
+ {
+ message->add(message, RAT_FRAMED_IP_ADDRESS, vip->get_address(vip));
+ }
+ if (vip && vip->get_family(vip) == AF_INET6)
+ {
+ /* we currently assign /128 prefixes, only (reserved, length) */
+ data = chunk_from_chars(0, 128);
+ data = chunk_cata("cc", data, vip->get_address(vip));
+ message->add(message, RAT_FRAMED_IPV6_PREFIX, data);
+ }
+}
+
+/**
+ * Send an accounting start message
+ */
+static void send_start(private_eap_radius_accounting_t *this, ike_sa_t *ike_sa)
+{
+ radius_message_t *message;
+ entry_t *entry;
+ u_int32_t id, value;
+
+ id = ike_sa->get_unique_id(ike_sa);
+ INIT(entry,
+ .created = time_monotonic(NULL),
+ );
+ snprintf(entry->sid, sizeof(entry->sid), "%u-%u", this->prefix, id);
+
+ message = radius_message_create(RMC_ACCOUNTING_REQUEST);
+ value = htonl(ACCT_STATUS_START);
+ message->add(message, RAT_ACCT_STATUS_TYPE, chunk_from_thing(value));
+ message->add(message, RAT_ACCT_SESSION_ID,
+ chunk_create(entry->sid, strlen(entry->sid)));
+ add_ike_sa_parameters(message, ike_sa);
+ if (send_message(this, message))
+ {
+ this->mutex->lock(this->mutex);
+ entry = this->sessions->put(this->sessions, (void*)(uintptr_t)id, entry);
+ this->mutex->unlock(this->mutex);
+ free(entry);
+ }
+ message->destroy(message);
+}
+
+/**
+ * Send an account stop message
+ */
+static void send_stop(private_eap_radius_accounting_t *this, ike_sa_t *ike_sa)
+{
+ radius_message_t *message;
+ entry_t *entry;
+ u_int32_t id, value;
+
+ id = ike_sa->get_unique_id(ike_sa);
+ this->mutex->lock(this->mutex);
+ entry = this->sessions->remove(this->sessions, (void*)(uintptr_t)id);
+ this->mutex->unlock(this->mutex);
+ if (entry)
+ {
+ message = radius_message_create(RMC_ACCOUNTING_REQUEST);
+ value = htonl(ACCT_STATUS_STOP);
+ message->add(message, RAT_ACCT_STATUS_TYPE, chunk_from_thing(value));
+ message->add(message, RAT_ACCT_SESSION_ID,
+ chunk_create(entry->sid, strlen(entry->sid)));
+ add_ike_sa_parameters(message, ike_sa);
+ value = htonl(entry->sent);
+ message->add(message, RAT_ACCT_OUTPUT_OCTETS, chunk_from_thing(value));
+ value = htonl(entry->sent >> 32);
+ if (value)
+ {
+ message->add(message, RAT_ACCT_OUTPUT_GIGAWORDS,
+ chunk_from_thing(value));
+ }
+ value = htonl(entry->received);
+ message->add(message, RAT_ACCT_INPUT_OCTETS, chunk_from_thing(value));
+ value = htonl(entry->received >> 32);
+ if (value)
+ {
+ message->add(message, RAT_ACCT_INPUT_GIGAWORDS,
+ chunk_from_thing(value));
+ }
+ value = htonl(time_monotonic(NULL) - entry->created);
+ message->add(message, RAT_ACCT_SESSION_TIME, chunk_from_thing(value));
+
+ send_message(this, message);
+ message->destroy(message);
+ free(entry);
+ }
+}
+
+METHOD(listener_t, ike_updown, bool,
+ private_eap_radius_accounting_t *this, ike_sa_t *ike_sa, bool up)
+{
+ if (!up)
+ {
+ enumerator_t *enumerator;
+ child_sa_t *child_sa;
+
+ /* update usage for all children just before sending stop */
+ enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (enumerator->enumerate(enumerator, &child_sa))
+ {
+ update_usage(this, ike_sa, child_sa);
+ }
+ enumerator->destroy(enumerator);
+
+ send_stop(this, ike_sa);
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, message_hook, bool,
+ private_eap_radius_accounting_t *this, ike_sa_t *ike_sa,
+ message_t *message, bool incoming)
+{
+ /* start accounting here, virtual IP now is set */
+ if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED &&
+ message->get_exchange_type(message) == IKE_AUTH &&
+ !incoming && !message->get_request(message))
+ {
+ send_start(this, ike_sa);
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, child_rekey, bool,
+ private_eap_radius_accounting_t *this, ike_sa_t *ike_sa,
+ child_sa_t *old, child_sa_t *new)
+{
+ update_usage(this, ike_sa, old);
+
+ return TRUE;
+}
+
+METHOD(listener_t, child_updown, bool,
+ private_eap_radius_accounting_t *this, ike_sa_t *ike_sa,
+ child_sa_t *child_sa, bool up)
+{
+ if (!up && ike_sa->get_state(ike_sa) == IKE_ESTABLISHED)
+ {
+ update_usage(this, ike_sa, child_sa);
+ }
+ return TRUE;
+}
+
+METHOD(eap_radius_accounting_t, destroy, void,
+ private_eap_radius_accounting_t *this)
+{
+ this->mutex->destroy(this->mutex);
+ this->sessions->destroy(this->sessions);
+ free(this);
+}
+
+/**
+ * See header
+ */
+eap_radius_accounting_t *eap_radius_accounting_create()
+{
+ private_eap_radius_accounting_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .ike_updown = _ike_updown,
+ .message = _message_hook,
+ .child_updown = _child_updown,
+ .child_rekey = _child_rekey,
+ },
+ .destroy = _destroy,
+ },
+ /* use system time as Session ID prefix */
+ .prefix = (u_int32_t)time(NULL),
+ .sessions = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 32),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.h b/src/libcharon/plugins/eap_radius/eap_radius_accounting.h
new file mode 100644
index 000000000..811a5bb90
--- /dev/null
+++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 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_radius_accounting eap_radius_accounting
+ * @{ @ingroup eap_radius
+ */
+
+#ifndef EAP_RADIUS_ACCOUNTING_H_
+#define EAP_RADIUS_ACCOUNTING_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct eap_radius_accounting_t eap_radius_accounting_t;
+
+/**
+ * RADIUS accounting for IKE/IPsec.
+ */
+struct eap_radius_accounting_t {
+
+ /**
+ * Implements listener_t.
+ */
+ listener_t listener;
+
+ /**
+ * Destroy a eap_radius_accounting_t.
+ */
+ void (*destroy)(eap_radius_accounting_t *this);
+};
+
+/**
+ * Create a eap_radius_accounting instance.
+ */
+eap_radius_accounting_t *eap_radius_accounting_create();
+
+#endif /** EAP_RADIUS_ACCOUNTING_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_dae.c b/src/libcharon/plugins/eap_radius/eap_radius_dae.c
new file mode 100644
index 000000000..e84fe5b9c
--- /dev/null
+++ b/src/libcharon/plugins/eap_radius/eap_radius_dae.c
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 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_radius_dae.h"
+
+#include <radius_message.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <daemon.h>
+#include <threading/thread.h>
+#include <processing/jobs/callback_job.h>
+#include <processing/jobs/delete_ike_sa_job.h>
+
+#define RADIUS_DAE_PORT 3799
+
+typedef struct private_eap_radius_dae_t private_eap_radius_dae_t;
+
+/**
+ * Private data of an eap_radius_dae_t object.
+ */
+struct private_eap_radius_dae_t {
+
+ /**
+ * Public eap_radius_dae_t interface.
+ */
+ eap_radius_dae_t public;
+
+ /**
+ * RADIUS session state
+ */
+ eap_radius_accounting_t *accounting;
+
+ /**
+ * Socket to listen on authorization extension port
+ */
+ int fd;
+
+ /**
+ * Listen job
+ */
+ callback_job_t *job;
+
+ /**
+ * RADIUS shared secret for DAE exchanges
+ */
+ chunk_t secret;
+
+ /**
+ * MD5 hasher
+ */
+ hasher_t *hasher;
+
+ /**
+ * HMAC MD5 signer, with secret set
+ */
+ signer_t *signer;
+
+ /**
+ * List of responses for retransmission, as entry_t
+ */
+ linked_list_t *responses;
+};
+
+/**
+ * Entry to store responses for retransmit
+ */
+typedef struct {
+ /** stored response */
+ radius_message_t *response;
+ /** client that sent the request */
+ host_t *client;
+} entry_t;
+
+/**
+ * Clean up an entry
+ */
+static void entry_destroy(entry_t *entry)
+{
+ entry->response->destroy(entry->response);
+ entry->client->destroy(entry->client);
+ free(entry);
+}
+
+/**
+ * Save/Replace response for retransmission
+ */
+static void save_retransmit(private_eap_radius_dae_t *this,
+ radius_message_t *response, host_t *client)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ bool found = FALSE;
+
+ enumerator = this->responses->create_enumerator(this->responses);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (client->equals(client, entry->client))
+ {
+ entry->response->destroy(entry->response);
+ entry->response = response;
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ INIT(entry,
+ .response = response,
+ .client = client->clone(client),
+ );
+ this->responses->insert_first(this->responses, entry);
+ }
+}
+
+/**
+ * Send a RADIUS message to client
+ */
+static void send_message(private_eap_radius_dae_t *this,
+ radius_message_t *message, host_t *client)
+{
+ chunk_t data;
+
+ data = message->get_encoding(message);
+ if (sendto(this->fd, data.ptr, data.len, 0, client->get_sockaddr(client),
+ *client->get_sockaddr_len(client)) != data.len)
+ {
+ DBG1(DBG_CFG, "sending RADIUS DAE response failed: %s", strerror(errno));
+ }
+}
+
+/**
+ * Check if we request is a retransmit, retransmit stored response
+ */
+static bool send_retransmit(private_eap_radius_dae_t *this,
+ radius_message_t *request, host_t *client)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ bool found = FALSE;
+
+ enumerator = this->responses->create_enumerator(this->responses);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (client->equals(client, entry->client) &&
+ request->get_identifier(request) ==
+ entry->response->get_identifier(entry->response))
+ {
+ DBG1(DBG_CFG, "received retransmit of RADIUS %N, retransmitting %N "
+ "to %H", radius_message_code_names, request->get_code(request),
+ radius_message_code_names,
+ entry->response->get_code(entry->response), client);
+ send_message(this, entry->response, client);
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
+/**
+ * Send an ACK/NAK response for a request
+ */
+static void send_response(private_eap_radius_dae_t *this,
+ radius_message_t *request, radius_message_code_t code,
+ host_t *client)
+{
+ radius_message_t *response;
+
+ response = radius_message_create(code);
+ response->set_identifier(response, request->get_identifier(request));
+ response->sign(response, request->get_authenticator(request),
+ this->secret, this->hasher, this->signer, NULL, FALSE);
+
+ send_message(this, response, client);
+ save_retransmit(this, response, client);
+}
+
+/**
+ * Add all IKE_SAs matching to user to a list
+ */
+static void add_matching_ike_sas(linked_list_t *list, identification_t *user)
+{
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ ike_sa_id_t *id;
+
+ enumerator = charon->ike_sa_manager->create_enumerator(
+ charon->ike_sa_manager, FALSE);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ if (user->matches(user, ike_sa->get_other_eap_id(ike_sa)))
+ {
+ id = ike_sa->get_id(ike_sa);
+ list->insert_last(list, id->clone(id));
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * Get list of IKE_SAs matching a Disconnect/CoA request
+ */
+static linked_list_t *get_matching_ike_sas(private_eap_radius_dae_t *this,
+ radius_message_t *request, host_t *client)
+{
+ enumerator_t *enumerator;
+ identification_t *user;
+ linked_list_t *ids;
+ chunk_t data;
+ int type;
+
+ ids = linked_list_create();
+
+ enumerator = request->create_enumerator(request);
+ while (enumerator->enumerate(enumerator, &type, &data))
+ {
+ if (type == RAT_USER_NAME && data.len)
+ {
+ user = identification_create_from_data(data);
+ DBG1(DBG_CFG, "received RADIUS DAE %N for %Y from %H",
+ radius_message_code_names, request->get_code(request),
+ user, client);
+ add_matching_ike_sas(ids, user);
+ user->destroy(user);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return ids;
+}
+
+/**
+ * Process a DAE disconnect request, send response
+ */
+static void process_disconnect(private_eap_radius_dae_t *this,
+ radius_message_t *request, host_t *client)
+{
+ enumerator_t *enumerator;
+ linked_list_t *ids;
+ ike_sa_id_t *id;
+
+ ids = get_matching_ike_sas(this, request, client);
+
+ if (ids->get_count(ids))
+ {
+ DBG1(DBG_CFG, "closing %d IKE_SA%s matching %N, sending %N",
+ ids->get_count(ids), ids->get_count(ids) > 1 ? "s" : "",
+ radius_message_code_names, RMC_DISCONNECT_REQUEST,
+ radius_message_code_names, RMC_DISCONNECT_ACK);
+
+ enumerator = ids->create_enumerator(ids);
+ while (enumerator->enumerate(enumerator, &id))
+ {
+ lib->processor->queue_job(lib->processor, (job_t*)
+ delete_ike_sa_job_create(id, TRUE));
+ }
+ enumerator->destroy(enumerator);
+
+ send_response(this, request, RMC_DISCONNECT_ACK, client);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "no IKE_SA matches %N, sending %N",
+ radius_message_code_names, RMC_DISCONNECT_REQUEST,
+ radius_message_code_names, RMC_DISCONNECT_NAK);
+ send_response(this, request, RMC_DISCONNECT_NAK, client);
+ }
+ ids->destroy_offset(ids, offsetof(ike_sa_id_t, destroy));
+}
+
+/**
+ * Apply a new lifetime to an IKE_SA
+ */
+static void apply_lifetime(private_eap_radius_dae_t *this, ike_sa_id_t *id,
+ u_int32_t lifetime)
+{
+ ike_sa_t *ike_sa;
+
+ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, id);
+ if (ike_sa)
+ {
+ if (ike_sa->set_auth_lifetime(ike_sa, lifetime) == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
+ ike_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ }
+ }
+}
+
+/**
+ * Process a DAE CoA request, send response
+ */
+static void process_coa(private_eap_radius_dae_t *this,
+ radius_message_t *request, host_t *client)
+{
+ enumerator_t *enumerator;
+ linked_list_t *ids;
+ ike_sa_id_t *id;
+ chunk_t data;
+ int type;
+ u_int32_t lifetime = 0;
+ bool lifetime_seen = FALSE;
+
+ ids = get_matching_ike_sas(this, request, client);
+
+ if (ids->get_count(ids))
+ {
+ enumerator = request->create_enumerator(request);
+ while (enumerator->enumerate(enumerator, &type, &data))
+ {
+ if (type == RAT_SESSION_TIMEOUT && data.len == 4)
+ {
+ lifetime = untoh32(data.ptr);
+ lifetime_seen = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (lifetime_seen)
+ {
+ DBG1(DBG_CFG, "applying %us lifetime to %d IKE_SA%s matching %N, "
+ "sending %N", lifetime, ids->get_count(ids),
+ ids->get_count(ids) > 1 ? "s" : "",
+ radius_message_code_names, RMC_COA_REQUEST,
+ radius_message_code_names, RMC_COA_ACK);
+
+ enumerator = ids->create_enumerator(ids);
+ while (enumerator->enumerate(enumerator, &id))
+ {
+ apply_lifetime(this, id, lifetime);
+ }
+ enumerator->destroy(enumerator);
+ send_response(this, request, RMC_COA_ACK, client);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "no Session-Timeout attribute found in %N, sending %N",
+ radius_message_code_names, RMC_COA_REQUEST,
+ radius_message_code_names, RMC_COA_NAK);
+ send_response(this, request, RMC_COA_NAK, client);
+ }
+ }
+ else
+ {
+ DBG1(DBG_CFG, "no IKE_SA matches %N, sending %N",
+ radius_message_code_names, RMC_COA_REQUEST,
+ radius_message_code_names, RMC_COA_NAK);
+ send_response(this, request, RMC_COA_NAK, client);
+ }
+ ids->destroy_offset(ids, offsetof(ike_sa_id_t, destroy));
+}
+
+/**
+ * Receive RADIUS DAE requests
+ */
+static job_requeue_t receive(private_eap_radius_dae_t *this)
+{
+ struct sockaddr_storage addr;
+ socklen_t addr_len = sizeof(addr);
+ radius_message_t *request;
+ char buf[2048];
+ ssize_t len;
+ bool oldstate;
+ host_t *client;
+
+ oldstate = thread_cancelability(TRUE);
+ len = recvfrom(this->fd, buf, sizeof(buf), 0,
+ (struct sockaddr*)&addr, &addr_len);
+ thread_cancelability(oldstate);
+
+ if (len > 0)
+ {
+ request = radius_message_parse(chunk_create(buf, len));
+ if (request)
+ {
+ client = host_create_from_sockaddr((struct sockaddr*)&addr);
+ if (client)
+ {
+ if (!send_retransmit(this, request, client))
+ {
+ if (request->verify(request, NULL, this->secret,
+ this->hasher, this->signer))
+ {
+ switch (request->get_code(request))
+ {
+ case RMC_DISCONNECT_REQUEST:
+ process_disconnect(this, request, client);
+ break;
+ case RMC_COA_REQUEST:
+ process_coa(this, request, client);
+ break;
+ default:
+ DBG1(DBG_CFG, "ignoring unsupported RADIUS DAE "
+ "%N message from %H",
+ radius_message_code_names,
+ request->get_code(request), client);
+ break;
+ }
+ }
+ }
+ client->destroy(client);
+ }
+ request->destroy(request);
+ }
+ else
+ {
+ DBG1(DBG_NET, "ignoring invalid RADIUS DAE request");
+ }
+ }
+ else
+ {
+ DBG1(DBG_NET, "receiving RADIUS DAE request failed: %s", strerror(errno));
+ }
+ return JOB_REQUEUE_DIRECT;
+}
+
+/**
+ * Open DAE socket
+ */
+static bool open_socket(private_eap_radius_dae_t *this)
+{
+ host_t *host;
+
+ this->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (this->fd == -1)
+ {
+ DBG1(DBG_CFG, "unable to open RADIUS DAE socket: %s", strerror(errno));
+ return FALSE;
+ }
+
+ host = host_create_from_string(
+ lib->settings->get_str(lib->settings,
+ "charon.plugins.eap-radius.dae.listen", "0.0.0.0"),
+ lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-radius.dae.port", RADIUS_DAE_PORT));
+ if (!host)
+ {
+ DBG1(DBG_CFG, "invalid RADIUS DAE listen address");
+ return FALSE;
+ }
+
+ if (bind(this->fd, host->get_sockaddr(host),
+ *host->get_sockaddr_len(host)) == -1)
+ {
+ DBG1(DBG_CFG, "unable to bind RADIUS DAE socket: %s", strerror(errno));
+ host->destroy(host);
+ return FALSE;
+ }
+ host->destroy(host);
+ return TRUE;
+}
+
+METHOD(eap_radius_dae_t, destroy, void,
+ private_eap_radius_dae_t *this)
+{
+ if (this->job)
+ {
+ this->job->cancel(this->job);
+ }
+ if (this->fd != -1)
+ {
+ close(this->fd);
+ }
+ DESTROY_IF(this->signer);
+ DESTROY_IF(this->hasher);
+ this->responses->destroy_function(this->responses, (void*)entry_destroy);
+ free(this);
+}
+
+/**
+ * See header
+ */
+eap_radius_dae_t *eap_radius_dae_create(eap_radius_accounting_t *accounting)
+{
+ private_eap_radius_dae_t *this;
+
+ INIT(this,
+ .public = {
+ .destroy = _destroy,
+ },
+ .accounting = accounting,
+ .fd = -1,
+ .secret = {
+ .ptr = lib->settings->get_str(lib->settings,
+ "charon.plugins.eap-radius.dae.secret", NULL),
+ },
+ .hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5),
+ .signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_MD5_128),
+ .responses = linked_list_create(),
+ );
+
+ if (!this->hasher || !this->signer)
+ {
+ destroy(this);
+ return NULL;
+ }
+ if (!this->secret.ptr)
+ {
+ DBG1(DBG_CFG, "missing RADIUS DAE secret, disabled");
+ destroy(this);
+ return NULL;
+ }
+ this->secret.len = strlen(this->secret.ptr);
+ this->signer->set_key(this->signer, this->secret);
+
+ if (!open_socket(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_dae.h b/src/libcharon/plugins/eap_radius/eap_radius_dae.h
new file mode 100644
index 000000000..759eadb49
--- /dev/null
+++ b/src/libcharon/plugins/eap_radius/eap_radius_dae.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 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_radius_dae eap_radius_dae
+ * @{ @ingroup eap_radius
+ */
+
+#ifndef EAP_RADIUS_DAE_H_
+#define EAP_RADIUS_DAE_H_
+
+#include "eap_radius_accounting.h"
+
+typedef struct eap_radius_dae_t eap_radius_dae_t;
+
+/**
+ * Dynamic Authorization Extensions (RFC 5176) for EAP-RADIUS.
+ */
+struct eap_radius_dae_t {
+
+ /**
+ * Destroy a eap_radius_dae_t.
+ */
+ void (*destroy)(eap_radius_dae_t *this);
+};
+
+/**
+ * Create a eap_radius_dae instance.
+ */
+eap_radius_dae_t *eap_radius_dae_create(eap_radius_accounting_t *accounting);
+
+#endif /** EAP_RADIUS_DAE_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_forward.c b/src/libcharon/plugins/eap_radius/eap_radius_forward.c
new file mode 100644
index 000000000..cb4ca74e3
--- /dev/null
+++ b/src/libcharon/plugins/eap_radius/eap_radius_forward.c
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 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_radius_forward.h"
+
+#include <daemon.h>
+#include <utils/linked_list.h>
+#include <utils/hashtable.h>
+#include <threading/mutex.h>
+
+typedef struct private_eap_radius_forward_t private_eap_radius_forward_t;
+
+/**
+ * Private data of an eap_radius_forward_t object.
+ */
+struct private_eap_radius_forward_t {
+
+ /**
+ * Public eap_radius_forward_t interface.
+ */
+ eap_radius_forward_t public;
+
+ /**
+ * List of attribute types to copy from IKE, as attr_t
+ */
+ linked_list_t *from_attr;
+
+ /**
+ * List of attribute types to copy to IKE, as attr_t
+ */
+ linked_list_t *to_attr;
+
+ /**
+ * Queued to forward from IKE, unique_id => linked_list_t of chunk_t
+ */
+ hashtable_t *from;
+
+ /**
+ * Queued to forward to IKE, unique_id => linked_list_t of chunk_t
+ */
+ hashtable_t *to;
+
+ /**
+ * Mutex to lock concurrent access to hashtables
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * RADIUS attribute selector
+ */
+typedef struct {
+ /** vendor ID, 0 for standard attributes */
+ u_int32_t vendor;
+ /** attribute type */
+ u_int8_t type;
+} attr_t;
+
+/**
+ * Single instance of this
+ */
+static private_eap_radius_forward_t *singleton = NULL;
+
+/**
+ * Hashtable hash function
+ */
+static u_int hash(uintptr_t key)
+{
+ return key;
+}
+
+/**
+ * Hashtable equals function
+ */
+static bool equals(uintptr_t a, uintptr_t b)
+{
+ return a == b;
+}
+
+/**
+ * Free a queue entry
+ */
+static void free_attribute(chunk_t *chunk)
+{
+ free(chunk->ptr);
+ free(chunk);
+}
+
+/**
+ * Lookup/create an attribute queue from a table
+ */
+static linked_list_t *lookup_queue(private_eap_radius_forward_t *this,
+ hashtable_t *table)
+{
+ linked_list_t *queue = NULL;
+ ike_sa_t *ike_sa;
+ uintptr_t id;
+
+ ike_sa = charon->bus->get_sa(charon->bus);
+ if (ike_sa && ike_sa->supports_extension(ike_sa, EXT_STRONGSWAN))
+ {
+ id = ike_sa->get_unique_id(ike_sa);
+ this->mutex->lock(this->mutex);
+ queue = table->get(table, (void*)id);
+ if (!queue)
+ {
+ queue = linked_list_create();
+ table->put(table, (void*)id, queue);
+ }
+ this->mutex->unlock(this->mutex);
+ }
+ return queue;
+}
+
+/**
+ * Remove attribute queue from table
+ */
+static void remove_queue(private_eap_radius_forward_t *this,
+ hashtable_t *table, ike_sa_t *ike_sa)
+{
+ linked_list_t *queue;
+
+ this->mutex->lock(this->mutex);
+ queue = table->remove(table, (void*)(uintptr_t)ike_sa->get_unique_id(ike_sa));
+ this->mutex->unlock(this->mutex);
+ if (queue)
+ {
+ queue->destroy_function(queue, (void*)free_attribute);
+ }
+}
+
+/**
+ * Check if RADIUS attribute is contained in selector
+ */
+static bool is_attribute_selected(linked_list_t *selector,
+ radius_attribute_type_t type, chunk_t data)
+{
+ enumerator_t *enumerator;
+ u_int32_t vendor = 0;
+ attr_t *sel;
+ bool found = FALSE;
+
+ if (type == RAT_VENDOR_SPECIFIC)
+ {
+ if (data.len < 4)
+ {
+ return FALSE;
+ }
+ vendor = untoh32(data.ptr);
+ }
+ enumerator = selector->create_enumerator(selector);
+ while (!found && enumerator->enumerate(enumerator, &sel))
+ {
+ if (sel->vendor == vendor)
+ {
+ if (vendor)
+ {
+ if (sel->type == 0)
+ { /* any of that vendor is fine */
+ found = TRUE;
+ }
+ else if (data.len > 4 && data.ptr[4] == sel->type)
+ { /* vendor specific type field, as defined in RFC 2865 */
+ found = TRUE;
+ }
+ }
+ else
+ {
+ if (sel->type == type)
+ {
+ found = TRUE;
+ }
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
+/**
+ * Copy RADIUS attributes from queue to a RADIUS message
+ */
+static void queue2radius(linked_list_t *queue, radius_message_t *message)
+{
+ chunk_t *data;
+
+ while (queue->remove_last(queue, (void**)&data) == SUCCESS)
+ {
+ if (data->len >= 2)
+ {
+ message->add(message, data->ptr[0], chunk_skip(*data, 2));
+ }
+ free_attribute(data);
+ }
+}
+
+/**
+ * Copy RADIUS attributes from a RADIUS message to the queue
+ */
+static void radius2queue(radius_message_t *message, linked_list_t *queue,
+ linked_list_t *selector)
+{
+ enumerator_t *enumerator;
+ int type;
+ chunk_t data, hdr, *ptr;
+
+ enumerator = message->create_enumerator(message);
+ while (enumerator->enumerate(enumerator, &type, &data))
+ {
+ if (is_attribute_selected(selector, type, data))
+ {
+ hdr = chunk_alloc(2);
+ hdr.ptr[0] = type;
+ hdr.ptr[1] = data.len + 2;
+
+ INIT(ptr);
+ *ptr = chunk_cat("mc", hdr, data);
+ queue->insert_last(queue, ptr);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * Copy RADIUS attribute nofifies from IKE message to queue
+ */
+static void ike2queue(message_t *message, linked_list_t *queue,
+ linked_list_t *selector)
+{
+ enumerator_t *enumerator;
+ payload_t *payload;
+ notify_payload_t *notify;
+ chunk_t data, *ptr;
+
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
+ {
+ if (payload->get_type(payload) == NOTIFY)
+ {
+ notify = (notify_payload_t*)payload;
+ if (notify->get_notify_type(notify) == RADIUS_ATTRIBUTE)
+ {
+ data = notify->get_notification_data(notify);
+ if (data.len >= 2 && is_attribute_selected(selector,
+ data.ptr[0], chunk_skip(data, 2)))
+ {
+ INIT(ptr);
+ *ptr = chunk_clone(data);
+ queue->insert_last(queue, ptr);
+ }
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * Copy RADUIS attributes from queue to IKE message notifies
+ */
+static void queue2ike(linked_list_t *queue, message_t *message)
+{
+ chunk_t *data;
+
+ while (queue->remove_last(queue, (void**)&data) == SUCCESS)
+ {
+ message->add_notify(message, FALSE, RADIUS_ATTRIBUTE, *data);
+ free_attribute(data);
+ }
+}
+
+/**
+ * See header.
+ */
+void eap_radius_forward_from_ike(radius_message_t *request)
+{
+ private_eap_radius_forward_t *this = singleton;
+ linked_list_t *queue;
+
+ if (this)
+ {
+ queue = lookup_queue(this, this->from);
+ if (queue)
+ {
+ queue2radius(queue, request);
+ }
+ }
+}
+
+/**
+ * See header.
+ */
+void eap_radius_forward_to_ike(radius_message_t *response)
+{
+ private_eap_radius_forward_t *this = singleton;
+ linked_list_t *queue;
+
+ if (this)
+ {
+ queue = lookup_queue(this, this->to);
+ if (queue)
+ {
+ radius2queue(response, queue, this->to_attr);
+ }
+ }
+}
+
+METHOD(listener_t, message, bool,
+ private_eap_radius_forward_t *this,
+ ike_sa_t *ike_sa, message_t *message, bool incoming)
+{
+ linked_list_t *queue;
+
+ if (message->get_exchange_type(message) == IKE_AUTH)
+ {
+ if (incoming)
+ {
+ queue = lookup_queue(this, this->from);
+ if (queue)
+ {
+ ike2queue(message, queue, this->from_attr);
+ }
+ }
+ else
+ {
+ queue = lookup_queue(this, this->to);
+ if (queue)
+ {
+ queue2ike(queue, message);
+ }
+ }
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, ike_updown, bool,
+ private_eap_radius_forward_t *this, ike_sa_t *ike_sa, bool up)
+{
+ /* up or down, we don't need the state anymore */
+ remove_queue(this, this->from, ike_sa);
+ remove_queue(this, this->to, ike_sa);
+ return TRUE;
+}
+
+/**
+ * Parse a selector string to a list of attr_t selectors
+ */
+static linked_list_t* parse_selector(char *selector)
+{
+ enumerator_t *enumerator;
+ linked_list_t *list;
+ char *token, *pos;
+
+ list = linked_list_create();
+ enumerator = enumerator_create_token(selector, ",", " ");
+ while (enumerator->enumerate(enumerator, &token))
+ {
+ int type, vendor = 0;
+ attr_t *attr;
+
+ pos = strchr(token, ':');
+ if (pos)
+ {
+ *(pos++) = 0;
+ vendor = atoi(token);
+ token = pos;
+ }
+ type = enum_from_name(radius_attribute_type_names, token);
+ if (type == -1)
+ {
+ type = atoi(token);
+ }
+ if (vendor == 0 && type == 0)
+ {
+ DBG1(DBG_CFG, "ignoring unknown RADIUS attribute type '%s'", token);
+ }
+ else
+ {
+ INIT(attr,
+ .type = type,
+ .vendor = vendor,
+ );
+ list->insert_last(list, attr);
+ if (!vendor)
+ {
+ DBG1(DBG_IKE, "forwarding RADIUS attribute %N",
+ radius_attribute_type_names, type);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "forwarding RADIUS VSA %d-%d", vendor, type);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ return list;
+}
+
+METHOD(eap_radius_forward_t, destroy, void,
+ private_eap_radius_forward_t *this)
+{
+ this->from_attr->destroy_function(this->from_attr, free);
+ this->to_attr->destroy_function(this->to_attr, free);
+ this->from->destroy(this->from);
+ this->to->destroy(this->to);
+ this->mutex->destroy(this->mutex);
+ free(this);
+ singleton = NULL;
+}
+
+/**
+ * See header
+ */
+eap_radius_forward_t *eap_radius_forward_create()
+{
+ private_eap_radius_forward_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .message = _message,
+ .ike_updown = _ike_updown,
+ },
+ .destroy = _destroy,
+ },
+ .from_attr = parse_selector(lib->settings->get_str(lib->settings,
+ "charon.plugins.eap-radius.forward.ike_to_radius", "")),
+ .to_attr = parse_selector(lib->settings->get_str(lib->settings,
+ "charon.plugins.eap-radius.forward.radius_to_ike", "")),
+ .from = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 8),
+ .to = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 8),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ );
+
+ if (this->from_attr->get_count(this->from_attr) == 0 &&
+ this->to_attr->get_count(this->to_attr) == 0)
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ singleton = this;
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_forward.h b/src/libcharon/plugins/eap_radius/eap_radius_forward.h
new file mode 100644
index 000000000..2c1dbf7a8
--- /dev/null
+++ b/src/libcharon/plugins/eap_radius/eap_radius_forward.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 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_radius_forward eap_radius_forward
+ * @{ @ingroup eap_radius
+ */
+
+#ifndef EAP_RADIUS_FORWARD_H_
+#define EAP_RADIUS_FORWARD_H_
+
+#include <radius_message.h>
+
+#include <bus/listeners/listener.h>
+
+typedef struct eap_radius_forward_t eap_radius_forward_t;
+
+/**
+ * Forward RADIUS attributes in Notifies between client and AAA backend.
+ */
+struct eap_radius_forward_t {
+
+ /**
+ * Implements a listener.
+ */
+ listener_t listener;
+
+ /**
+ * Destroy a eap_radius_forward_t.
+ */
+ void (*destroy)(eap_radius_forward_t *this);
+};
+
+/**
+ * Create a eap_radius_forward instance.
+ */
+eap_radius_forward_t *eap_radius_forward_create();
+
+/**
+ * Forward RADIUS attributes from IKE notifies to a RADIUS request.
+ *
+ * @param request RADIUS request message to add attributes to
+ */
+void eap_radius_forward_from_ike(radius_message_t *request);
+
+/**
+ * Forward RADIUS attributes from a RADIUS response to IKE notifies.
+ *
+ * @param response RADIUS respose to read notifies from
+ */
+void eap_radius_forward_to_ike(radius_message_t *response);
+
+#endif /** EAP_RADIUS_FORWARD_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
index c218bd48b..8ee0ab81a 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
@@ -16,16 +16,25 @@
#include "eap_radius_plugin.h"
#include "eap_radius.h"
-#include "radius_client.h"
-#include "radius_server.h"
+#include "eap_radius_accounting.h"
+#include "eap_radius_dae.h"
+#include "eap_radius_forward.h"
+
+#include <radius_client.h>
+#include <radius_config.h>
#include <daemon.h>
#include <threading/rwlock.h>
/**
- * Default RADIUS server port, when not configured
+ * Default RADIUS server port for authentication
*/
-#define RADIUS_PORT 1812
+#define AUTH_PORT 1812
+
+/**
+ * Default RADIUS server port for accounting
+ */
+#define ACCT_PORT 1813
typedef struct private_eap_radius_plugin_t private_eap_radius_plugin_t;
@@ -40,14 +49,29 @@ struct private_eap_radius_plugin_t {
eap_radius_plugin_t public;
/**
- * List of RADIUS servers
+ * List of RADIUS server configurations
*/
- linked_list_t *servers;
+ linked_list_t *configs;
/**
- * Lock for server list
+ * Lock for configs list
*/
rwlock_t *lock;
+
+ /**
+ * RADIUS sessions for accounting
+ */
+ eap_radius_accounting_t *accounting;
+
+ /**
+ * Dynamic authorization extensions
+ */
+ eap_radius_dae_t *dae;
+
+ /**
+ * RADIUS <-> IKE attribute forwarding
+ */
+ eap_radius_forward_t *forward;
};
/**
@@ -58,12 +82,12 @@ static private_eap_radius_plugin_t *instance = NULL;
/**
* Load RADIUS servers from configuration
*/
-static void load_servers(private_eap_radius_plugin_t *this)
+static void load_configs(private_eap_radius_plugin_t *this)
{
enumerator_t *enumerator;
- radius_server_t *server;
+ radius_config_t *config;
char *nas_identifier, *secret, *address, *section;
- int port, sockets, preference;
+ int auth_port, acct_port, sockets, preference;
address = lib->settings->get_str(lib->settings,
"charon.plugins.eap-radius.server", NULL);
@@ -78,18 +102,18 @@ static void load_servers(private_eap_radius_plugin_t *this)
}
nas_identifier = lib->settings->get_str(lib->settings,
"charon.plugins.eap-radius.nas_identifier", "strongSwan");
- port = lib->settings->get_int(lib->settings,
- "charon.plugins.eap-radius.port", RADIUS_PORT);
+ auth_port = lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-radius.port", AUTH_PORT);
sockets = lib->settings->get_int(lib->settings,
"charon.plugins.eap-radius.sockets", 1);
- server = radius_server_create(address, address, port, nas_identifier,
- secret, sockets, 0);
- if (!server)
+ config = radius_config_create(address, address, auth_port, ACCT_PORT,
+ nas_identifier, secret, sockets, 0);
+ if (!config)
{
DBG1(DBG_CFG, "no RADUIS server defined");
return;
}
- this->servers->insert_last(this->servers, server);
+ this->configs->insert_last(this->configs, config);
return;
}
@@ -114,26 +138,32 @@ static void load_servers(private_eap_radius_plugin_t *this)
nas_identifier = lib->settings->get_str(lib->settings,
"charon.plugins.eap-radius.servers.%s.nas_identifier",
"strongSwan", section);
- port = lib->settings->get_int(lib->settings,
- "charon.plugins.eap-radius.servers.%s.port", RADIUS_PORT, section);
+ auth_port = lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-radius.servers.%s.auth_port",
+ lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-radius.servers.%s.port",
+ AUTH_PORT, section),
+ section);
+ acct_port = lib->settings->get_int(lib->settings,
+ "charon.plugins.eap-radius.servers.%s.acct_port", ACCT_PORT, section);
sockets = lib->settings->get_int(lib->settings,
"charon.plugins.eap-radius.servers.%s.sockets", 1, section);
preference = lib->settings->get_int(lib->settings,
"charon.plugins.eap-radius.servers.%s.preference", 0, section);
- server = radius_server_create(section, address, port, nas_identifier,
- secret, sockets, preference);
- if (!server)
+ config = radius_config_create(section, address, auth_port, acct_port,
+ nas_identifier, secret, sockets, preference);
+ if (!config)
{
DBG1(DBG_CFG, "loading RADIUS server '%s' failed, skipped", section);
continue;
}
- this->servers->insert_last(this->servers, server);
+ this->configs->insert_last(this->configs, config);
}
enumerator->destroy(enumerator);
DBG1(DBG_CFG, "loaded %d RADIUS server configuration%s",
- this->servers->get_count(this->servers),
- this->servers->get_count(this->servers) == 1 ? "" : "s");
+ this->configs->get_count(this->configs),
+ this->configs->get_count(this->configs) == 1 ? "" : "s");
}
METHOD(plugin_t, get_name, char*,
@@ -142,14 +172,28 @@ METHOD(plugin_t, get_name, char*,
return "eap-radius";
}
+METHOD(plugin_t, get_features, int,
+ eap_radius_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(eap_method_register, eap_radius_create),
+ PLUGIN_PROVIDE(EAP_SERVER, EAP_RADIUS),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_MD5_128),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, reload, bool,
private_eap_radius_plugin_t *this)
{
this->lock->write_lock(this->lock);
- this->servers->destroy_offset(this->servers,
- offsetof(radius_server_t, destroy));
- this->servers = linked_list_create();
- load_servers(this);
+ this->configs->destroy_offset(this->configs,
+ offsetof(radius_config_t, destroy));
+ this->configs = linked_list_create();
+ load_configs(this);
this->lock->unlock(this->lock);
return TRUE;
}
@@ -157,10 +201,17 @@ METHOD(plugin_t, reload, bool,
METHOD(plugin_t, destroy, void,
private_eap_radius_plugin_t *this)
{
- charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_radius_create);
- this->servers->destroy_offset(this->servers,
- offsetof(radius_server_t, destroy));
+ if (this->forward)
+ {
+ charon->bus->remove_listener(charon->bus, &this->forward->listener);
+ this->forward->destroy(this->forward);
+ }
+ DESTROY_IF(this->dae);
+ this->configs->destroy_offset(this->configs,
+ offsetof(radius_config_t, destroy));
this->lock->destroy(this->lock);
+ charon->bus->remove_listener(charon->bus, &this->accounting->listener);
+ this->accounting->destroy(this->accounting);
free(this);
instance = NULL;
}
@@ -176,36 +227,78 @@ plugin_t *eap_radius_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
+ .get_features = _get_features,
.reload = _reload,
.destroy = _destroy,
},
},
- .servers = linked_list_create(),
+ .configs = linked_list_create(),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ .accounting = eap_radius_accounting_create(),
+ .forward = eap_radius_forward_create(),
);
- load_servers(this);
-
- charon->eap->add_method(charon->eap, EAP_RADIUS, 0,
- EAP_SERVER, (eap_constructor_t)eap_radius_create);
-
+ load_configs(this);
instance = this;
+ if (lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-radius.accounting", FALSE))
+ {
+ charon->bus->add_listener(charon->bus, &this->accounting->listener);
+ }
+ if (lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-radius.dae.enable", FALSE))
+ {
+ this->dae = eap_radius_dae_create(this->accounting);
+ }
+ if (this->forward)
+ {
+ charon->bus->add_listener(charon->bus, &this->forward->listener);
+ }
+
return &this->public.plugin;
}
/**
* See header
*/
-enumerator_t *eap_radius_create_server_enumerator()
+radius_client_t *eap_radius_create_client()
{
if (instance)
{
+ enumerator_t *enumerator;
+ radius_config_t *config, *selected = NULL;
+ int current, best = -1;
+
instance->lock->read_lock(instance->lock);
- return enumerator_create_cleaner(
- instance->servers->create_enumerator(instance->servers),
- (void*)instance->lock->unlock, instance->lock);
+ enumerator = instance->configs->create_enumerator(instance->configs);
+ while (enumerator->enumerate(enumerator, &config))
+ {
+ current = config->get_preference(config);
+ if (current > best ||
+ /* for two with equal preference, 50-50 chance */
+ (current == best && random() % 2 == 0))
+ {
+ DBG2(DBG_CFG, "RADIUS server '%s' is candidate: %d",
+ config->get_name(config), current);
+ best = current;
+ DESTROY_IF(selected);
+ selected = config->get_ref(config);
+ }
+ else
+ {
+ DBG2(DBG_CFG, "RADIUS server '%s' skipped: %d",
+ config->get_name(config), current);
+ }
+ }
+ enumerator->destroy(enumerator);
+ instance->lock->unlock(instance->lock);
+
+ if (selected)
+ {
+ return radius_client_create(selected);
+ }
}
- return enumerator_create_empty();
+ return NULL;
}
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.h b/src/libcharon/plugins/eap_radius/eap_radius_plugin.h
index cb724364a..1570bd566 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.h
+++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.h
@@ -25,7 +25,8 @@
#define EAP_RADIUS_PLUGIN_H_
#include <plugins/plugin.h>
-#include <utils/enumerator.h>
+
+#include <radius_client.h>
typedef struct eap_radius_plugin_t eap_radius_plugin_t;
@@ -44,10 +45,10 @@ struct eap_radius_plugin_t {
};
/**
- * Create an enumerator over all loaded RADIUS servers.
+ * Get a RADIUS client instance to connect to servers.
*
- * @return enumerator over radius_server_t
+ * @return RADIUS client
*/
-enumerator_t *eap_radius_create_server_enumerator();
+radius_client_t *eap_radius_create_client();
#endif /** EAP_RADIUS_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in
index b9ab6656b..d06929522 100644
--- a/src/libcharon/plugins/eap_sim/Makefile.in
+++ b/src/libcharon/plugins/eap_sim/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/eap_sim/eap_sim_peer.c b/src/libcharon/plugins/eap_sim/eap_sim_peer.c
index 083bf73a3..1d1ab99e0 100644
--- a/src/libcharon/plugins/eap_sim/eap_sim_peer.c
+++ b/src/libcharon/plugins/eap_sim/eap_sim_peer.c
@@ -18,6 +18,7 @@
#include <daemon.h>
#include <simaka_message.h>
+#include <simaka_manager.h>
/* number of tries we do authenticate */
#define MAX_TRIES 3
@@ -41,6 +42,11 @@ struct private_eap_sim_peer_t {
eap_sim_peer_t public;
/**
+ * SIM backend manager
+ */
+ simaka_manager_t *mgr;
+
+ /**
* permanent ID of peer
*/
identification_t *permanent;
@@ -116,7 +122,7 @@ static eap_payload_t* create_client_error(private_eap_sim_peer_t *this,
encoded = htons(code);
message->add_attribute(message, AT_CLIENT_ERROR_CODE,
chunk_create((char*)&encoded, sizeof(encoded)));
- out = message->generate(message, chunk_empty);
+ out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
return out;
}
@@ -188,7 +194,7 @@ static status_t process_start(private_eap_sim_peer_t *this,
switch (id_req)
{
case AT_ANY_ID_REQ:
- this->reauth = charon->sim->card_get_reauth(charon->sim,
+ this->reauth = this->mgr->card_get_reauth(this->mgr,
this->permanent, this->mk, &this->counter);
if (this->reauth)
{
@@ -197,8 +203,8 @@ static status_t process_start(private_eap_sim_peer_t *this,
}
/* FALL */
case AT_FULLAUTH_ID_REQ:
- this->pseudonym = charon->sim->card_get_pseudonym(charon->sim,
- this->permanent);
+ this->pseudonym = this->mgr->card_get_pseudonym(this->mgr,
+ this->permanent);
if (this->pseudonym)
{
id = this->pseudonym->get_encoding(this->pseudonym);
@@ -228,7 +234,7 @@ static status_t process_start(private_eap_sim_peer_t *this,
{
message->add_attribute(message, AT_IDENTITY, id);
}
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
return NEED_MORE;
@@ -287,8 +293,8 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
sreses = sres = chunk_alloca(rands.len / 4);
while (rands.len >= SIM_RAND_LEN)
{
- if (!charon->sim->card_get_triplet(charon->sim, this->permanent,
- rands.ptr, sres.ptr, kc.ptr))
+ if (!this->mgr->card_get_triplet(this->mgr, this->permanent,
+ rands.ptr, sres.ptr, kc.ptr))
{
DBG1(DBG_IKE, "unable to get EAP-SIM triplet");
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
@@ -328,13 +334,13 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
case AT_NEXT_REAUTH_ID:
this->counter = 0;
id = identification_create_from_data(data);
- charon->sim->card_set_reauth(charon->sim, this->permanent, id,
- this->mk, this->counter);
+ this->mgr->card_set_reauth(this->mgr, this->permanent, id,
+ this->mk, this->counter);
id->destroy(id);
break;
case AT_NEXT_PSEUDONYM:
id = identification_create_from_data(data);
- charon->sim->card_set_pseudonym(charon->sim, this->permanent, id);
+ this->mgr->card_set_pseudonym(this->mgr, this->permanent, id);
id->destroy(id);
break;
default:
@@ -346,7 +352,7 @@ static status_t process_challenge(private_eap_sim_peer_t *this,
/* build response with AT_MAC, built over "EAP packet | n*SRES" */
message = simaka_message_create(FALSE, this->identifier, EAP_SIM,
SIM_CHALLENGE, this->crypto);
- *out = message->generate(message, sreses);
+ *out = eap_payload_create_data_own(message->generate(message, sreses));
message->destroy(message);
return NEED_MORE;
}
@@ -443,13 +449,13 @@ static status_t process_reauthentication(private_eap_sim_peer_t *this,
identification_t *reauth;
reauth = identification_create_from_data(data);
- charon->sim->card_set_reauth(charon->sim, this->permanent, reauth,
- this->mk, this->counter);
+ this->mgr->card_set_reauth(this->mgr, this->permanent, reauth,
+ this->mk, this->counter);
reauth->destroy(reauth);
}
}
message->add_attribute(message, AT_COUNTER, counter);
- *out = message->generate(message, nonce);
+ *out = eap_payload_create_data_own(message->generate(message, nonce));
message->destroy(message);
return NEED_MORE;
}
@@ -500,7 +506,8 @@ static status_t process_notification(private_eap_sim_peer_t *this,
{ /* empty notification reply */
message = simaka_message_create(FALSE, this->identifier, EAP_SIM,
SIM_NOTIFICATION, this->crypto);
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message,
+ chunk_empty));
message->destroy(message);
}
else
@@ -519,7 +526,7 @@ METHOD(eap_method_t, process, status_t,
/* store received EAP message identifier */
this->identifier = in->get_identifier(in);
- message = simaka_message_create_from_payload(in, this->crypto);
+ message = simaka_message_create_from_payload(in->get_data(in), this->crypto);
if (!message)
{
*out = create_client_error(this, SIM_UNABLE_TO_PROCESS);
@@ -633,7 +640,8 @@ eap_sim_peer_t *eap_sim_peer_create(identification_t *server,
.destroy = _destroy,
},
},
- .crypto = simaka_crypto_create(),
+ .crypto = simaka_crypto_create(EAP_SIM),
+ .mgr = lib->get(lib, "sim-manager"),
);
if (!this->crypto)
diff --git a/src/libcharon/plugins/eap_sim/eap_sim_peer.h b/src/libcharon/plugins/eap_sim/eap_sim_peer.h
index 89f81301e..ba72ce484 100644
--- a/src/libcharon/plugins/eap_sim/eap_sim_peer.h
+++ b/src/libcharon/plugins/eap_sim/eap_sim_peer.h
@@ -27,9 +27,6 @@ typedef struct eap_sim_peer_t eap_sim_peer_t;
/**
* EAP-SIM peer implementation.
- *
- * This EAP-SIM module uses sim_card_t implementations for triplet calculation,
- * found via the eap_sim_manager_t.
*/
struct eap_sim_peer_t {
diff --git a/src/libcharon/plugins/eap_sim/eap_sim_plugin.c b/src/libcharon/plugins/eap_sim/eap_sim_plugin.c
index b15292544..5bc0af6bd 100644
--- a/src/libcharon/plugins/eap_sim/eap_sim_plugin.c
+++ b/src/libcharon/plugins/eap_sim/eap_sim_plugin.c
@@ -19,20 +19,61 @@
#include "eap_sim_peer.h"
#include <daemon.h>
+#include <simaka_manager.h>
+
+typedef struct private_eap_sim_plugin_t private_eap_sim_plugin_t;
+
+/**
+ * Private data of an eap_sim_plugin_t object.
+ */
+struct private_eap_sim_plugin_t {
+
+ /**
+ * Public interface.
+ */
+ eap_sim_plugin_t public;
+
+ /**
+ * EAP-SIM backend manager
+ */
+ simaka_manager_t *mgr;
+};
METHOD(plugin_t, get_name, char*,
- eap_sim_plugin_t *this)
+ private_eap_sim_plugin_t *this)
{
return "eap-sim";
}
+METHOD(plugin_t, get_features, int,
+ private_eap_sim_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_PROVIDE(CUSTOM, "sim-manager"),
+ PLUGIN_CALLBACK(eap_method_register, eap_sim_server_create),
+ PLUGIN_PROVIDE(EAP_SERVER, EAP_SIM),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(PRF, PRF_FIPS_SHA1_160),
+ PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA1_128),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_CALLBACK(eap_method_register, eap_sim_peer_create),
+ PLUGIN_PROVIDE(EAP_PEER, EAP_SIM),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(PRF, PRF_FIPS_SHA1_160),
+ PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA1_128),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
- eap_sim_plugin_t *this)
+ private_eap_sim_plugin_t *this)
{
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_sim_server_create);
- charon->eap->remove_method(charon->eap,
- (eap_constructor_t)eap_sim_peer_create);
+ lib->set(lib, "sim-manager", NULL);
+ this->mgr->destroy(this->mgr);
free(this);
}
@@ -41,21 +82,20 @@ METHOD(plugin_t, destroy, void,
*/
plugin_t *eap_sim_plugin_create()
{
- eap_sim_plugin_t *this;
+ private_eap_sim_plugin_t *this;
INIT(this,
- .plugin = {
- .get_name = _get_name,
- .reload = (void*)return_false,
- .destroy = _destroy,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
},
+ .mgr = simaka_manager_create(),
);
+ lib->set(lib, "sim-manager", this->mgr);
- charon->eap->add_method(charon->eap, EAP_SIM, 0, EAP_SERVER,
- (eap_constructor_t)eap_sim_server_create);
- charon->eap->add_method(charon->eap, EAP_SIM, 0, EAP_PEER,
- (eap_constructor_t)eap_sim_peer_create);
-
- return &this->plugin;
+ return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/eap_sim/eap_sim_plugin.h b/src/libcharon/plugins/eap_sim/eap_sim_plugin.h
index 4e10380c4..0c71ca548 100644
--- a/src/libcharon/plugins/eap_sim/eap_sim_plugin.h
+++ b/src/libcharon/plugins/eap_sim/eap_sim_plugin.h
@@ -30,6 +30,11 @@ typedef struct eap_sim_plugin_t eap_sim_plugin_t;
/**
* EAP-SIM plugin.
+ *
+ * This plugin implements the protocol level of EAP-SIM and uses simaka_card_t
+ * and simaka_provider_t backends to provide triplets. It registers a
+ * simaka_manager_t on the library as "sim-manager", other plugins can use it
+ * to provide the required backends.
*/
struct eap_sim_plugin_t {
diff --git a/src/libcharon/plugins/eap_sim/eap_sim_server.c b/src/libcharon/plugins/eap_sim/eap_sim_server.c
index d1dfde5d6..e0f7e92ad 100644
--- a/src/libcharon/plugins/eap_sim/eap_sim_server.c
+++ b/src/libcharon/plugins/eap_sim/eap_sim_server.c
@@ -19,6 +19,7 @@
#include <simaka_message.h>
#include <simaka_crypto.h>
+#include <simaka_manager.h>
/* number of triplets for one authentication */
#define TRIPLET_COUNT 3
@@ -39,6 +40,11 @@ struct private_eap_sim_server_t {
eap_sim_server_t public;
/**
+ * SIM backend manager
+ */
+ simaka_manager_t *mgr;
+
+ /**
* permanent ID of peer
*/
identification_t *permanent;
@@ -127,7 +133,7 @@ METHOD(eap_method_t, initiate, status_t,
{
message->add_attribute(message, AT_PERMANENT_ID_REQ, chunk_empty);
}
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
this->pending = SIM_START;
@@ -163,14 +169,14 @@ static status_t reauthenticate(private_eap_sim_server_t *this,
SIM_REAUTHENTICATION, this->crypto);
message->add_attribute(message, AT_COUNTER, this->counter);
message->add_attribute(message, AT_NONCE_S, this->nonce);
- next = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk);
+ next = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk);
if (next)
{
message->add_attribute(message, AT_NEXT_REAUTH_ID,
next->get_encoding(next));
next->destroy(next);
}
- *out = message->generate(message, chunk_empty);
+ *out = eap_payload_create_data_own(message->generate(message, chunk_empty));
message->destroy(message);
this->pending = SIM_REAUTHENTICATION;
@@ -298,8 +304,8 @@ static status_t process_start(private_eap_sim_server_t *this,
char mk[HASH_SIZE_SHA1];
u_int16_t counter;
- permanent = charon->sim->provider_is_reauth(charon->sim, id,
- mk, &counter);
+ permanent = this->mgr->provider_is_reauth(this->mgr, id,
+ mk, &counter);
if (permanent)
{
this->permanent->destroy(this->permanent);
@@ -315,7 +321,7 @@ static status_t process_start(private_eap_sim_server_t *this,
}
if (this->use_pseudonym)
{
- permanent = charon->sim->provider_is_pseudonym(charon->sim, id);
+ permanent = this->mgr->provider_is_pseudonym(this->mgr, id);
if (permanent)
{
this->permanent->destroy(this->permanent);
@@ -348,8 +354,8 @@ static status_t process_start(private_eap_sim_server_t *this,
rands.len = kcs.len = sreses.len = 0;
for (i = 0; i < TRIPLET_COUNT; i++)
{
- if (!charon->sim->provider_get_triplet(charon->sim, this->permanent,
- rand.ptr, sres.ptr, kc.ptr))
+ if (!this->mgr->provider_get_triplet(this->mgr, this->permanent,
+ rand.ptr, sres.ptr, kc.ptr))
{
if (this->use_pseudonym)
{
@@ -386,24 +392,21 @@ static status_t process_start(private_eap_sim_server_t *this,
message = simaka_message_create(TRUE, this->identifier++, EAP_SIM,
SIM_CHALLENGE, this->crypto);
message->add_attribute(message, AT_RAND, rands);
- id = charon->sim->provider_gen_reauth(charon->sim, this->permanent, mk.ptr);
+ id = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk.ptr);
if (id)
{
message->add_attribute(message, AT_NEXT_REAUTH_ID,
id->get_encoding(id));
id->destroy(id);
}
- else
+ id = this->mgr->provider_gen_pseudonym(this->mgr, this->permanent);
+ if (id)
{
- id = charon->sim->provider_gen_pseudonym(charon->sim, this->permanent);
- if (id)
- {
- message->add_attribute(message, AT_NEXT_PSEUDONYM,
- id->get_encoding(id));
- id->destroy(id);
- }
+ message->add_attribute(message, AT_NEXT_PSEUDONYM,
+ id->get_encoding(id));
+ id->destroy(id);
}
- *out = message->generate(message, nonce);
+ *out = eap_payload_create_data_own(message->generate(message, nonce));
message->destroy(message);
free(mk.ptr);
@@ -483,7 +486,7 @@ METHOD(eap_method_t, process, status_t,
simaka_message_t *message;
status_t status;
- message = simaka_message_create_from_payload(in, this->crypto);
+ message = simaka_message_create_from_payload(in->get_data(in), this->crypto);
if (!message)
{
return FAILED;
@@ -588,7 +591,8 @@ eap_sim_server_t *eap_sim_server_create(identification_t *server,
.destroy = _destroy,
},
},
- .crypto = simaka_crypto_create(),
+ .crypto = simaka_crypto_create(EAP_SIM),
+ .mgr = lib->get(lib, "sim-manager"),
);
if (!this->crypto)
diff --git a/src/libcharon/plugins/eap_sim/eap_sim_server.h b/src/libcharon/plugins/eap_sim/eap_sim_server.h
index 978e1e1e9..c0ed64ff2 100644
--- a/src/libcharon/plugins/eap_sim/eap_sim_server.h
+++ b/src/libcharon/plugins/eap_sim/eap_sim_server.h
@@ -27,9 +27,6 @@ typedef struct eap_sim_server_t eap_sim_server_t;
/**
* EAP-SIM server implementation.
- *
- * This EAP-SIM module uses sim_provider_t implementations for triplet
- * calculation, found via the eap_sim_manager_t.
*/
struct eap_sim_server_t {
diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.am b/src/libcharon/plugins/eap_sim_file/Makefile.am
index 2b59a7c88..d76cdc5ca 100644
--- a/src/libcharon/plugins/eap_sim_file/Makefile.am
+++ b/src/libcharon/plugins/eap_sim_file/Makefile.am
@@ -1,6 +1,6 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${sysconfdir}\"
@@ -8,6 +8,7 @@ if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-eap-sim-file.la
else
plugin_LTLIBRARIES = libstrongswan-eap-sim-file.la
+libstrongswan_eap_sim_file_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la
endif
libstrongswan_eap_sim_file_la_SOURCES = \
diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in
index 5662a1c53..bebf62e5b 100644
--- a/src/libcharon/plugins/eap_sim_file/Makefile.in
+++ b/src/libcharon/plugins/eap_sim_file/Makefile.in
@@ -74,7 +74,8 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_eap_sim_file_la_LIBADD =
+@MONOLITHIC_FALSE@libstrongswan_eap_sim_file_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libsimaka/libsimaka.la
am_libstrongswan_eap_sim_file_la_OBJECTS = eap_sim_file_plugin.lo \
eap_sim_file_card.lo eap_sim_file_provider.lo \
eap_sim_file_triplets.lo
@@ -196,6 +197,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -204,6 +208,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -220,11 +225,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -268,6 +275,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -279,11 +287,12 @@ 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/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${sysconfdir}\"
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-sim-file.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-sim-file.la
+@MONOLITHIC_FALSE@libstrongswan_eap_sim_file_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la
libstrongswan_eap_sim_file_la_SOURCES = \
eap_sim_file_plugin.h eap_sim_file_plugin.c \
eap_sim_file_card.h eap_sim_file_card.c \
diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c
index 5397c418e..bd47e5085 100644
--- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c
+++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.c
@@ -35,7 +35,7 @@ struct private_eap_sim_file_card_t {
eap_sim_file_triplets_t *triplets;
};
-METHOD(sim_card_t, get_triplet, bool,
+METHOD(simaka_card_t, get_triplet, bool,
private_eap_sim_file_card_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
@@ -66,7 +66,7 @@ METHOD(sim_card_t, get_triplet, bool,
return FALSE;
}
-METHOD(sim_card_t, get_quintuplet, status_t,
+METHOD(simaka_card_t, get_quintuplet, status_t,
private_eap_sim_file_card_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len)
diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.h b/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.h
index 1a5470968..45b0e51db 100644
--- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.h
+++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_card.h
@@ -23,7 +23,7 @@
#include "eap_sim_file_triplets.h"
-#include <sa/authenticators/eap/sim_manager.h>
+#include <simaka_card.h>
typedef struct eap_sim_file_card_t eap_sim_file_card_t;
@@ -33,9 +33,9 @@ typedef struct eap_sim_file_card_t eap_sim_file_card_t;
struct eap_sim_file_card_t {
/**
- * Implements sim_card_t interface
+ * Implements simaka_card_t interface
*/
- sim_card_t card;
+ simaka_card_t card;
/**
* Destroy a eap_sim_file_card_t.
diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c
index 0ab5a1848..eae76729c 100644
--- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c
+++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_plugin.c
@@ -56,14 +56,70 @@ METHOD(plugin_t, get_name, char*,
return "eap-sim-file";
}
-METHOD(plugin_t, destroy, void,
- private_eap_sim_file_t *this)
+/**
+ * Load triplet file
+ */
+static bool load_triplets(private_eap_sim_file_t *this,
+ plugin_feature_t *feature, bool reg, void *data)
{
- charon->sim->remove_card(charon->sim, &this->card->card);
- charon->sim->remove_provider(charon->sim, &this->provider->provider);
+ if (reg)
+ {
+ this->triplets = eap_sim_file_triplets_create(TRIPLET_FILE);
+ if (!this->triplets)
+ {
+ return FALSE;
+ }
+ this->provider = eap_sim_file_provider_create(this->triplets);
+ this->card = eap_sim_file_card_create(this->triplets);
+ return TRUE;
+ }
this->card->destroy(this->card);
this->provider->destroy(this->provider);
this->triplets->destroy(this->triplets);
+ this->card = NULL;
+ this->provider = NULL;
+ this->triplets = NULL;
+ return TRUE;
+}
+
+/**
+ * Callback providing our card to register
+ */
+static simaka_card_t* get_card(private_eap_sim_file_t *this)
+{
+ return &this->card->card;
+}
+
+/**
+ * Callback providing our provider to register
+ */
+static simaka_provider_t* get_provider(private_eap_sim_file_t *this)
+{
+ return &this->provider->provider;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_eap_sim_file_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK((void*)load_triplets, NULL),
+ PLUGIN_PROVIDE(CUSTOM, "eap-sim-file-triplets"),
+ PLUGIN_CALLBACK(simaka_manager_register, get_card),
+ PLUGIN_PROVIDE(CUSTOM, "sim-card"),
+ PLUGIN_DEPENDS(CUSTOM, "sim-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "eap-sim-file-triplets"),
+ PLUGIN_CALLBACK(simaka_manager_register, get_provider),
+ PLUGIN_PROVIDE(CUSTOM, "sim-provider"),
+ PLUGIN_DEPENDS(CUSTOM, "sim-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "eap-sim-file-triplets"),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_eap_sim_file_t *this)
+{
free(this);
}
@@ -78,25 +134,12 @@ plugin_t *eap_sim_file_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
- .triplets = eap_sim_file_triplets_create(TRIPLET_FILE),
);
- this->provider = eap_sim_file_provider_create(this->triplets);
- if (!this->provider)
- {
- this->triplets->destroy(this->triplets);
- free(this);
- return NULL;
- }
- this->card = eap_sim_file_card_create(this->triplets);
-
- charon->sim->add_card(charon->sim, &this->card->card);
- charon->sim->add_provider(charon->sim, &this->provider->provider);
-
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c
index 38b651404..4ca1eb93f 100644
--- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c
+++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.c
@@ -35,7 +35,7 @@ struct private_eap_sim_file_provider_t {
eap_sim_file_triplets_t *triplets;
};
-METHOD(sim_provider_t, get_triplet, bool,
+METHOD(simaka_provider_t, get_triplet, bool,
private_eap_sim_file_provider_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.h b/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.h
index 10fda282a..577345dbf 100644
--- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.h
+++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_provider.h
@@ -23,6 +23,8 @@
#include "eap_sim_file_triplets.h"
+#include <simaka_provider.h>
+
typedef struct eap_sim_file_provider_t eap_sim_file_provider_t;
/**
@@ -31,9 +33,9 @@ typedef struct eap_sim_file_provider_t eap_sim_file_provider_t;
struct eap_sim_file_provider_t {
/**
- * Implements sim_provider_t interface.
+ * Implements simaka_provider_t interface.
*/
- sim_provider_t provider;
+ simaka_provider_t provider;
/**
* Destroy a eap_sim_file_provider_t.
diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c
index c693923fe..de3b69382 100644
--- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c
+++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c
@@ -21,6 +21,7 @@
#include <daemon.h>
#include <utils/linked_list.h>
#include <threading/mutex.h>
+#include <simaka_manager.h>
typedef struct private_eap_sim_file_triplets_t private_eap_sim_file_triplets_t;
@@ -149,7 +150,7 @@ static void parse_token(char *to, char *from, size_t len)
/**
* Read the triplets from the file
*/
-static void read_triplets(private_eap_sim_file_triplets_t *this, char *path)
+static bool read_triplets(private_eap_sim_file_triplets_t *this, char *path)
{
char line[512];
FILE *file;
@@ -160,7 +161,7 @@ static void read_triplets(private_eap_sim_file_triplets_t *this, char *path)
{
DBG1(DBG_CFG, "opening triplet file %s failed: %s",
path, strerror(errno));
- return;
+ return FALSE;
}
/* read line by line */
@@ -226,6 +227,7 @@ static void read_triplets(private_eap_sim_file_triplets_t *this, char *path)
DBG1(DBG_CFG, "read %d triplets from %s",
this->triplets->get_count(this->triplets), path);
+ return TRUE;
}
METHOD(eap_sim_file_triplets_t, destroy, void,
@@ -251,8 +253,12 @@ eap_sim_file_triplets_t *eap_sim_file_triplets_create(char *file)
.triplets = linked_list_create(),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
);
- read_triplets(this, file);
+ if (!read_triplets(this, file))
+ {
+ destroy(this);
+ return NULL;
+ }
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.h b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.h
index 8f8130810..c8e9e0359 100644
--- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.h
+++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.h
@@ -21,7 +21,7 @@
#ifndef EAP_SIM_FILE_TRIPLETS_H_
#define EAP_SIM_FILE_TRIPLETS_H_
-#include <sa/authenticators/eap/sim_manager.h>
+#include <utils/enumerator.h>
typedef struct eap_sim_file_triplets_t eap_sim_file_triplets_t;
diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.am b/src/libcharon/plugins/eap_sim_pcsc/Makefile.am
index 2d75fe3ad..fae6fccfc 100644
--- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.am
+++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.am
@@ -1,18 +1,19 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic ${pcsclite_CFLAGS}
+libstrongswan_eap_sim_pcsc_la_LDFLAGS = -module -avoid-version
+libstrongswan_eap_sim_pcsc_la_LIBADD = ${pcsclite_LIBS}
+
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la
else
plugin_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la
+libstrongswan_eap_sim_pcsc_la_LIBADD += $(top_builddir)/src/libsimaka/libsimaka.la
endif
libstrongswan_eap_sim_pcsc_la_SOURCES = \
eap_sim_pcsc_plugin.h eap_sim_pcsc_plugin.c \
eap_sim_pcsc_card.h eap_sim_pcsc_card.c
-
-libstrongswan_eap_sim_pcsc_la_LDFLAGS = -module -avoid-version
-libstrongswan_eap_sim_pcsc_la_LIBADD = ${pcsclite_LIBS}
diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
index a8249a7ac..5c05b2bf1 100644
--- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
+++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in
@@ -34,6 +34,7 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@MONOLITHIC_FALSE@am__append_1 = $(top_builddir)/src/libsimaka/libsimaka.la
subdir = src/libcharon/plugins/eap_sim_pcsc
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -75,7 +76,8 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
am__DEPENDENCIES_1 =
-libstrongswan_eap_sim_pcsc_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+libstrongswan_eap_sim_pcsc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__append_1)
am_libstrongswan_eap_sim_pcsc_la_OBJECTS = eap_sim_pcsc_plugin.lo \
eap_sim_pcsc_card.lo
libstrongswan_eap_sim_pcsc_la_OBJECTS = \
@@ -196,6 +198,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -204,6 +209,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -220,11 +226,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -268,6 +276,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -279,17 +288,18 @@ 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/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic ${pcsclite_CFLAGS}
+libstrongswan_eap_sim_pcsc_la_LDFLAGS = -module -avoid-version
+libstrongswan_eap_sim_pcsc_la_LIBADD = ${pcsclite_LIBS} \
+ $(am__append_1)
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-sim-pcsc.la
libstrongswan_eap_sim_pcsc_la_SOURCES = \
eap_sim_pcsc_plugin.h eap_sim_pcsc_plugin.c \
eap_sim_pcsc_card.h eap_sim_pcsc_card.c
-libstrongswan_eap_sim_pcsc_la_LDFLAGS = -module -avoid-version
-libstrongswan_eap_sim_pcsc_la_LIBADD = ${pcsclite_LIBS}
all: all-am
.SUFFIXES:
diff --git a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c
index d0a2718f3..c3f0f24b3 100644
--- a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c
+++ b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.c
@@ -87,7 +87,7 @@ static bool decode_imsi_ef(unsigned char *input, int input_len, char *output)
return TRUE;
}
-METHOD(sim_card_t, get_triplet, bool,
+METHOD(simaka_card_t, get_triplet, bool,
private_eap_sim_pcsc_card_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
@@ -207,7 +207,8 @@ METHOD(sim_card_t, get_triplet, bool,
if (dwRecvLength < APDU_STATUS_LEN ||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
{
- DBG1(DBG_IKE, "Select MF failed: %b", pbRecvBuffer, dwRecvLength);
+ DBG1(DBG_IKE, "Select MF failed: %b", pbRecvBuffer,
+ (u_int)dwRecvLength);
continue;
}
@@ -223,7 +224,8 @@ METHOD(sim_card_t, get_triplet, bool,
if (dwRecvLength < APDU_STATUS_LEN ||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
{
- DBG1(DBG_IKE, "Select DF GSM failed: %b", pbRecvBuffer, dwRecvLength);
+ DBG1(DBG_IKE, "Select DF GSM failed: %b", pbRecvBuffer,
+ (u_int)dwRecvLength);
continue;
}
@@ -239,7 +241,8 @@ METHOD(sim_card_t, get_triplet, bool,
if (dwRecvLength < APDU_STATUS_LEN ||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
{
- DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer, dwRecvLength);
+ DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer,
+ (u_int)dwRecvLength);
continue;
}
@@ -255,14 +258,15 @@ METHOD(sim_card_t, get_triplet, bool,
if (dwRecvLength < APDU_STATUS_LEN ||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_SUCCESS)
{
- DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer, dwRecvLength);
+ DBG1(DBG_IKE, "Select IMSI failed: %b", pbRecvBuffer,
+ (u_int)dwRecvLength);
continue;
}
if (!decode_imsi_ef(pbRecvBuffer, dwRecvLength-APDU_STATUS_LEN, imsi))
{
DBG1(DBG_IKE, "Couldn't decode IMSI EF: %b",
- pbRecvBuffer, dwRecvLength);
+ pbRecvBuffer, (u_int)dwRecvLength);
continue;
}
@@ -288,7 +292,7 @@ METHOD(sim_card_t, get_triplet, bool,
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_RESPONSE_DATA)
{
DBG1(DBG_IKE, "Run GSM Algorithm failed: %b",
- pbRecvBuffer, dwRecvLength);
+ pbRecvBuffer, (u_int)dwRecvLength);
continue;
}
@@ -305,7 +309,8 @@ METHOD(sim_card_t, get_triplet, bool,
if (dwRecvLength < APDU_STATUS_LEN ||
pbRecvBuffer[dwRecvLength-APDU_STATUS_LEN] != APDU_SW1_SUCCESS)
{
- DBG1(DBG_IKE, "Get Response failed: %b", pbRecvBuffer, dwRecvLength);
+ DBG1(DBG_IKE, "Get Response failed: %b", pbRecvBuffer,
+ (u_int)dwRecvLength);
continue;
}
@@ -320,7 +325,7 @@ METHOD(sim_card_t, get_triplet, bool,
else
{
DBG1(DBG_IKE, "Get Response incorrect length: %b",
- pbRecvBuffer, dwRecvLength);
+ pbRecvBuffer, (u_int)dwRecvLength);
continue;
}
@@ -351,7 +356,7 @@ METHOD(sim_card_t, get_triplet, bool,
return found;
}
-METHOD(sim_card_t, get_quintuplet, status_t,
+METHOD(simaka_card_t, get_quintuplet, status_t,
private_eap_sim_pcsc_card_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len)
diff --git a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h
index e7659656b..6b69f76ec 100644
--- a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h
+++ b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_card.h
@@ -20,7 +20,7 @@
#ifndef EAP_SIM_PCSC_CARD_H_
#define EAP_SIM_PCSC_CARD_H_
-#include <sa/authenticators/eap/sim_manager.h>
+#include <simaka_card.h>
typedef struct eap_sim_pcsc_card_t eap_sim_pcsc_card_t;
@@ -30,9 +30,9 @@ typedef struct eap_sim_pcsc_card_t eap_sim_pcsc_card_t;
struct eap_sim_pcsc_card_t {
/**
- * Implements sim_card_t interface
+ * Implements simaka_card_t interface
*/
- sim_card_t card;
+ simaka_card_t card;
/**
* Destroy a eap_sim_pcsc_card_t.
diff --git a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c
index 44096455e..898e85345 100644
--- a/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c
+++ b/src/libcharon/plugins/eap_sim_pcsc/eap_sim_pcsc_plugin.c
@@ -41,10 +41,29 @@ METHOD(plugin_t, get_name, char*,
return "eap-sim-pcsc";
}
+/**
+ * Callback providing our card to register
+ */
+static simaka_card_t* get_card(private_eap_sim_pcsc_plugin_t *this)
+{
+ return &this->card->card;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_eap_sim_pcsc_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(simaka_manager_register, get_card),
+ PLUGIN_PROVIDE(CUSTOM, "sim-card"),
+ PLUGIN_DEPENDS(CUSTOM, "sim-manager"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_eap_sim_pcsc_plugin_t *this)
{
- charon->sim->remove_card(charon->sim, &this->card->card);
this->card->destroy(this->card);
free(this);
}
@@ -60,13 +79,12 @@ plugin_t *eap_sim_pcsc_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
.card = eap_sim_pcsc_card_create(),
);
- charon->sim->add_card(charon->sim, &this->card->card);
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am
index a158d6dbe..a8e03f650 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am
@@ -1,6 +1,6 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic
@@ -8,6 +8,7 @@ if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-eap-simaka-pseudonym.la
else
plugin_LTLIBRARIES = libstrongswan-eap-simaka-pseudonym.la
+libstrongswan_eap_simaka_pseudonym_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la
endif
libstrongswan_eap_simaka_pseudonym_la_SOURCES = \
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
index 98e80bc71..0d7c32c14 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in
@@ -74,7 +74,8 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_eap_simaka_pseudonym_la_LIBADD =
+@MONOLITHIC_FALSE@libstrongswan_eap_simaka_pseudonym_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libsimaka/libsimaka.la
am_libstrongswan_eap_simaka_pseudonym_la_OBJECTS = \
eap_simaka_pseudonym_plugin.lo eap_simaka_pseudonym_card.lo \
eap_simaka_pseudonym_provider.lo
@@ -197,6 +198,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -205,6 +209,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -221,11 +226,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -269,6 +276,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -280,11 +288,12 @@ 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/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-simaka-pseudonym.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-simaka-pseudonym.la
+@MONOLITHIC_FALSE@libstrongswan_eap_simaka_pseudonym_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la
libstrongswan_eap_simaka_pseudonym_la_SOURCES = \
eap_simaka_pseudonym_plugin.h eap_simaka_pseudonym_plugin.c \
eap_simaka_pseudonym_card.h eap_simaka_pseudonym_card.c \
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c
index 9b0f1bc71..5f78c967a 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.c
@@ -57,11 +57,8 @@ static bool equals(identification_t *key1, identification_t *key2)
return key1->equals(key1, key2);
}
-/**
- * Implementation of sim_card_t.get_pseudonym
- */
-static identification_t *get_pseudonym(private_eap_simaka_pseudonym_card_t *this,
- identification_t *id)
+METHOD(simaka_card_t, get_pseudonym, identification_t*,
+ private_eap_simaka_pseudonym_card_t *this, identification_t *id)
{
identification_t *pseudonym;
@@ -73,11 +70,9 @@ static identification_t *get_pseudonym(private_eap_simaka_pseudonym_card_t *this
return NULL;
}
-/**
- * Implementation of sim_card_t.set_pseudonym
- */
-static void set_pseudonym(private_eap_simaka_pseudonym_card_t *this,
- identification_t *id, identification_t *pseudonym)
+METHOD(simaka_card_t, set_pseudonym, void,
+ private_eap_simaka_pseudonym_card_t *this, identification_t *id,
+ identification_t *pseudonym)
{
identification_t *permanent;
@@ -92,18 +87,16 @@ static void set_pseudonym(private_eap_simaka_pseudonym_card_t *this,
DESTROY_IF(pseudonym);
}
-/**
- * Implementation of sim_card_t.get_quintuplet
- */
-static status_t get_quintuplet()
+METHOD(simaka_card_t, get_quintuplet, status_t,
+ private_eap_simaka_pseudonym_card_t *this, identification_t *id,
+ char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
+ char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len)
{
return NOT_SUPPORTED;
}
-/**
- * Implementation of eap_simaka_pseudonym_card_t.destroy.
- */
-static void destroy(private_eap_simaka_pseudonym_card_t *this)
+METHOD(eap_simaka_pseudonym_card_t, destroy, void,
+ private_eap_simaka_pseudonym_card_t *this)
{
enumerator_t *enumerator;
identification_t *id;
@@ -135,19 +128,22 @@ eap_simaka_pseudonym_card_t *eap_simaka_pseudonym_card_create()
{
private_eap_simaka_pseudonym_card_t *this;
- this = malloc_thing(private_eap_simaka_pseudonym_card_t);
-
- this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false;
- this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len))get_quintuplet;
- this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
- this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))get_pseudonym;
- this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))set_pseudonym;
- this->public.card.get_reauth = (identification_t*(*)(sim_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))return_null;
- this->public.card.set_reauth = (void(*)(sim_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))nop;
- this->public.destroy = (void(*)(eap_simaka_pseudonym_card_t*))destroy;
-
- this->pseudonym = hashtable_create((void*)hash, (void*)equals, 0);
- this->permanent = hashtable_create((void*)hash, (void*)equals, 0);
+ INIT(this,
+ .public = {
+ .card = {
+ .get_triplet = (void*)return_false,
+ .get_quintuplet = _get_quintuplet,
+ .resync = (void*)return_false,
+ .get_pseudonym = _get_pseudonym,
+ .set_pseudonym = _set_pseudonym,
+ .get_reauth = (void*)return_null,
+ .set_reauth = (void*)nop,
+ },
+ .destroy = _destroy,
+ },
+ .pseudonym = hashtable_create((void*)hash, (void*)equals, 0),
+ .permanent = hashtable_create((void*)hash, (void*)equals, 0),
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h
index 1b5940fdc..6c73a8cb9 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_card.h
@@ -21,7 +21,7 @@
#ifndef EAP_SIMAKA_PSEUDONYM_CARD_H_
#define EAP_SIMAKA_PSEUDONYM_CARD_H_
-#include <sa/authenticators/eap/sim_manager.h>
+#include <simaka_card.h>
typedef struct eap_simaka_pseudonym_card_t eap_simaka_pseudonym_card_t;
@@ -31,9 +31,9 @@ typedef struct eap_simaka_pseudonym_card_t eap_simaka_pseudonym_card_t;
struct eap_simaka_pseudonym_card_t {
/**
- * Implements sim_card_t interface
+ * Implements simaka_card_t interface
*/
- sim_card_t card;
+ simaka_card_t card;
/**
* Destroy a eap_simaka_pseudonym_card_t.
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c
index 06631b1c5..e2cc0e84f 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_plugin.c
@@ -48,13 +48,60 @@ METHOD(plugin_t, get_name, char*,
return "eap-simaka-pseudonym";
}
+/**
+ * Callback providing our card to register
+ */
+static simaka_card_t* get_card(private_eap_simaka_pseudonym_t *this)
+{
+ if (!this->card)
+ {
+ this->card = eap_simaka_pseudonym_card_create();
+ }
+ return &this->card->card;
+}
+
+/**
+ * Callback providing our provider to register
+ */
+static simaka_provider_t* get_provider(private_eap_simaka_pseudonym_t *this)
+{
+ if (!this->provider)
+ {
+ this->provider = eap_simaka_pseudonym_provider_create();
+ if (!this->provider)
+ {
+ return NULL;
+ }
+ }
+ return &this->provider->provider;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_eap_simaka_pseudonym_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(simaka_manager_register, get_card),
+ PLUGIN_PROVIDE(CUSTOM, "aka-card"),
+ PLUGIN_DEPENDS(CUSTOM, "aka-manager"),
+ PLUGIN_PROVIDE(CUSTOM, "sim-card"),
+ PLUGIN_DEPENDS(CUSTOM, "sim-manager"),
+ PLUGIN_CALLBACK(simaka_manager_register, get_provider),
+ PLUGIN_PROVIDE(CUSTOM, "aka-provider"),
+ PLUGIN_DEPENDS(CUSTOM, "aka-manager"),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_PROVIDE(CUSTOM, "sim-provider"),
+ PLUGIN_DEPENDS(CUSTOM, "sim-manager"),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_eap_simaka_pseudonym_t *this)
{
- charon->sim->remove_card(charon->sim, &this->card->card);
- charon->sim->remove_provider(charon->sim, &this->provider->provider);
- this->card->destroy(this->card);
- this->provider->destroy(this->provider);
+ DESTROY_IF(this->card);
+ DESTROY_IF(this->provider);
free(this);
}
@@ -69,23 +116,12 @@ plugin_t *eap_simaka_pseudonym_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
- .provider = eap_simaka_pseudonym_provider_create(),
);
- if (!this->provider)
- {
- free(this);
- return NULL;
- }
- this->card = eap_simaka_pseudonym_card_create();
-
- charon->sim->add_card(charon->sim, &this->card->card);
- charon->sim->add_provider(charon->sim, &this->provider->provider);
-
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c
index 0613b8807..49c3ad328 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.c
@@ -61,11 +61,8 @@ static bool equals(identification_t *key1, identification_t *key2)
return key1->equals(key1, key2);
}
-/**
- * Implementation of sim_provider_t.is_pseudonym
- */
-static identification_t* is_pseudonym(
- private_eap_simaka_pseudonym_provider_t *this, identification_t *id)
+METHOD(simaka_provider_t, is_pseudonym, identification_t*,
+ private_eap_simaka_pseudonym_provider_t *this, identification_t *id)
{
identification_t *permanent;
@@ -91,11 +88,8 @@ static identification_t *gen_identity(
return identification_create_from_string(hex);
}
-/**
- * Implementation of sim_provider_t.get_pseudonym
- */
-static identification_t* gen_pseudonym(
- private_eap_simaka_pseudonym_provider_t *this, identification_t *id)
+METHOD(simaka_provider_t, gen_pseudonym, identification_t*,
+ private_eap_simaka_pseudonym_provider_t *this, identification_t *id)
{
identification_t *pseudonym, *permanent;
@@ -121,10 +115,8 @@ static identification_t* gen_pseudonym(
return pseudonym->clone(pseudonym);
}
-/**
- * Implementation of eap_simaka_pseudonym_provider_t.destroy.
- */
-static void destroy(private_eap_simaka_pseudonym_provider_t *this)
+METHOD(eap_simaka_pseudonym_provider_t, destroy, void,
+ private_eap_simaka_pseudonym_provider_t *this)
{
enumerator_t *enumerator;
identification_t *id;
@@ -157,18 +149,21 @@ eap_simaka_pseudonym_provider_t *eap_simaka_pseudonym_provider_create()
{
private_eap_simaka_pseudonym_provider_t *this;
- this = malloc_thing(private_eap_simaka_pseudonym_provider_t);
-
- this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false;
- this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false;
- this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
- this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))is_pseudonym;
- this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))gen_pseudonym;
- this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))return_null;
- this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))return_null;
- this->public.destroy = (void(*)(eap_simaka_pseudonym_provider_t*))destroy;
-
- this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ INIT(this,
+ .public = {
+ .provider = {
+ .get_triplet = (void*)return_false,
+ .get_quintuplet = (void*)return_false,
+ .resync = (void*)return_false,
+ .is_pseudonym = _is_pseudonym,
+ .gen_pseudonym = _gen_pseudonym,
+ .is_reauth = (void*)return_null,
+ .gen_reauth = (void*)return_null,
+ },
+ .destroy = _destroy,
+ },
+ .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
+ );
if (!this->rng)
{
free(this);
diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h
index 5d8e6d221..2dea516c3 100644
--- a/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h
+++ b/src/libcharon/plugins/eap_simaka_pseudonym/eap_simaka_pseudonym_provider.h
@@ -21,7 +21,7 @@
#ifndef EAP_SIMAKA_PSEDUONYM_PROVIDER_H_
#define EAP_SIMAKA_PSEDUONYM_PROVIDER_H_
-#include <sa/authenticators/eap/sim_manager.h>
+#include <simaka_provider.h>
typedef struct eap_simaka_pseudonym_provider_t eap_simaka_pseudonym_provider_t;
@@ -31,9 +31,9 @@ typedef struct eap_simaka_pseudonym_provider_t eap_simaka_pseudonym_provider_t;
struct eap_simaka_pseudonym_provider_t {
/**
- * Implements sim_provider_t interface.
+ * Implements simaka_provider_t interface.
*/
- sim_provider_t provider;
+ simaka_provider_t provider;
/**
* Destroy a eap_simaka_pseudonym_provider_t.
diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.am b/src/libcharon/plugins/eap_simaka_reauth/Makefile.am
index fbcd544d3..0b35c7521 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.am
+++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.am
@@ -1,6 +1,6 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic
@@ -8,6 +8,7 @@ if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-eap-simaka-reauth.la
else
plugin_LTLIBRARIES = libstrongswan-eap-simaka-reauth.la
+libstrongswan_eap_simaka_reauth_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la
endif
libstrongswan_eap_simaka_reauth_la_SOURCES = \
diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
index 56bc188b0..6177f3b3a 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in
@@ -74,7 +74,8 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_eap_simaka_reauth_la_LIBADD =
+@MONOLITHIC_FALSE@libstrongswan_eap_simaka_reauth_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libsimaka/libsimaka.la
am_libstrongswan_eap_simaka_reauth_la_OBJECTS = \
eap_simaka_reauth_plugin.lo eap_simaka_reauth_card.lo \
eap_simaka_reauth_provider.lo
@@ -196,6 +197,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -204,6 +208,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -220,11 +225,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -268,6 +275,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -279,11 +287,12 @@ 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/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-simaka-reauth.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-simaka-reauth.la
+@MONOLITHIC_FALSE@libstrongswan_eap_simaka_reauth_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la
libstrongswan_eap_simaka_reauth_la_SOURCES = \
eap_simaka_reauth_plugin.h eap_simaka_reauth_plugin.c \
eap_simaka_reauth_card.h eap_simaka_reauth_card.c \
diff --git a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c
index 14d0416d9..870d72781 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c
+++ b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.c
@@ -66,12 +66,9 @@ static bool equals(identification_t *key1, identification_t *key2)
return key1->equals(key1, key2);
}
-/**
- * Implementation of sim_card_t.get_reauth
- */
-static identification_t *get_reauth(private_eap_simaka_reauth_card_t *this,
- identification_t *id, char mk[HASH_SIZE_SHA1],
- u_int16_t *counter)
+METHOD(simaka_card_t, get_reauth, identification_t*,
+ private_eap_simaka_reauth_card_t *this, identification_t *id,
+ char mk[HASH_SIZE_SHA1], u_int16_t *counter)
{
reauth_data_t *data;
identification_t *reauth;
@@ -90,12 +87,9 @@ static identification_t *get_reauth(private_eap_simaka_reauth_card_t *this,
return reauth;
}
-/**
- * Implementation of sim_card_t.set_reauth
- */
-static void set_reauth(private_eap_simaka_reauth_card_t *this,
- identification_t *id, identification_t* next,
- char mk[HASH_SIZE_SHA1], u_int16_t counter)
+METHOD(simaka_card_t, set_reauth, void,
+ private_eap_simaka_reauth_card_t *this, identification_t *id,
+ identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter)
{
reauth_data_t *data;
@@ -115,18 +109,16 @@ static void set_reauth(private_eap_simaka_reauth_card_t *this,
memcpy(data->mk, mk, HASH_SIZE_SHA1);
}
-/**
- * Implementation of sim_card_t.get_quintuplet
- */
-static status_t get_quintuplet()
+METHOD(simaka_card_t, get_quintuplet, status_t,
+ private_eap_simaka_reauth_card_t *this, identification_t *id,
+ char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
+ char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len)
{
return NOT_SUPPORTED;
}
-/**
- * Implementation of eap_simaka_reauth_card_t.destroy.
- */
-static void destroy(private_eap_simaka_reauth_card_t *this)
+METHOD(eap_simaka_reauth_card_t, destroy, void,
+ private_eap_simaka_reauth_card_t *this)
{
enumerator_t *enumerator;
reauth_data_t *data;
@@ -152,18 +144,21 @@ eap_simaka_reauth_card_t *eap_simaka_reauth_card_create()
{
private_eap_simaka_reauth_card_t *this;
- this = malloc_thing(private_eap_simaka_reauth_card_t);
-
- this->public.card.get_triplet = (bool(*)(sim_card_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_null;
- this->public.card.get_quintuplet = (status_t(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len))get_quintuplet;
- this->public.card.resync = (bool(*)(sim_card_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
- this->public.card.get_pseudonym = (identification_t*(*)(sim_card_t*, identification_t *perm))return_null;
- this->public.card.set_pseudonym = (void(*)(sim_card_t*, identification_t *id, identification_t *pseudonym))nop;
- this->public.card.get_reauth = (identification_t*(*)(sim_card_t*, identification_t *id, char mk[HASH_SIZE_SHA1], u_int16_t *counter))get_reauth;
- this->public.card.set_reauth = (void(*)(sim_card_t*, identification_t *id, identification_t* next, char mk[HASH_SIZE_SHA1], u_int16_t counter))set_reauth;
- this->public.destroy = (void(*)(eap_simaka_reauth_card_t*))destroy;
-
- this->reauth = hashtable_create((void*)hash, (void*)equals, 0);
+ INIT(this,
+ .public = {
+ .card = {
+ .get_triplet = (void*)return_null,
+ .get_quintuplet = _get_quintuplet,
+ .resync = (void*)return_false,
+ .get_pseudonym = (void*)return_null,
+ .set_pseudonym = (void*)nop,
+ .get_reauth = _get_reauth,
+ .set_reauth = _set_reauth,
+ },
+ .destroy = _destroy,
+ },
+ .reauth = hashtable_create((void*)hash, (void*)equals, 0),
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h
index f24dc8a15..683de7559 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h
+++ b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_card.h
@@ -21,7 +21,7 @@
#ifndef EAP_SIMAKA_REAUTH_CARD_H_
#define EAP_SIMAKA_REAUTH_CARD_H_
-#include <sa/authenticators/eap/sim_manager.h>
+#include <simaka_provider.h>
typedef struct eap_simaka_reauth_card_t eap_simaka_reauth_card_t;
@@ -31,9 +31,9 @@ typedef struct eap_simaka_reauth_card_t eap_simaka_reauth_card_t;
struct eap_simaka_reauth_card_t {
/**
- * Implements sim_card_t interface
+ * Implements simaka_card_t interface
*/
- sim_card_t card;
+ simaka_card_t card;
/**
* Destroy a eap_simaka_reauth_card_t.
diff --git a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c
index 343e4eefb..ab3ab2f4d 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c
+++ b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_plugin.c
@@ -48,13 +48,60 @@ METHOD(plugin_t, get_name, char*,
return "eap-simaka-reauth";
}
+/**
+ * Callback providing our card to register
+ */
+static simaka_card_t* get_card(private_eap_simaka_reauth_t *this)
+{
+ if (!this->card)
+ {
+ this->card = eap_simaka_reauth_card_create();
+ }
+ return &this->card->card;
+}
+
+/**
+ * Callback providing our provider to register
+ */
+static simaka_provider_t* get_provider(private_eap_simaka_reauth_t *this)
+{
+ if (!this->provider)
+ {
+ this->provider = eap_simaka_reauth_provider_create();
+ if (!this->provider)
+ {
+ return NULL;
+ }
+ }
+ return &this->provider->provider;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_eap_simaka_reauth_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(simaka_manager_register, get_card),
+ PLUGIN_PROVIDE(CUSTOM, "aka-card"),
+ PLUGIN_DEPENDS(CUSTOM, "aka-manager"),
+ PLUGIN_PROVIDE(CUSTOM, "sim-card"),
+ PLUGIN_DEPENDS(CUSTOM, "sim-manager"),
+ PLUGIN_CALLBACK(simaka_manager_register, get_provider),
+ PLUGIN_PROVIDE(CUSTOM, "aka-provider"),
+ PLUGIN_DEPENDS(CUSTOM, "aka-manager"),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_PROVIDE(CUSTOM, "sim-provider"),
+ PLUGIN_DEPENDS(CUSTOM, "sim-manager"),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_eap_simaka_reauth_t *this)
{
- charon->sim->remove_card(charon->sim, &this->card->card);
- charon->sim->remove_provider(charon->sim, &this->provider->provider);
- this->card->destroy(this->card);
- this->provider->destroy(this->provider);
+ DESTROY_IF(this->card);
+ DESTROY_IF(this->provider);
free(this);
}
@@ -69,23 +116,12 @@ plugin_t *eap_simaka_reauth_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
- .provider = eap_simaka_reauth_provider_create(),
);
- if (!this->provider)
- {
- free(this);
- return NULL;
- }
- this->card = eap_simaka_reauth_card_create();
-
- charon->sim->add_card(charon->sim, &this->card->card);
- charon->sim->add_provider(charon->sim, &this->provider->provider);
-
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c
index f962b2d84..ba1a32778 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c
+++ b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.c
@@ -87,12 +87,9 @@ static identification_t *gen_identity(private_eap_simaka_reauth_provider_t *this
return identification_create_from_string(hex);
}
-/**
- * Implementation of sim_provider_t.is_reauth
- */
-static identification_t *is_reauth(private_eap_simaka_reauth_provider_t *this,
- identification_t *id, char mk[HASH_SIZE_SHA1],
- u_int16_t *counter)
+METHOD(simaka_provider_t, is_reauth, identification_t*,
+ private_eap_simaka_reauth_provider_t *this, identification_t *id,
+ char mk[HASH_SIZE_SHA1], u_int16_t *counter)
{
identification_t *permanent;
reauth_data_t *data;
@@ -114,11 +111,9 @@ static identification_t *is_reauth(private_eap_simaka_reauth_provider_t *this,
return permanent->clone(permanent);
}
-/**
- * Implementation of sim_provider_t.gen_reauth
- */
-static identification_t *gen_reauth(private_eap_simaka_reauth_provider_t *this,
- identification_t *id, char mk[HASH_SIZE_SHA1])
+METHOD(simaka_provider_t, gen_reauth, identification_t*,
+ private_eap_simaka_reauth_provider_t *this, identification_t *id,
+ char mk[HASH_SIZE_SHA1])
{
reauth_data_t *data;
identification_t *permanent;
@@ -136,9 +131,9 @@ static identification_t *gen_reauth(private_eap_simaka_reauth_provider_t *this,
}
else
{ /* generate new entry */
- data = malloc_thing(reauth_data_t);
- data->counter = 0;
- data->id = gen_identity(this);
+ INIT(data,
+ .id = gen_identity(this),
+ );
id = id->clone(id);
this->reauth->put(this->reauth, id, data);
this->permanent->put(this->permanent, data->id, id);
@@ -148,10 +143,8 @@ static identification_t *gen_reauth(private_eap_simaka_reauth_provider_t *this,
return data->id->clone(data->id);
}
-/**
- * Implementation of eap_simaka_reauth_provider_t.destroy.
- */
-static void destroy(private_eap_simaka_reauth_provider_t *this)
+METHOD(eap_simaka_reauth_provider_t, destroy, void,
+ private_eap_simaka_reauth_provider_t *this)
{
enumerator_t *enumerator;
identification_t *id;
@@ -184,18 +177,23 @@ static void destroy(private_eap_simaka_reauth_provider_t *this)
*/
eap_simaka_reauth_provider_t *eap_simaka_reauth_provider_create()
{
- private_eap_simaka_reauth_provider_t *this = malloc_thing(private_eap_simaka_reauth_provider_t);
-
- this->public.provider.get_triplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN]))return_false;
- this->public.provider.get_quintuplet = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN]))return_false;
- this->public.provider.resync = (bool(*)(sim_provider_t*, identification_t *id, char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]))return_false;
- this->public.provider.is_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null;
- this->public.provider.gen_pseudonym = (identification_t*(*)(sim_provider_t*, identification_t *id))return_null;
- this->public.provider.is_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char [HASH_SIZE_SHA1], u_int16_t *counter))is_reauth;
- this->public.provider.gen_reauth = (identification_t*(*)(sim_provider_t*, identification_t *id, char mk[HASH_SIZE_SHA1]))gen_reauth;
- this->public.destroy = (void(*)(eap_simaka_reauth_provider_t*))destroy;
-
- this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ private_eap_simaka_reauth_provider_t *this;
+
+ INIT(this,
+ .public = {
+ .provider = {
+ .get_triplet = (void*)return_false,
+ .get_quintuplet = (void*)return_false,
+ .resync = (void*)return_false,
+ .is_pseudonym = (void*)return_null,
+ .gen_pseudonym = (void*)return_null,
+ .is_reauth = _is_reauth,
+ .gen_reauth = _gen_reauth,
+ },
+ .destroy = _destroy,
+ },
+ .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
+ );
if (!this->rng)
{
free(this);
diff --git a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h
index 7ae151a27..bc6376d53 100644
--- a/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h
+++ b/src/libcharon/plugins/eap_simaka_reauth/eap_simaka_reauth_provider.h
@@ -21,7 +21,7 @@
#ifndef EAP_SIMAKA_REAUTH_PROVIDER_H_
#define EAP_SIMAKA_REAUTH_PROVIDER_H_
-#include <sa/authenticators/eap/sim_manager.h>
+#include <simaka_provider.h>
typedef struct eap_simaka_reauth_provider_t eap_simaka_reauth_provider_t;
@@ -31,9 +31,9 @@ typedef struct eap_simaka_reauth_provider_t eap_simaka_reauth_provider_t;
struct eap_simaka_reauth_provider_t {
/**
- * Implements sim_provider_t interface.
+ * Implements simaka_provider_t interface.
*/
- sim_provider_t provider;
+ simaka_provider_t provider;
/**
* Destroy a eap_simaka_reauth_provider_t.
diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.am b/src/libcharon/plugins/eap_simaka_sql/Makefile.am
index 73768be0e..c83267e67 100644
--- a/src/libcharon/plugins/eap_simaka_sql/Makefile.am
+++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.am
@@ -1,6 +1,6 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${sysconfdir}\"
@@ -8,6 +8,7 @@ if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-eap-simaka-sql.la
else
plugin_LTLIBRARIES = libstrongswan-eap-simaka-sql.la
+libstrongswan_eap_simaka_sql_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la
endif
libstrongswan_eap_simaka_sql_la_SOURCES = \
diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
index 93c7aed03..3639e24e8 100644
--- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in
+++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in
@@ -74,7 +74,8 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_eap_simaka_sql_la_LIBADD =
+@MONOLITHIC_FALSE@libstrongswan_eap_simaka_sql_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libsimaka/libsimaka.la
am_libstrongswan_eap_simaka_sql_la_OBJECTS = eap_simaka_sql_plugin.lo \
eap_simaka_sql_card.lo eap_simaka_sql_provider.lo
libstrongswan_eap_simaka_sql_la_OBJECTS = \
@@ -195,6 +196,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +207,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +224,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +274,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -278,11 +286,12 @@ 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/libcharon -I$(top_srcdir)/src/libsimaka
AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${sysconfdir}\"
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-simaka-sql.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-eap-simaka-sql.la
+@MONOLITHIC_FALSE@libstrongswan_eap_simaka_sql_la_LIBADD = $(top_builddir)/src/libsimaka/libsimaka.la
libstrongswan_eap_simaka_sql_la_SOURCES = \
eap_simaka_sql_plugin.h eap_simaka_sql_plugin.c \
eap_simaka_sql_card.h eap_simaka_sql_card.c \
diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c
index b7590405f..90627b52e 100644
--- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c
+++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c
@@ -42,7 +42,7 @@ struct private_eap_simaka_sql_card_t {
bool remove_used;
};
-METHOD(sim_card_t, get_triplet, bool,
+METHOD(simaka_card_t, get_triplet, bool,
private_eap_simaka_sql_card_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
@@ -90,7 +90,7 @@ METHOD(sim_card_t, get_triplet, bool,
return found;
}
-METHOD(sim_card_t, get_quintuplet, status_t,
+METHOD(simaka_card_t, get_quintuplet, status_t,
private_eap_simaka_sql_card_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN],
char ik[AKA_IK_LEN], char res[AKA_RES_MAX], int *res_len)
diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.h b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.h
index 46b7de25e..760755a56 100644
--- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.h
+++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.h
@@ -22,7 +22,7 @@
#define EAP_SIMAKA_SQL_CARD_H_
#include <database/database.h>
-#include <sa/authenticators/eap/sim_manager.h>
+#include <simaka_manager.h>
typedef struct eap_simaka_sql_card_t eap_simaka_sql_card_t;
@@ -32,9 +32,9 @@ typedef struct eap_simaka_sql_card_t eap_simaka_sql_card_t;
struct eap_simaka_sql_card_t {
/**
- * Implements sim_card_t interface
+ * Implements simaka_card_t interface
*/
- sim_card_t card;
+ simaka_card_t card;
/**
* Destroy a eap_simaka_sql_card_t.
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 5a528153d..6e590fae7 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
@@ -53,14 +53,93 @@ METHOD(plugin_t, get_name, char*,
return "eap-simaka-sql";
}
-METHOD(plugin_t, destroy, void,
- private_eap_simaka_sql_t *this)
+/**
+ * Load database
+ */
+static bool load_db(private_eap_simaka_sql_t *this,
+ plugin_feature_t *feature, bool reg, void *data)
{
- charon->sim->remove_card(charon->sim, &this->card->card);
- charon->sim->remove_provider(charon->sim, &this->provider->provider);
+ if (reg)
+ {
+ bool remove_used;
+ char *uri;
+
+ uri = lib->settings->get_str(lib->settings,
+ "charon.plugins.eap-simaka-sql.database", NULL);
+ if (!uri)
+ {
+ DBG1(DBG_CFG, "eap-simaka-sql database URI missing");
+ return FALSE;
+ }
+ this->db = lib->db->create(lib->db, uri);
+ if (!this->db)
+ {
+ DBG1(DBG_CFG, "opening eap-simaka-sql database failed");
+ return FALSE;
+ }
+ remove_used = lib->settings->get_bool(lib->settings,
+ "charon.plugins.eap-simaka-sql.remove_used", FALSE);
+
+ this->provider = eap_simaka_sql_provider_create(this->db, remove_used);
+ this->card = eap_simaka_sql_card_create(this->db, remove_used);
+ return TRUE;
+ }
this->card->destroy(this->card);
this->provider->destroy(this->provider);
this->db->destroy(this->db);
+ this->card = NULL;
+ this->provider = NULL;
+ this->db = NULL;
+ return TRUE;
+}
+
+/**
+ * Callback providing our card to register
+ */
+static simaka_card_t* get_card(private_eap_simaka_sql_t *this)
+{
+ return &this->card->card;
+}
+
+/**
+ * Callback providing our provider to register
+ */
+static simaka_provider_t* get_provider(private_eap_simaka_sql_t *this)
+{
+ return &this->provider->provider;
+}
+
+METHOD(plugin_t, get_features, int,
+ private_eap_simaka_sql_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK((void*)load_db, NULL),
+ PLUGIN_PROVIDE(CUSTOM, "eap-simaka-sql-db"),
+ PLUGIN_DEPENDS(DATABASE, DB_ANY),
+ PLUGIN_SDEPEND(DATABASE, DB_SQLITE),
+ PLUGIN_SDEPEND(DATABASE, DB_MYSQL),
+ PLUGIN_CALLBACK(simaka_manager_register, get_card),
+ PLUGIN_PROVIDE(CUSTOM, "aka-card"),
+ PLUGIN_DEPENDS(CUSTOM, "aka-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "eap-simaka-sql-db"),
+ PLUGIN_PROVIDE(CUSTOM, "sim-card"),
+ PLUGIN_DEPENDS(CUSTOM, "sim-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "eap-simaka-sql-db"),
+ PLUGIN_CALLBACK(simaka_manager_register, get_provider),
+ PLUGIN_PROVIDE(CUSTOM, "aka-provider"),
+ PLUGIN_DEPENDS(CUSTOM, "aka-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "eap-simaka-sql-db"),
+ PLUGIN_PROVIDE(CUSTOM, "sim-provider"),
+ PLUGIN_DEPENDS(CUSTOM, "sim-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "eap-simaka-sql-db"),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_eap_simaka_sql_t *this)
+{
free(this);
}
@@ -70,41 +149,16 @@ METHOD(plugin_t, destroy, void,
plugin_t *eap_simaka_sql_plugin_create()
{
private_eap_simaka_sql_t *this;
- database_t *db;
- bool remove_used;
- char *uri;
-
- uri = lib->settings->get_str(lib->settings,
- "charon.plugins.eap-simaka-sql.database", NULL);
- if (!uri)
- {
- DBG1(DBG_CFG, "eap-simaka-sql database URI missing");
- return NULL;
- }
- db = lib->db->create(lib->db, uri);
- if (!db)
- {
- DBG1(DBG_CFG, "opening eap-simaka-sql database failed");
- return NULL;
- }
- remove_used = lib->settings->get_bool(lib->settings,
- "charon.plugins.eap-simaka-sql.remove_used", FALSE);
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
- .db = db,
- .provider = eap_simaka_sql_provider_create(db, remove_used),
- .card = eap_simaka_sql_card_create(db, remove_used),
);
- charon->sim->add_card(charon->sim, &this->card->card);
- charon->sim->add_provider(charon->sim, &this->provider->provider);
-
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.c b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.c
index 73cccf549..21a19655f 100644
--- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.c
+++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.c
@@ -42,7 +42,7 @@ struct private_eap_simaka_sql_provider_t {
bool remove_used;
};
-METHOD(sim_provider_t, get_triplet, bool,
+METHOD(simaka_provider_t, get_triplet, bool,
private_eap_simaka_sql_provider_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
@@ -53,7 +53,7 @@ METHOD(sim_provider_t, get_triplet, bool,
snprintf(buf, sizeof(buf), "%Y", id);
query = this->db->query(this->db,
- "select rand, sres, kc from triplets where id = ? order by use",
+ "select rand, sres, kc from triplets where id = ? order by used",
DB_TEXT, buf, DB_BLOB, DB_BLOB, DB_BLOB);
if (query)
{
@@ -82,7 +82,7 @@ METHOD(sim_provider_t, get_triplet, bool,
else
{
this->db->execute(this->db, NULL,
- "update triplets set use = ? where id = ? and rand = ?",
+ "update triplets set used = ? where id = ? and rand = ?",
DB_UINT, time(NULL), DB_TEXT, buf,
DB_BLOB, chunk_create(rand, SIM_RAND_LEN));
}
@@ -90,7 +90,7 @@ METHOD(sim_provider_t, get_triplet, bool,
return found;
}
-METHOD(sim_provider_t, get_quintuplet, bool,
+METHOD(simaka_provider_t, get_quintuplet, bool,
private_eap_simaka_sql_provider_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len,
char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN])
@@ -102,7 +102,7 @@ METHOD(sim_provider_t, get_quintuplet, bool,
snprintf(buf, sizeof(buf), "%Y", id);
query = this->db->query(this->db, "select rand, res, ck, ik, autn "
- "from quintuplets where id = ? order by use", DB_TEXT, buf,
+ "from quintuplets where id = ? order by used", DB_TEXT, buf,
DB_BLOB, DB_BLOB, DB_BLOB, DB_BLOB, DB_BLOB);
if (query)
{
@@ -137,7 +137,7 @@ METHOD(sim_provider_t, get_quintuplet, bool,
else
{
this->db->execute(this->db, NULL,
- "update quintuplets set use = ? where id = ? and rand = ?",
+ "update quintuplets set used = ? where id = ? and rand = ?",
DB_UINT, time(NULL), DB_TEXT, buf,
DB_BLOB, chunk_create(rand, AKA_RAND_LEN));
}
diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.h b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.h
index ecb0c8cb0..88a8b1f24 100644
--- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.h
+++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_provider.h
@@ -22,7 +22,7 @@
#define EAP_SIMAKA_SQL_PROVIDER_H_
#include <database/database.h>
-#include <sa/authenticators/eap/sim_manager.h>
+#include <simaka_provider.h>
typedef struct eap_simaka_sql_provider_t eap_simaka_sql_provider_t;
@@ -32,9 +32,9 @@ typedef struct eap_simaka_sql_provider_t eap_simaka_sql_provider_t;
struct eap_simaka_sql_provider_t {
/**
- * Implements sim_provider_t interface
+ * Implements simaka_provider_t interface
*/
- sim_provider_t provider;
+ simaka_provider_t provider;
/**
* Destroy a eap_simaka_sql_provider_t.
diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in
index c58bced06..67e2c0cb0 100644
--- a/src/libcharon/plugins/eap_tls/Makefile.in
+++ b/src/libcharon/plugins/eap_tls/Makefile.in
@@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +205,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +222,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/eap_tls/eap_tls.c b/src/libcharon/plugins/eap_tls/eap_tls.c
index 39e1a60d9..dc0289ba2 100644
--- a/src/libcharon/plugins/eap_tls/eap_tls.c
+++ b/src/libcharon/plugins/eap_tls/eap_tls.c
@@ -39,7 +39,7 @@ struct private_eap_tls_t {
};
/** Maximum number of EAP-TLS messages/fragments allowed */
-#define MAX_MESSAGE_COUNT 32
+#define MAX_MESSAGE_COUNT 32
/** Default size of a EAP-TLS fragment */
#define MAX_FRAGMENT_LEN 1024
@@ -148,8 +148,8 @@ static eap_tls_t *eap_tls_create(identification_t *server,
max_msg_count = lib->settings->get_int(lib->settings,
"charon.plugins.eap-tls.max_message_count", MAX_MESSAGE_COUNT);
include_length = lib->settings->get_bool(lib->settings,
- "charon.plugins.eap-tls.include_length", TRUE);
- tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TLS, NULL);
+ "charon.plugins.eap-tls.include_length", TRUE);
+ tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TLS, NULL, NULL);
this->tls_eap = tls_eap_create(EAP_TLS, tls, frag_size, max_msg_count,
include_length);
if (!this->tls_eap)
diff --git a/src/libcharon/plugins/eap_tls/eap_tls_plugin.c b/src/libcharon/plugins/eap_tls/eap_tls_plugin.c
index 7afb79819..5507d8e02 100644
--- a/src/libcharon/plugins/eap_tls/eap_tls_plugin.c
+++ b/src/libcharon/plugins/eap_tls/eap_tls_plugin.c
@@ -25,13 +25,29 @@ METHOD(plugin_t, get_name, char*,
return "eap-tls";
}
+METHOD(plugin_t, get_features, int,
+ eap_tls_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(eap_method_register, eap_tls_create_server),
+ PLUGIN_PROVIDE(EAP_SERVER, EAP_TLS),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_CALLBACK(eap_method_register, eap_tls_create_peer),
+ PLUGIN_PROVIDE(EAP_PEER, EAP_TLS),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ };
+ *features = f;
+ return countof(f);
+}
+
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);
}
@@ -45,15 +61,10 @@ plugin_t *eap_tls_plugin_create()
INIT(this,
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.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/eap_tnc/Makefile.am b/src/libcharon/plugins/eap_tnc/Makefile.am
index 9c5a445c5..0e10f7d9c 100644
--- a/src/libcharon/plugins/eap_tnc/Makefile.am
+++ b/src/libcharon/plugins/eap_tnc/Makefile.am
@@ -1,6 +1,11 @@
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@@ -8,7 +13,9 @@ 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
+libstrongswan_eap_tnc_la_LIBADD = \
+ $(top_builddir)/src/libtls/libtls.la \
+ $(top_builddir)/src/libtnccs/libtnccs.la
endif
libstrongswan_eap_tnc_la_SOURCES = \
diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in
index dfc052bf8..62278f835 100644
--- a/src/libcharon/plugins/eap_tnc/Makefile.in
+++ b/src/libcharon/plugins/eap_tnc/Makefile.in
@@ -75,7 +75,8 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
@MONOLITHIC_FALSE@libstrongswan_eap_tnc_la_DEPENDENCIES = \
-@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.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)
@@ -194,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -276,13 +284,21 @@ 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
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
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
+@MONOLITHIC_FALSE@libstrongswan_eap_tnc_la_LIBADD = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+
libstrongswan_eap_tnc_la_SOURCES = \
eap_tnc_plugin.h eap_tnc_plugin.c eap_tnc.h eap_tnc.c
diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c
index ab3f87688..33a83ba18 100644
--- a/src/libcharon/plugins/eap_tnc/eap_tnc.c
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c
@@ -15,9 +15,9 @@
#include "eap_tnc.h"
+#include <tnc/tnc.h>
+#include <tnc/tnccs/tnccs_manager.h>
#include <tls_eap.h>
-
-#include <daemon.h>
#include <debug.h>
typedef struct private_eap_tnc_t private_eap_tnc_t;
@@ -172,7 +172,7 @@ static eap_tnc_t *eap_tnc_create(identification_t *server,
free(this);
return NULL;
}
- tnccs = charon->tnccs->create_instance(charon->tnccs, type, is_server);
+ tnccs = tnc->tnccs->create_instance(tnc->tnccs, type, is_server);
this->tls_eap = tls_eap_create(EAP_TNC, (tls_t*)tnccs, frag_size,
max_msg_count, include_length);
if (!this->tls_eap)
diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c
index 93847e636..813a75f48 100644
--- a/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c
+++ b/src/libcharon/plugins/eap_tnc/eap_tnc_plugin.c
@@ -24,13 +24,26 @@ METHOD(plugin_t, get_name, char*,
return "eap-tnc";
}
+METHOD(plugin_t, get_features, int,
+ eap_tnc_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(eap_method_register, eap_tnc_create_server),
+ PLUGIN_PROVIDE(EAP_SERVER, EAP_TNC),
+ PLUGIN_DEPENDS(EAP_SERVER, EAP_TTLS),
+ PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
+ PLUGIN_CALLBACK(eap_method_register, eap_tnc_create_peer),
+ PLUGIN_PROVIDE(EAP_PEER, EAP_TNC),
+ PLUGIN_DEPENDS(EAP_PEER, EAP_TTLS),
+ PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
+ };
+ *features = f;
+ return countof(f);
+}
+
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);
}
@@ -44,16 +57,11 @@ plugin_t *eap_tnc_plugin_create()
INIT(this,
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.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/eap_ttls/Makefile.am b/src/libcharon/plugins/eap_ttls/Makefile.am
index 94ce5cc1e..8cc82cc2e 100644
--- a/src/libcharon/plugins/eap_ttls/Makefile.am
+++ b/src/libcharon/plugins/eap_ttls/Makefile.am
@@ -1,6 +1,7 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libradius
AM_CFLAGS = -rdynamic
diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in
index d0d5341e2..b41fbd719 100644
--- a/src/libcharon/plugins/eap_ttls/Makefile.in
+++ b/src/libcharon/plugins/eap_ttls/Makefile.in
@@ -197,6 +197,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -205,6 +208,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -221,11 +225,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -269,6 +275,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -280,7 +287,8 @@ 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
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libradius
AM_CFLAGS = -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-eap-ttls.la
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.c b/src/libcharon/plugins/eap_ttls/eap_ttls.c
index 7193bc9f0..ace62f6b9 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls.c
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls.c
@@ -156,7 +156,8 @@ static eap_ttls_t *eap_ttls_create(identification_t *server,
"charon.plugins.eap-ttls.max_message_count", MAX_MESSAGE_COUNT);
include_length = lib->settings->get_bool(lib->settings,
"charon.plugins.eap-ttls.include_length", TRUE);
- tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TTLS, application);
+ tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_TTLS,
+ application, NULL);
this->tls_eap = tls_eap_create(EAP_TTLS, tls, frag_size, max_msg_count,
include_length);
if (!this->tls_eap)
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c
index 0eb5e94be..0d531c437 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c
@@ -54,7 +54,7 @@ struct private_eap_ttls_avp_t {
};
METHOD(eap_ttls_avp_t, build, void,
- private_eap_ttls_avp_t *this, tls_writer_t *writer, chunk_t data)
+ private_eap_ttls_avp_t *this, bio_writer_t *writer, chunk_t data)
{
char zero_padding[] = { 0x00, 0x00, 0x00 };
chunk_t avp_padding;
@@ -73,14 +73,14 @@ METHOD(eap_ttls_avp_t, build, void,
}
METHOD(eap_ttls_avp_t, process, status_t,
- private_eap_ttls_avp_t* this, tls_reader_t *reader, chunk_t *data)
+ private_eap_ttls_avp_t* this, bio_reader_t *reader, chunk_t *data)
{
size_t len;
chunk_t buf;
if (this->process_header)
{
- tls_reader_t *header;
+ bio_reader_t *header;
u_int32_t avp_code;
u_int8_t avp_flags;
u_int32_t avp_len;
@@ -110,7 +110,7 @@ METHOD(eap_ttls_avp_t, process, status_t,
}
/* parse AVP header */
- header = tls_reader_create(this->input);
+ header = bio_reader_create(this->input);
success = header->read_uint32(header, &avp_code) &&
header->read_uint8(header, &avp_flags) &&
header->read_uint24(header, &avp_len);
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h
index cad1d9c56..e56d92fc2 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_avp.h
@@ -25,8 +25,8 @@ typedef struct eap_ttls_avp_t eap_ttls_avp_t;
#include <library.h>
-#include <tls_reader.h>
-#include <tls_writer.h>
+#include <bio/bio_reader.h>
+#include <bio/bio_writer.h>
/**
* EAP-TTLS Attribute-Value Pair (AVP) handler.
@@ -43,7 +43,7 @@ struct eap_ttls_avp_t {
* - 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,
+ status_t (*process)(eap_ttls_avp_t *this, bio_reader_t *reader,
chunk_t *data);
/**
@@ -52,7 +52,7 @@ struct eap_ttls_avp_t {
* @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);
+ void (*build)(eap_ttls_avp_t *this, bio_writer_t *writer, chunk_t data);
/**
* Destroy a eap_ttls_application_t.
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
index 931eb2e89..4b6897b1d 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_peer.c
@@ -18,7 +18,7 @@
#include <debug.h>
#include <daemon.h>
-
+#include <radius_message.h>
#include <sa/authenticators/eap/eap_method.h>
typedef struct private_eap_ttls_peer_t private_eap_ttls_peer_t;
@@ -64,10 +64,8 @@ struct private_eap_ttls_peer_t {
eap_ttls_avp_t *avp;
};
-#define MAX_RADIUS_ATTRIBUTE_SIZE 253
-
METHOD(tls_application_t, process, status_t,
- private_eap_ttls_peer_t *this, tls_reader_t *reader)
+ private_eap_ttls_peer_t *this, bio_reader_t *reader)
{
chunk_t avp_data = chunk_empty;
chunk_t eap_data = chunk_empty;
@@ -229,7 +227,7 @@ METHOD(tls_application_t, process, status_t,
}
METHOD(tls_application_t, build, status_t,
- private_eap_ttls_peer_t *this, tls_writer_t *writer)
+ private_eap_ttls_peer_t *this, bio_writer_t *writer)
{
chunk_t data;
eap_code_t code;
diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c
index cbc3929bb..7ccbc9381 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_plugin.c
@@ -25,13 +25,31 @@ METHOD(plugin_t, get_name, char*,
return "eap-ttls";
}
+METHOD(plugin_t, get_features, int,
+ eap_ttls_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(eap_method_register, eap_ttls_create_server),
+ PLUGIN_PROVIDE(EAP_SERVER, EAP_TTLS),
+ PLUGIN_DEPENDS(EAP_SERVER, EAP_IDENTITY),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_CALLBACK(eap_method_register, eap_ttls_create_peer),
+ PLUGIN_PROVIDE(EAP_PEER, EAP_TTLS),
+ PLUGIN_DEPENDS(EAP_PEER, EAP_IDENTITY),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ };
+ *features = f;
+ return countof(f);
+}
+
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);
}
@@ -45,15 +63,10 @@ plugin_t *eap_ttls_plugin_create()
INIT(this,
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.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_server.c b/src/libcharon/plugins/eap_ttls/eap_ttls_server.c
index 835cd7306..3c46993b7 100644
--- a/src/libcharon/plugins/eap_ttls/eap_ttls_server.c
+++ b/src/libcharon/plugins/eap_ttls/eap_ttls_server.c
@@ -135,7 +135,7 @@ static status_t start_phase2_tnc(private_eap_ttls_server_t *this)
}
METHOD(tls_application_t, process, status_t,
- private_eap_ttls_server_t *this, tls_reader_t *reader)
+ private_eap_ttls_server_t *this, bio_reader_t *reader)
{
chunk_t data = chunk_empty;
status_t status;
@@ -284,7 +284,7 @@ METHOD(tls_application_t, process, status_t,
}
METHOD(tls_application_t, build, status_t,
- private_eap_ttls_server_t *this, tls_writer_t *writer)
+ private_eap_ttls_server_t *this, bio_writer_t *writer)
{
chunk_t data;
eap_code_t code;
diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in
index 4ba29472d..cfb51933c 100644
--- a/src/libcharon/plugins/farp/Makefile.in
+++ b/src/libcharon/plugins/farp/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/farp/farp_listener.c b/src/libcharon/plugins/farp/farp_listener.c
index 8eed49778..d1df4cc27 100644
--- a/src/libcharon/plugins/farp/farp_listener.c
+++ b/src/libcharon/plugins/farp/farp_listener.c
@@ -15,7 +15,7 @@
#include "farp_listener.h"
-#include <utils/hashtable.h>
+#include <utils/linked_list.h>
#include <threading/rwlock.h>
typedef struct private_farp_listener_t private_farp_listener_t;
@@ -31,9 +31,9 @@ struct private_farp_listener_t {
farp_listener_t public;
/**
- * Hashtable with active virtual IPs
+ * List with entry_t
*/
- hashtable_t *ips;
+ linked_list_t *entries;
/**
* RWlock for IP list
@@ -42,88 +42,99 @@ struct private_farp_listener_t {
};
/**
- * Hashtable hash function
+ * Traffic selector cache entry
*/
-static u_int hash(host_t *key)
+typedef struct {
+ /** list of local selectors */
+ linked_list_t *local;
+ /** list of remote selectors */
+ linked_list_t *remote;
+ /** reqid of CHILD_SA */
+ u_int32_t reqid;
+} entry_t;
+
+METHOD(listener_t, child_updown, bool,
+ private_farp_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
+ bool up)
{
- return chunk_hash(key->get_address(key));
-}
-
-/**
- * Hashtable equals function
- */
-static bool equals(host_t *a, host_t *b)
-{
- return a->ip_equals(a, b);
-}
+ enumerator_t *enumerator;
+ entry_t *entry;
-METHOD(listener_t, ike_updown, bool,
- private_farp_listener_t *this, ike_sa_t *ike_sa, bool up)
-{
- if (!up)
+ if (up)
{
- host_t *ip;
-
- ip = ike_sa->get_virtual_ip(ike_sa, FALSE);
- if (ip)
- {
- this->lock->write_lock(this->lock);
- ip = this->ips->remove(this->ips, ip);
- this->lock->unlock(this->lock);
- DESTROY_IF(ip);
- }
+ INIT(entry,
+ .local = child_sa->get_traffic_selectors(child_sa, TRUE),
+ .remote = child_sa->get_traffic_selectors(child_sa, FALSE),
+ .reqid = child_sa->get_reqid(child_sa),
+ );
+ entry->local = entry->local->clone_offset(entry->local,
+ offsetof(traffic_selector_t, clone));
+ entry->remote = entry->remote->clone_offset(entry->remote,
+ offsetof(traffic_selector_t, clone));
+
+ this->lock->write_lock(this->lock);
+ this->entries->insert_last(this->entries, entry);
+ this->lock->unlock(this->lock);
}
- return TRUE;
-}
-
-METHOD(listener_t, message_hook, bool,
- private_farp_listener_t *this, ike_sa_t *ike_sa,
- message_t *message, bool incoming)
-{
- if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED &&
- message->get_exchange_type(message) == IKE_AUTH &&
- !message->get_request(message))
+ else
{
- host_t *ip;
-
- ip = ike_sa->get_virtual_ip(ike_sa, FALSE);
- if (ip)
+ this->lock->write_lock(this->lock);
+ enumerator = this->entries->create_enumerator(this->entries);
+ while (enumerator->enumerate(enumerator, &entry))
{
- ip = ip->clone(ip);
- this->lock->write_lock(this->lock);
- ip = this->ips->put(this->ips, ip, ip);
- this->lock->unlock(this->lock);
- DESTROY_IF(ip);
+ if (entry->reqid == child_sa->get_reqid(child_sa))
+ {
+ this->entries->remove_at(this->entries, enumerator);
+ entry->local->destroy_offset(entry->local,
+ offsetof(traffic_selector_t, destroy));
+ entry->remote->destroy_offset(entry->remote,
+ offsetof(traffic_selector_t, destroy));
+ free(entry);
+ }
}
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
}
return TRUE;
}
-METHOD(farp_listener_t, is_active, bool,
- private_farp_listener_t *this, host_t *ip)
+METHOD(farp_listener_t, has_tunnel, bool,
+ private_farp_listener_t *this, host_t *local, host_t *remote)
{
- bool active;
+ enumerator_t *entries, *locals, *remotes;
+ traffic_selector_t *ts;
+ bool found = FALSE;
+ entry_t *entry;
this->lock->read_lock(this->lock);
- active = this->ips->get(this->ips, ip) != NULL;
+ entries = this->entries->create_enumerator(this->entries);
+ while (!found && entries->enumerate(entries, &entry))
+ {
+ remotes = entry->remote->create_enumerator(entry->remote);
+ while (!found && remotes->enumerate(remotes, &ts))
+ {
+ if (ts->includes(ts, remote))
+ {
+ locals = entry->local->create_enumerator(entry->local);
+ while (!found && locals->enumerate(locals, &ts))
+ {
+ found = ts->includes(ts, local);
+ }
+ locals->destroy(locals);
+ }
+ }
+ remotes->destroy(remotes);
+ }
+ entries->destroy(entries);
this->lock->unlock(this->lock);
- return active;
+
+ return found;
}
METHOD(farp_listener_t, destroy, void,
private_farp_listener_t *this)
{
- enumerator_t *enumerator;
- host_t *key, *value;
-
- enumerator = this->ips->create_enumerator(this->ips);
- while (enumerator->enumerate(enumerator, &key, &value))
- {
- value->destroy(value);
- }
- enumerator->destroy(enumerator);
- this->ips->destroy(this->ips);
-
+ this->entries->destroy(this->entries);
this->lock->destroy(this->lock);
free(this);
}
@@ -138,14 +149,12 @@ farp_listener_t *farp_listener_create()
INIT(this,
.public = {
.listener = {
- .ike_updown = _ike_updown,
- .message = _message_hook,
+ .child_updown = _child_updown,
},
- .is_active = _is_active,
+ .has_tunnel = _has_tunnel,
.destroy = _destroy,
},
- .ips = hashtable_create((hashtable_hash_t)hash,
- (hashtable_equals_t)equals, 8),
+ .entries = linked_list_create(),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
);
diff --git a/src/libcharon/plugins/farp/farp_listener.h b/src/libcharon/plugins/farp/farp_listener.h
index bd96d7a1c..3155f60e2 100644
--- a/src/libcharon/plugins/farp/farp_listener.h
+++ b/src/libcharon/plugins/farp/farp_listener.h
@@ -37,12 +37,13 @@ struct farp_listener_t {
listener_t listener;
/**
- * Check if a given IP is currently used as virtual IP by a peer.
+ * Check if we have a tunnel between two IP addresses.
*
- * @param ip IP to check
- * @return TRUE if IP is an active virtual IP
+ * @param local local IP
+ * @param remote remote IP
+ * @return TRUE if a tunnel is active
*/
- bool (*is_active)(farp_listener_t *this, host_t *ip);
+ bool (*has_tunnel)(farp_listener_t *this, host_t *local, host_t *remote);
/**
* Destroy a farp_listener_t.
diff --git a/src/libcharon/plugins/farp/farp_spoofer.c b/src/libcharon/plugins/farp/farp_spoofer.c
index a904a6538..587a3a74e 100644
--- a/src/libcharon/plugins/farp/farp_spoofer.c
+++ b/src/libcharon/plugins/farp/farp_spoofer.c
@@ -108,7 +108,7 @@ static job_requeue_t receive_arp(private_farp_spoofer_t *this)
arp_t arp;
int oldstate;
ssize_t len;
- host_t *ip;
+ host_t *local, *remote;
oldstate = thread_cancelability(TRUE);
len = recvfrom(this->skt, &arp, sizeof(arp), 0,
@@ -117,16 +117,16 @@ static job_requeue_t receive_arp(private_farp_spoofer_t *this)
if (len == sizeof(arp))
{
- ip = host_create_from_chunk(AF_INET,
+ local = host_create_from_chunk(AF_INET,
+ chunk_create((char*)&arp.sender_ip, 4), 0);
+ remote = host_create_from_chunk(AF_INET,
chunk_create((char*)&arp.target_ip, 4), 0);
- if (ip)
+ if (this->listener->has_tunnel(this->listener, local, remote))
{
- if (this->listener->is_active(this->listener, ip))
- {
- send_arp(this, &arp, &addr);
- }
- ip->destroy(ip);
+ send_arp(this, &arp, &addr);
}
+ local->destroy(local);
+ remote->destroy(remote);
}
return JOB_REQUEUE_DIRECT;
@@ -189,8 +189,8 @@ farp_spoofer_t *farp_spoofer_create(farp_listener_t *listener)
return NULL;
}
- this->job = callback_job_create((callback_job_cb_t)receive_arp,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive_arp,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
diff --git a/src/libcharon/plugins/ha/Makefile.am b/src/libcharon/plugins/ha/Makefile.am
index 0df1b8d91..bc1b49d48 100644
--- a/src/libcharon/plugins/ha/Makefile.am
+++ b/src/libcharon/plugins/ha/Makefile.am
@@ -1,5 +1,5 @@
-INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \
+INCLUDES = -I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon
AM_CFLAGS = -rdynamic -DIPSEC_PIDDIR=\"${piddir}\"
diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in
index fe72c5c8e..c66a550cd 100644
--- a/src/libcharon/plugins/ha/Makefile.in
+++ b/src/libcharon/plugins/ha/Makefile.in
@@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +205,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +222,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -276,7 +283,7 @@ 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 \
+INCLUDES = -I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon
AM_CFLAGS = -rdynamic -DIPSEC_PIDDIR=\"${piddir}\"
diff --git a/src/libcharon/plugins/ha/ha_cache.c b/src/libcharon/plugins/ha/ha_cache.c
index 9ff3fd5ff..970a8a2b9 100644
--- a/src/libcharon/plugins/ha/ha_cache.c
+++ b/src/libcharon/plugins/ha/ha_cache.c
@@ -196,22 +196,37 @@ METHOD(ha_cache_t, delete_, void,
*/
static status_t rekey_children(ike_sa_t *ike_sa)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
child_sa_t *child_sa;
status_t status = SUCCESS;
- iterator = ike_sa->create_child_sa_iterator(ike_sa);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
- DBG1(DBG_CFG, "resyncing CHILD_SA");
- status = ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE));
+ if (ike_sa->supports_extension(ike_sa, EXT_MS_WINDOWS) &&
+ ike_sa->has_condition(ike_sa, COND_NAT_THERE))
+ {
+ /* NATed Windows clients don't accept CHILD_SA rekeying, but fail
+ * with an "invalid situation" error. We just close the CHILD_SA,
+ * Windows will reestablish it immediately if required. */
+ DBG1(DBG_CFG, "resyncing CHILD_SA using a delete");
+ status = ike_sa->delete_child_sa(ike_sa,
+ child_sa->get_protocol(child_sa),
+ child_sa->get_spi(child_sa, TRUE));
+ }
+ else
+ {
+ DBG1(DBG_CFG, "resyncing CHILD_SA using a rekey");
+ status = ike_sa->rekey_child_sa(ike_sa,
+ child_sa->get_protocol(child_sa),
+ child_sa->get_spi(child_sa, TRUE));
+ }
if (status == DESTROY_ME)
{
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return status;
}
@@ -228,7 +243,7 @@ static void rekey_segment(private_ha_cache_t *this, u_int segment)
list = linked_list_create();
enumerator = charon->ike_sa_manager->create_enumerator(
- charon->ike_sa_manager);
+ charon->ike_sa_manager, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED &&
@@ -355,8 +370,8 @@ ha_cache_t *ha_cache_create(ha_kernel_t *kernel, ha_socket_t *socket,
{
/* request a resync as soon as we are up */
lib->scheduler->schedule_job(lib->scheduler, (job_t*)
- callback_job_create((callback_job_cb_t)request_resync,
- this, NULL, NULL), 1);
+ callback_job_create_with_prio((callback_job_cb_t)request_resync,
+ this, NULL, NULL, JOB_PRIO_CRITICAL), 1);
}
return &this->public;
}
diff --git a/src/libcharon/plugins/ha/ha_ctl.c b/src/libcharon/plugins/ha/ha_ctl.c
index 15f7824f9..9c99807ed 100644
--- a/src/libcharon/plugins/ha/ha_ctl.c
+++ b/src/libcharon/plugins/ha/ha_ctl.c
@@ -141,8 +141,8 @@ ha_ctl_t *ha_ctl_create(ha_segments_t *segments, ha_cache_t *cache)
strerror(errno));
}
- this->job = callback_job_create((callback_job_cb_t)dispatch_fifo,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)dispatch_fifo,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
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 0d0df8dd1..994f91d20 100644
--- a/src/libcharon/plugins/ha/ha_dispatcher.c
+++ b/src/libcharon/plugins/ha/ha_dispatcher.c
@@ -220,7 +220,7 @@ static void process_ike_update(private_ha_dispatcher_t *this,
ike_sa_t *ike_sa = NULL;
peer_cfg_t *peer_cfg = NULL;
auth_cfg_t *auth;
- bool received_vip = FALSE;
+ bool received_vip = FALSE, first_peer_addr = TRUE;
enumerator = message->create_attribute_enumerator(message);
while (enumerator->enumerate(enumerator, &attribute, &value))
@@ -260,9 +260,13 @@ static void process_ike_update(private_ha_dispatcher_t *this,
ike_sa->set_virtual_ip(ike_sa, FALSE, value.host);
received_vip = TRUE;
break;
- case HA_ADDITIONAL_ADDR:
- ike_sa->add_additional_address(ike_sa,
- value.host->clone(value.host));
+ case HA_PEER_ADDR:
+ if (first_peer_addr)
+ {
+ ike_sa->clear_peer_addresses(ike_sa);
+ first_peer_addr = FALSE;
+ }
+ ike_sa->add_peer_address(ike_sa, value.host->clone(value.host));
break;
case HA_CONFIG_NAME:
peer_cfg = charon->backends->get_peer_cfg_by_name(
@@ -281,6 +285,10 @@ static void process_ike_update(private_ha_dispatcher_t *this,
set_extension(ike_sa, value.u32, EXT_NATT);
set_extension(ike_sa, value.u32, EXT_MOBIKE);
set_extension(ike_sa, value.u32, EXT_HASH_AND_URL);
+ set_extension(ike_sa, value.u32, EXT_MULTIPLE_AUTH);
+ set_extension(ike_sa, value.u32, EXT_STRONGSWAN);
+ set_extension(ike_sa, value.u32, EXT_EAP_ONLY_AUTHENTICATION);
+ set_extension(ike_sa, value.u32, EXT_MS_WINDOWS);
break;
case HA_CONDITIONS:
set_condition(ike_sa, value.u32, COND_NAT_ANY);
@@ -290,6 +298,7 @@ static void process_ike_update(private_ha_dispatcher_t *this,
set_condition(ike_sa, value.u32, COND_EAP_AUTHENTICATED);
set_condition(ike_sa, value.u32, COND_CERTREQ_SEEN);
set_condition(ike_sa, value.u32, COND_ORIGINAL_INITIATOR);
+ set_condition(ike_sa, value.u32, COND_STALE);
break;
default:
break;
@@ -872,8 +881,8 @@ ha_dispatcher_t *ha_dispatcher_create(ha_socket_t *socket,
.kernel = kernel,
.attr = attr,
);
- this->job = callback_job_create((callback_job_cb_t)dispatch,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)dispatch,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
diff --git a/src/libcharon/plugins/ha/ha_ike.c b/src/libcharon/plugins/ha/ha_ike.c
index 1efba4e8f..e818aec9c 100644
--- a/src/libcharon/plugins/ha/ha_ike.c
+++ b/src/libcharon/plugins/ha/ha_ike.c
@@ -143,7 +143,7 @@ METHOD(listener_t, ike_updown, bool,
if (up)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
peer_cfg_t *peer_cfg;
u_int32_t extension, condition;
host_t *addr;
@@ -158,11 +158,16 @@ METHOD(listener_t, ike_updown, bool,
| copy_condition(ike_sa, COND_NAT_FAKE)
| copy_condition(ike_sa, COND_EAP_AUTHENTICATED)
| copy_condition(ike_sa, COND_CERTREQ_SEEN)
- | copy_condition(ike_sa, COND_ORIGINAL_INITIATOR);
+ | copy_condition(ike_sa, COND_ORIGINAL_INITIATOR)
+ | copy_condition(ike_sa, COND_STALE);
extension = copy_extension(ike_sa, EXT_NATT)
| copy_extension(ike_sa, EXT_MOBIKE)
- | copy_extension(ike_sa, EXT_HASH_AND_URL);
+ | copy_extension(ike_sa, EXT_HASH_AND_URL)
+ | copy_extension(ike_sa, EXT_MULTIPLE_AUTH)
+ | copy_extension(ike_sa, EXT_STRONGSWAN)
+ | copy_extension(ike_sa, EXT_EAP_ONLY_AUTHENTICATION)
+ | copy_extension(ike_sa, EXT_MS_WINDOWS);
id = ike_sa->get_id(ike_sa);
@@ -180,12 +185,12 @@ METHOD(listener_t, ike_updown, bool,
m->add_attribute(m, HA_CONDITIONS, condition);
m->add_attribute(m, HA_EXTENSIONS, extension);
m->add_attribute(m, HA_CONFIG_NAME, peer_cfg->get_name(peer_cfg));
- iterator = ike_sa->create_additional_address_iterator(ike_sa);
- while (iterator->iterate(iterator, (void**)&addr))
+ enumerator = ike_sa->create_peer_address_enumerator(ike_sa);
+ while (enumerator->enumerate(enumerator, (void**)&addr))
{
- m->add_attribute(m, HA_ADDITIONAL_ADDR, addr);
+ m->add_attribute(m, HA_PEER_ADDR, addr);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
else
{
diff --git a/src/libcharon/plugins/ha/ha_kernel.c b/src/libcharon/plugins/ha/ha_kernel.c
index 56bdbf454..2377a2630 100644
--- a/src/libcharon/plugins/ha/ha_kernel.c
+++ b/src/libcharon/plugins/ha/ha_kernel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Martin Willi
+ * Copyright (C) 2009-2011 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,7 +18,7 @@
typedef u_int32_t u32;
typedef u_int8_t u8;
-#include <linux/jhash.h>
+#include <sys/utsname.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
@@ -28,6 +28,16 @@ typedef u_int8_t u8;
#define CLUSTERIP_DIR "/proc/net/ipt_CLUSTERIP"
+/**
+ * Versions of jhash used in the Linux kernel
+ */
+typedef enum {
+ /* old variant, http://burtleburtle.net/bob/c/lookup2.c */
+ JHASH_LOOKUP2,
+ /* new variant, http://burtleburtle.net/bob/c/lookup3.c, since 2.6.37 */
+ JHASH_LOOKUP3,
+} jhash_version_t;
+
typedef struct private_ha_kernel_t private_ha_kernel_t;
/**
@@ -41,17 +51,98 @@ struct private_ha_kernel_t {
ha_kernel_t public;
/**
- * Init value for jhash
+ * Total number of ClusterIP segments
*/
- u_int initval;
+ u_int count;
/**
- * Total number of ClusterIP segments
+ * jhash version the kernel uses
*/
- u_int count;
+ jhash_version_t version;
};
/**
+ * Get the jhash version based on the uname().release
+ */
+static jhash_version_t get_jhash_version()
+{
+ struct utsname utsname;
+ int a, b, c;
+
+ if (uname(&utsname) == 0)
+ {
+ switch (sscanf(utsname.release, "%d.%d.%d", &a, &b, &c))
+ {
+ case 3:
+ if (a == 2 && b == 6)
+ {
+ if (c < 37)
+ {
+ DBG1(DBG_CFG, "detected Linux %d.%d.%d, using old "
+ "jhash", a, b, c);
+ return JHASH_LOOKUP2;
+ }
+ DBG1(DBG_CFG, "detected Linux %d.%d.%d, using new "
+ "jhash", a, b, c);
+ return JHASH_LOOKUP3;
+ }
+ /* FALL */
+ case 2:
+ DBG1(DBG_CFG, "detected Linux %d.%d, using new jhash", a, b);
+ return JHASH_LOOKUP3;
+ default:
+ break;
+ }
+ }
+ DBG1(DBG_CFG, "detecting Linux version failed, using new jhash");
+ return JHASH_LOOKUP3;
+}
+
+/**
+ * Rotate 32 bit word x by k bits
+ */
+#define jhash_rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+/**
+ * jhash algorithm of two words, as used in kernel (using 0 as initval)
+ */
+static u_int32_t jhash(jhash_version_t version, u_int32_t a, u_int32_t b)
+{
+ u_int32_t c = 0;
+
+ switch (version)
+ {
+ case JHASH_LOOKUP2:
+ a += 0x9e3779b9;
+ b += 0x9e3779b9;
+
+ a -= b; a -= c; a ^= (c >> 13);
+ b -= c; b -= a; b ^= (a << 8);
+ c -= a; c -= b; c ^= (b >> 13);
+ a -= b; a -= c; a ^= (c >> 12);
+ b -= c; b -= a; b ^= (a << 16);
+ c -= a; c -= b; c ^= (b >> 5);
+ a -= b; a -= c; a ^= (c >> 3);
+ b -= c; b -= a; b ^= (a << 10);
+ c -= a; c -= b; c ^= (b >> 15);
+ break;
+ case JHASH_LOOKUP3:
+ a += 0xdeadbeef;
+ b += 0xdeadbeef;
+
+ c ^= b; c -= jhash_rot(b, 14);
+ a ^= c; a -= jhash_rot(c, 11);
+ b ^= a; b -= jhash_rot(a, 25);
+ c ^= b; c -= jhash_rot(b, 16);
+ a ^= c; a -= jhash_rot(c, 4);
+ b ^= a; b -= jhash_rot(a, 14);
+ c ^= b; c -= jhash_rot(b, 24);
+ break;
+ }
+ return c;
+}
+
+/**
* Segmentate a calculated hash
*/
static u_int hash2segment(private_ha_kernel_t *this, u_int64_t hash)
@@ -78,7 +169,7 @@ METHOD(ha_kernel_t, get_segment, u_int,
u_int32_t addr;
addr = host2int(host);
- hash = jhash_1word(ntohl(addr), this->initval);
+ hash = jhash(this->version, ntohl(addr), 0);
return hash2segment(this, hash);
}
@@ -90,7 +181,7 @@ METHOD(ha_kernel_t, get_segment_spi, u_int,
u_int32_t addr;
addr = host2int(host);
- hash = jhash_2words(ntohl(addr), ntohl(spi), this->initval);
+ hash = jhash(this->version, ntohl(addr), ntohl(spi));
return hash2segment(this, hash);
}
@@ -100,7 +191,7 @@ METHOD(ha_kernel_t, get_segment_int, u_int,
{
unsigned long hash;
- hash = jhash_1word(ntohl(n), this->initval);
+ hash = jhash(this->version, ntohl(n), 0);
return hash2segment(this, hash);
}
@@ -123,7 +214,7 @@ static void enable_disable(private_ha_kernel_t *this, u_int segment,
file, strerror(errno));
return;
}
- if (write(fd, cmd, strlen(cmd) == -1))
+ if (write(fd, cmd, strlen(cmd)) == -1)
{
DBG1(DBG_CFG, "writing to CLUSTERIP file '%s' failed: %s",
file, strerror(errno));
@@ -149,6 +240,7 @@ static segment_mask_t get_active(private_ha_kernel_t *this, char *file)
return 0;
}
len = read(fd, buf, sizeof(buf)-1);
+ close(fd);
if (len == -1)
{
DBG1(DBG_CFG, "reading from CLUSTERIP file '%s' failed: %s",
@@ -182,11 +274,14 @@ METHOD(ha_kernel_t, activate, void,
char *file;
enumerator = enumerator_create_directory(CLUSTERIP_DIR);
- while (enumerator->enumerate(enumerator, NULL, &file, NULL))
+ if (enumerator)
{
- enable_disable(this, segment, file, TRUE);
+ while (enumerator->enumerate(enumerator, NULL, &file, NULL))
+ {
+ enable_disable(this, segment, file, TRUE);
+ }
+ enumerator->destroy(enumerator);
}
- enumerator->destroy(enumerator);
}
METHOD(ha_kernel_t, deactivate, void,
@@ -196,11 +291,14 @@ METHOD(ha_kernel_t, deactivate, void,
char *file;
enumerator = enumerator_create_directory(CLUSTERIP_DIR);
- while (enumerator->enumerate(enumerator, NULL, &file, NULL))
+ if (enumerator)
{
- enable_disable(this, segment, file, FALSE);
+ while (enumerator->enumerate(enumerator, NULL, &file, NULL))
+ {
+ enable_disable(this, segment, file, FALSE);
+ }
+ enumerator->destroy(enumerator);
}
- enumerator->destroy(enumerator);
}
/**
@@ -214,23 +312,26 @@ static void disable_all(private_ha_kernel_t *this)
int i;
enumerator = enumerator_create_directory(CLUSTERIP_DIR);
- while (enumerator->enumerate(enumerator, NULL, &file, NULL))
+ if (enumerator)
{
- if (chown(file, charon->uid, charon->gid) != 0)
+ while (enumerator->enumerate(enumerator, NULL, &file, NULL))
{
- DBG1(DBG_CFG, "changing ClusterIP permissions failed: %s",
- strerror(errno));
- }
- active = get_active(this, file);
- for (i = 1; i <= this->count; i++)
- {
- if (active & SEGMENTS_BIT(i))
+ if (chown(file, charon->uid, charon->gid) != 0)
{
- enable_disable(this, i, file, FALSE);
+ DBG1(DBG_CFG, "changing ClusterIP permissions failed: %s",
+ strerror(errno));
+ }
+ active = get_active(this, file);
+ for (i = 1; i <= this->count; i++)
+ {
+ if (active & SEGMENTS_BIT(i))
+ {
+ enable_disable(this, i, file, FALSE);
+ }
}
}
+ enumerator->destroy(enumerator);
}
- enumerator->destroy(enumerator);
}
METHOD(ha_kernel_t, destroy, void,
@@ -255,7 +356,7 @@ ha_kernel_t *ha_kernel_create(u_int count)
.deactivate = _deactivate,
.destroy = _destroy,
},
- .initval = 0,
+ .version = get_jhash_version(),
.count = count,
);
diff --git a/src/libcharon/plugins/ha/ha_message.c b/src/libcharon/plugins/ha/ha_message.c
index f98f78dd4..810109a5d 100644
--- a/src/libcharon/plugins/ha/ha_message.c
+++ b/src/libcharon/plugins/ha/ha_message.c
@@ -184,7 +184,7 @@ METHOD(ha_message_t, add_attribute, void,
case HA_REMOTE_ADDR:
case HA_LOCAL_VIP:
case HA_REMOTE_VIP:
- case HA_ADDITIONAL_ADDR:
+ case HA_PEER_ADDR:
{
host_encoding_t *enc;
host_t *host;
@@ -386,7 +386,7 @@ METHOD(enumerator_t, attribute_enumerate, bool,
case HA_REMOTE_ADDR:
case HA_LOCAL_VIP:
case HA_REMOTE_VIP:
- case HA_ADDITIONAL_ADDR:
+ case HA_PEER_ADDR:
{
host_encoding_t *enc;
diff --git a/src/libcharon/plugins/ha/ha_message.h b/src/libcharon/plugins/ha/ha_message.h
index 1f8eabd62..d0323d7a0 100644
--- a/src/libcharon/plugins/ha/ha_message.h
+++ b/src/libcharon/plugins/ha/ha_message.h
@@ -98,8 +98,8 @@ enum ha_message_attribute_t {
HA_LOCAL_VIP,
/** host_t*, remote virtual IP */
HA_REMOTE_VIP,
- /** host_t*, additional MOBIKE peer address */
- HA_ADDITIONAL_ADDR,
+ /** host_t*, known peer addresses (used for MOBIKE) */
+ HA_PEER_ADDR,
/** u_int8_t, initiator of an exchange, TRUE for local */
HA_INITIATOR,
/** chunk_t, initiators nonce */
diff --git a/src/libcharon/plugins/ha/ha_segments.c b/src/libcharon/plugins/ha/ha_segments.c
index 7c7bef851..c5a180683 100644
--- a/src/libcharon/plugins/ha/ha_segments.c
+++ b/src/libcharon/plugins/ha/ha_segments.c
@@ -166,7 +166,8 @@ static void enable_disable(private_ha_segments_t *this, u_int segment,
if (changes)
{
- enumerator = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager);
+ enumerator = charon->ike_sa_manager->create_enumerator(
+ charon->ike_sa_manager, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (ike_sa->get_state(ike_sa) != old)
@@ -279,8 +280,8 @@ static job_requeue_t watchdog(private_ha_segments_t *this)
*/
static void start_watchdog(private_ha_segments_t *this)
{
- this->job = callback_job_create((callback_job_cb_t)watchdog,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)watchdog,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
}
diff --git a/src/libcharon/plugins/ha/ha_segments.h b/src/libcharon/plugins/ha/ha_segments.h
index eb9e5c1d5..76da38082 100644
--- a/src/libcharon/plugins/ha/ha_segments.h
+++ b/src/libcharon/plugins/ha/ha_segments.h
@@ -55,7 +55,7 @@ struct ha_segments_t {
* Activate a set of IKE_SAs identified by a segment.
*
* @param segment numerical segment to takeover, 0 for all
- * @param notify wheter to notify other nodes about activation
+ * @param notify whether to notify other nodes about activation
*/
void (*activate)(ha_segments_t *this, u_int segment, bool notify);
@@ -63,7 +63,7 @@ struct ha_segments_t {
* Deactivate a set of IKE_SAs identified by a segment.
*
* @param segment numerical segment to takeover, 0 for all
- * @param notify wheter to notify other nodes about deactivation
+ * @param notify whether to notify other nodes about deactivation
*/
void (*deactivate)(ha_segments_t *this, u_int segment, bool notify);
diff --git a/src/libcharon/plugins/ha/ha_socket.c b/src/libcharon/plugins/ha/ha_socket.c
index 086178442..c02cf1021 100644
--- a/src/libcharon/plugins/ha/ha_socket.c
+++ b/src/libcharon/plugins/ha/ha_socket.c
@@ -105,8 +105,8 @@ METHOD(ha_socket_t, push, void,
.fd = this->fd,
);
- job = callback_job_create((callback_job_cb_t)send_message,
- data, (void*)job_data_destroy, NULL);
+ job = callback_job_create_with_prio((callback_job_cb_t)send_message,
+ data, (void*)job_data_destroy, NULL, JOB_PRIO_HIGH);
lib->processor->queue_job(lib->processor, (job_t*)job);
return;
}
diff --git a/src/libcharon/plugins/led/Makefile.in b/src/libcharon/plugins/led/Makefile.in
index db3a7c702..56684ee11 100644
--- a/src/libcharon/plugins/led/Makefile.in
+++ b/src/libcharon/plugins/led/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/led/led_listener.c b/src/libcharon/plugins/led/led_listener.c
index 18def8005..4aae2abe5 100644
--- a/src/libcharon/plugins/led/led_listener.c
+++ b/src/libcharon/plugins/led/led_listener.c
@@ -156,9 +156,9 @@ static void blink_activity(private_led_listener_t *this)
{
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);
+ lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)
+ callback_job_create_with_prio((callback_job_cb_t)reset_activity_led,
+ this, NULL, NULL, JOB_PRIO_CRITICAL), this->blink_time);
this->mutex->unlock(this->mutex);
}
}
diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in
index 1e9a5fe82..bbd20d4b9 100644
--- a/src/libcharon/plugins/load_tester/Makefile.in
+++ b/src/libcharon/plugins/load_tester/Makefile.in
@@ -197,6 +197,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -205,6 +208,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -221,11 +225,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -269,6 +275,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c
index 71391d593..6bc6f91e4 100644
--- a/src/libcharon/plugins/load_tester/load_tester_config.c
+++ b/src/libcharon/plugins/load_tester/load_tester_config.c
@@ -65,6 +65,16 @@ struct private_load_tester_config_t {
char *responder_auth;
/**
+ * Initiator ID to enforce
+ */
+ char *initiator_id;
+
+ /**
+ * Responder ID to enforce
+ */
+ char *responder_id;
+
+ /**
* IKE_SA rekeying delay
*/
u_int ike_rekey;
@@ -75,6 +85,11 @@ struct private_load_tester_config_t {
u_int child_rekey;
/**
+ * DPD check delay
+ */
+ u_int dpd_delay;
+
+ /**
* incremental numbering of generated configs
*/
u_int num;
@@ -102,24 +117,46 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
enumerator = enumerator_create_token(str, "|", " ");
while (enumerator->enumerate(enumerator, &str))
{
+ id = NULL;
auth = auth_cfg_create();
rnd++;
- if (streq(str, "psk"))
- { /* PSK authentication, use FQDNs */
- class = AUTH_CLASS_PSK;
- if ((local && !num) || (!local && num))
+ if (this->initiator_id)
+ {
+ if ((local && num) || (!local && !num))
{
- id = identification_create_from_string("srv.strongswan.org");
+ snprintf(buf, sizeof(buf), this->initiator_id, num, rnd);
+ id = identification_create_from_string(buf);
}
- else if (local)
+ }
+ if (this->responder_id)
+ {
+ if ((local && !num) || (!local && num))
{
- snprintf(buf, sizeof(buf), "c%d-r%d.strongswan.org", num, rnd);
+ snprintf(buf, sizeof(buf), this->responder_id, num, rnd);
id = identification_create_from_string(buf);
}
- else
+ }
+
+ if (streq(str, "psk"))
+ { /* PSK authentication, use FQDNs */
+ class = AUTH_CLASS_PSK;
+ if (!id)
{
- id = identification_create_from_string("*.strongswan.org");
+ if ((local && !num) || (!local && num))
+ {
+ id = identification_create_from_string("srv.strongswan.org");
+ }
+ else if (local)
+ {
+ snprintf(buf, sizeof(buf), "c%d-r%d.strongswan.org",
+ num, rnd);
+ id = identification_create_from_string(buf);
+ }
+ else
+ {
+ id = identification_create_from_string("*.strongswan.org");
+ }
}
}
else if (strneq(str, "eap", strlen("eap")))
@@ -133,14 +170,18 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
auth->add(auth, AUTH_RULE_EAP_TYPE, type);
}
}
- if (local && num)
+ if (!id)
{
- snprintf(buf, sizeof(buf), "1%.10d%.4d@strongswan.org", num, rnd);
- id = identification_create_from_string(buf);
- }
- else
- {
- id = identification_create_from_encoding(ID_ANY, chunk_empty);
+ if (local && num)
+ {
+ snprintf(buf, sizeof(buf), "1%.10d%.4d@strongswan.org",
+ num, rnd);
+ id = identification_create_from_string(buf);
+ }
+ else
+ {
+ id = identification_create_from_encoding(ID_ANY, chunk_empty);
+ }
}
}
else
@@ -152,21 +193,24 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
}
/* certificate authentication, use distinguished names */
class = AUTH_CLASS_PUBKEY;
- if ((local && !num) || (!local && num))
- {
- id = identification_create_from_string(
- "CN=srv, OU=load-test, O=strongSwan");
- }
- else if (local)
+ if (!id)
{
- snprintf(buf, sizeof(buf),
- "CN=c%d-r%d, OU=load-test, O=strongSwan", num, rnd);
- id = identification_create_from_string(buf);
- }
- else
- {
- id = identification_create_from_string(
- "CN=*, OU=load-test, O=strongSwan");
+ if ((local && !num) || (!local && num))
+ {
+ id = identification_create_from_string(
+ "CN=srv, OU=load-test, O=strongSwan");
+ }
+ else if (local)
+ {
+ snprintf(buf, sizeof(buf),
+ "CN=c%d-r%d, OU=load-test, O=strongSwan", num, rnd);
+ id = identification_create_from_string(buf);
+ }
+ else
+ {
+ id = identification_create_from_string(
+ "CN=*, OU=load-test, O=strongSwan");
+ }
}
}
auth->add(auth, AUTH_RULE_AUTH_CLASS, class);
@@ -209,7 +253,7 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
CERT_SEND_IF_ASKED, UNIQUE_NO, 1, /* keytries */
this->ike_rekey, 0, /* rekey, reauth */
0, this->ike_rekey, /* jitter, overtime */
- FALSE, 0, /* mobike, dpddelay */
+ FALSE, this->dpd_delay, /* mobike, dpddelay */
this->vip ? this->vip->clone(this->vip) : NULL,
this->pool, FALSE, NULL, NULL);
if (num)
@@ -236,21 +280,15 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
return peer_cfg;
}
-/**
- * Implementation of backend_t.create_peer_cfg_enumerator.
- */
-static enumerator_t* create_peer_cfg_enumerator(private_load_tester_config_t *this,
- identification_t *me,
- identification_t *other)
+METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
+ private_load_tester_config_t *this,
+ identification_t *me, identification_t *other)
{
return enumerator_create_single(this->peer_cfg, NULL);
}
-/**
- * Implementation of backend_t.create_ike_cfg_enumerator.
- */
-static enumerator_t* create_ike_cfg_enumerator(private_load_tester_config_t *this,
- host_t *me, host_t *other)
+METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
+ private_load_tester_config_t *this, host_t *me, host_t *other)
{
ike_cfg_t *ike_cfg;
@@ -258,11 +296,8 @@ static enumerator_t* create_ike_cfg_enumerator(private_load_tester_config_t *thi
return enumerator_create_single(ike_cfg, NULL);
}
-/**
- * implements backend_t.get_peer_cfg_by_name.
- */
-static peer_cfg_t *get_peer_cfg_by_name(private_load_tester_config_t *this,
- char *name)
+METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
+ private_load_tester_config_t *this, char *name)
{
if (streq(name, "load-test"))
{
@@ -271,10 +306,8 @@ static peer_cfg_t *get_peer_cfg_by_name(private_load_tester_config_t *this,
return NULL;
}
-/**
- * Implementation of load_tester_config_t.destroy.
- */
-static void destroy(private_load_tester_config_t *this)
+METHOD(load_tester_config_t, destroy, void,
+ private_load_tester_config_t *this)
{
this->peer_cfg->destroy(this->peer_cfg);
DESTROY_IF(this->proposal);
@@ -287,14 +320,20 @@ static void destroy(private_load_tester_config_t *this)
*/
load_tester_config_t *load_tester_config_create()
{
- private_load_tester_config_t *this = malloc_thing(private_load_tester_config_t);
-
- this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator;
- this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator;
- this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
- this->public.destroy = (void(*)(load_tester_config_t*))destroy;
+ private_load_tester_config_t *this;
+
+ INIT(this,
+ .public = {
+ .backend = {
+ .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
+ .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
+ .get_peer_cfg_by_name = _get_peer_cfg_by_name,
+ },
+ .destroy = _destroy,
+ },
+ .num = 1,
+ );
- this->vip = NULL;
if (lib->settings->get_bool(lib->settings,
"charon.plugins.load-tester.request_virtual_ip", FALSE))
{
@@ -317,16 +356,21 @@ load_tester_config_t *load_tester_config_create()
"charon.plugins.load-tester.ike_rekey", 0);
this->child_rekey = lib->settings->get_int(lib->settings,
"charon.plugins.load-tester.child_rekey", 600);
+ this->dpd_delay = lib->settings->get_int(lib->settings,
+ "charon.plugins.load-tester.dpd_delay", 0);
this->initiator_auth = lib->settings->get_str(lib->settings,
"charon.plugins.load-tester.initiator_auth", "pubkey");
this->responder_auth = lib->settings->get_str(lib->settings,
"charon.plugins.load-tester.responder_auth", "pubkey");
+ this->initiator_id = lib->settings->get_str(lib->settings,
+ "charon.plugins.load-tester.initiator_id", NULL);
+ this->responder_id = lib->settings->get_str(lib->settings,
+ "charon.plugins.load-tester.responder_id", NULL);
this->port = lib->settings->get_int(lib->settings,
"charon.plugins.load-tester.dynamic_port", 0);
- this->num = 1;
this->peer_cfg = generate_config(this, 0);
return &this->public;
diff --git a/src/libcharon/plugins/load_tester/load_tester_creds.c b/src/libcharon/plugins/load_tester/load_tester_creds.c
index 890703c1a..c34ea73c5 100644
--- a/src/libcharon/plugins/load_tester/load_tester_creds.c
+++ b/src/libcharon/plugins/load_tester/load_tester_creds.c
@@ -49,9 +49,14 @@ struct private_load_tester_creds_t {
u_int32_t serial;
/**
- * Preshared key
+ * Preshared key for IKE
*/
- shared_key_t *shared;
+ shared_key_t *psk;
+
+ /**
+ * Password for EAP
+ */
+ shared_key_t *pwd;
};
/**
@@ -131,7 +136,7 @@ CwMLbJ7vQqwPHXRitDmNkEOK9H+vRnDf
-----END CERTIFICATE-----
*/
-char cert[] = {
+static char cert[] = {
0x30,0x82,0x01,0xf4,0x30,0x82,0x01,0x5d,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x00,
0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,
0x37,0x31,0x0c,0x30,0x0a,0x06,0x03,0x55,0x04,0x03,0x13,0x03,0x73,0x72,0x76,0x31,
@@ -168,17 +173,17 @@ char cert[] = {
/**
- * A preshared key
+ * Default IKE preshared key
*/
-static char psk[] = {
- 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08
-};
+static char *default_psk = "default-psk";
/**
- * Implements credential_set_t.create_private_enumerator
+ * Default EAP password for EAP
*/
-static enumerator_t* create_private_enumerator(private_load_tester_creds_t *this,
- key_type_t type, identification_t *id)
+static char *default_pwd = "default-pwd";
+
+METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
+ private_load_tester_creds_t *this, key_type_t type, identification_t *id)
{
if (this->private == NULL)
{
@@ -198,12 +203,9 @@ static enumerator_t* create_private_enumerator(private_load_tester_creds_t *this
return enumerator_create_single(this->private, NULL);
}
-/**
- * Implements credential_set_t.create_cert_enumerator
- */
-static enumerator_t* create_cert_enumerator(private_load_tester_creds_t *this,
- certificate_type_t cert, key_type_t key,
- identification_t *id, bool trusted)
+METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
+ private_load_tester_creds_t *this, certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
{
certificate_t *peer_cert;
public_key_t *peer_key, *ca_key;
@@ -265,49 +267,87 @@ static enumerator_t* create_cert_enumerator(private_load_tester_creds_t *this,
}
/**
- * Implements credential_set_t.create_shared_enumerator
+ * Filter function for shared keys, returning ID matches
*/
-static enumerator_t* create_shared_enumerator(private_load_tester_creds_t *this,
- shared_key_type_t type, identification_t *me,
- identification_t *other)
+static bool shared_filter(void *null, shared_key_t **in, shared_key_t **out,
+ void **un1, id_match_t *me, void **un2, id_match_t *other)
+{
+ *out = *in;
+ if (me)
+ {
+ *me = ID_MATCH_ANY;
+ }
+ if (other)
+ {
+ *other = ID_MATCH_ANY;
+ }
+ return TRUE;
+}
+
+METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
+ private_load_tester_creds_t *this, shared_key_type_t type,
+ identification_t *me, identification_t *other)
{
- return enumerator_create_single(this->shared, NULL);
+ shared_key_t *shared;
+
+ switch (type)
+ {
+ case SHARED_IKE:
+ shared = this->psk;
+ break;
+ case SHARED_EAP:
+ shared = this->pwd;
+ break;
+ default:
+ return NULL;
+ }
+ return enumerator_create_filter(enumerator_create_single(shared, NULL),
+ (void*)shared_filter, NULL, NULL);
}
-/**
- * Implementation of load_tester_creds_t.destroy
- */
-static void destroy(private_load_tester_creds_t *this)
+METHOD(load_tester_creds_t, destroy, void,
+ private_load_tester_creds_t *this)
{
DESTROY_IF(this->private);
DESTROY_IF(this->ca);
- this->shared->destroy(this->shared);
+ this->psk->destroy(this->psk);
+ this->pwd->destroy(this->pwd);
free(this);
}
load_tester_creds_t *load_tester_creds_create()
{
- private_load_tester_creds_t *this = malloc_thing(private_load_tester_creds_t);
-
- this->public.credential_set.create_shared_enumerator = (enumerator_t*(*)(credential_set_t*, shared_key_type_t, identification_t*, identification_t*))create_shared_enumerator;
- this->public.credential_set.create_private_enumerator = (enumerator_t*(*) (credential_set_t*, key_type_t, identification_t*))create_private_enumerator;
- this->public.credential_set.create_cert_enumerator = (enumerator_t*(*) (credential_set_t*, certificate_type_t, key_type_t,identification_t *, bool))create_cert_enumerator;
- this->public.credential_set.create_cdp_enumerator = (enumerator_t*(*) (credential_set_t *,certificate_type_t, identification_t *))return_null;
- this->public.credential_set.cache_cert = (void (*)(credential_set_t *, certificate_t *))nop;
- this->public.destroy = (void(*) (load_tester_creds_t*))destroy;
-
- this->private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
- BUILD_BLOB_ASN1_DER, chunk_create(private, sizeof(private)),
- BUILD_END);
+ private_load_tester_creds_t *this;
+ char *pwd, *psk;
- this->ca = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, chunk_create(cert, sizeof(cert)),
- BUILD_X509_FLAG, X509_CA,
- BUILD_END);
+ psk = lib->settings->get_str(lib->settings,
+ "charon.plugins.load-tester.preshared_key", default_psk);
+ pwd = lib->settings->get_str(lib->settings,
+ "charon.plugins.load-tester.eap_password", default_pwd);
- this->shared = shared_key_create(SHARED_IKE,
- chunk_clone(chunk_create(psk, sizeof(psk))));
- this->serial = 0;
+ INIT(this,
+ .public = {
+ .credential_set = {
+ .create_shared_enumerator = _create_shared_enumerator,
+ .create_private_enumerator = _create_private_enumerator,
+ .create_cert_enumerator = _create_cert_enumerator,
+ .create_cdp_enumerator = (void*)return_null,
+ .cache_cert = (void*)nop,
+ },
+ .destroy = _destroy,
+ },
+ .private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
+ BUILD_BLOB_ASN1_DER, chunk_create(private, sizeof(private)),
+ BUILD_END),
+ .ca = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER, chunk_create(cert, sizeof(cert)),
+ BUILD_X509_FLAG, X509_CA,
+ BUILD_END),
+ .psk = shared_key_create(SHARED_IKE,
+ chunk_clone(chunk_create(psk, strlen(psk)))),
+ .pwd = shared_key_create(SHARED_EAP,
+ chunk_clone(chunk_create(pwd, strlen(pwd)))),
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
index fdec5300e..440197260 100644
--- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c
+++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c
@@ -35,75 +35,75 @@ struct private_load_tester_ipsec_t {
};
METHOD(kernel_ipsec_t, get_spi, status_t,
- private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
- u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+ private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
+ u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
{
*spi = ++this->spi;
return SUCCESS;
}
METHOD(kernel_ipsec_t, get_cpi, status_t,
- private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
+ private_load_tester_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_load_tester_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
- u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
- u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
- u_int16_t cpi, bool encap, bool esn, bool inbound,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+ private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
+ u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
+ u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
+ u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
+ u_int16_t cpi, bool encap, bool esn, bool inbound,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
{
return SUCCESS;
}
METHOD(kernel_ipsec_t, update_sa, status_t,
- 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)
+ 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)
{
return SUCCESS;
}
METHOD(kernel_ipsec_t, query_sa, status_t,
- private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t spi, u_int8_t protocol, mark_t mark, u_int64_t *bytes)
+ private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
+ 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, u_int8_t protocol, u_int16_t cpi, mark_t mark)
+ private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
+ u_int32_t spi, u_int8_t protocol, u_int16_t cpi, mark_t mark)
{
return SUCCESS;
}
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, policy_type_t type, ipsec_sa_cfg_t *sa,
- mark_t mark, bool routed)
+ 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, policy_type_t type, ipsec_sa_cfg_t *sa,
+ mark_t mark, policy_priority_t priority)
{
return SUCCESS;
}
METHOD(kernel_ipsec_t, query_policy, status_t,
- private_load_tester_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)
+ private_load_tester_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)
{
- *use_time = time_monotonic(NULL);
+ *use_time = 1;
return SUCCESS;
}
METHOD(kernel_ipsec_t, del_policy, status_t,
- private_load_tester_ipsec_t *this, traffic_selector_t *src_ts,
- traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
- bool unrouted)
+ private_load_tester_ipsec_t *this, traffic_selector_t *src_ts,
+ traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+ mark_t mark, policy_priority_t priority)
{
return SUCCESS;
}
@@ -115,7 +115,7 @@ METHOD(kernel_ipsec_t, bypass_socket, bool,
}
METHOD(kernel_ipsec_t, destroy, void,
- private_load_tester_ipsec_t *this)
+ private_load_tester_ipsec_t *this)
{
free(this);
}
@@ -136,9 +136,11 @@ load_tester_ipsec_t *load_tester_ipsec_create()
.update_sa = _update_sa,
.query_sa = _query_sa,
.del_sa = _del_sa,
+ .flush_sas = (void*)return_failed,
.add_policy = _add_policy,
.query_policy = _query_policy,
.del_policy = _del_policy,
+ .flush_policies = (void*)return_failed,
.bypass_socket = _bypass_socket,
.destroy = _destroy,
},
diff --git a/src/libcharon/plugins/load_tester/load_tester_listener.c b/src/libcharon/plugins/load_tester/load_tester_listener.c
index cf6dd0562..7c96f7d97 100644
--- a/src/libcharon/plugins/load_tester/load_tester_listener.c
+++ b/src/libcharon/plugins/load_tester/load_tester_listener.c
@@ -42,21 +42,25 @@ struct private_load_tester_listener_t {
u_int established;
/**
+ * Number of terminated SAs
+ */
+ u_int terminated;
+
+ /**
* Shutdown the daemon if we have established this SA count
*/
u_int shutdown_on;
};
-/**
- * Implementation of listener_t.ike_state_change
- */
-static bool ike_state_change(private_load_tester_listener_t *this,
- ike_sa_t *ike_sa, ike_sa_state_t state)
+METHOD(listener_t, ike_updown, bool,
+ private_load_tester_listener_t *this, ike_sa_t *ike_sa, bool up)
{
- if (state == IKE_ESTABLISHED)
+ if (up)
{
ike_sa_id_t *id = ike_sa->get_id(ike_sa);
+ this->established++;
+
if (this->delete_after_established)
{
lib->processor->queue_job(lib->processor,
@@ -65,37 +69,48 @@ static bool ike_state_change(private_load_tester_listener_t *this,
if (id->is_initiator(id))
{
- if (this->shutdown_on == ++this->established)
+ if (this->shutdown_on == this->established)
{
DBG1(DBG_CFG, "load-test complete, raising SIGTERM");
kill(0, SIGTERM);
}
}
}
+ else
+ {
+ this->terminated++;
+ }
return TRUE;
}
-/**
- * Implementation of load_tester_listener_t.destroy
- */
-static void destroy(private_load_tester_listener_t *this)
+METHOD(load_tester_listener_t, get_established, u_int,
+ private_load_tester_listener_t *this)
+{
+ return this->established - this->terminated;
+}
+
+METHOD(load_tester_listener_t, destroy, void,
+ private_load_tester_listener_t *this)
{
free(this);
}
load_tester_listener_t *load_tester_listener_create(u_int shutdown_on)
{
- private_load_tester_listener_t *this = malloc_thing(private_load_tester_listener_t);
-
- memset(&this->public.listener, 0, sizeof(listener_t));
- this->public.listener.ike_state_change = (void*)ike_state_change;
- this->public.destroy = (void(*) (load_tester_listener_t*))destroy;
-
- this->delete_after_established = lib->settings->get_bool(lib->settings,
- "charon.plugins.load-tester.delete_after_established", FALSE);
-
- this->shutdown_on = shutdown_on;
- this->established = 0;
+ private_load_tester_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .ike_updown = _ike_updown,
+ },
+ .get_established = _get_established,
+ .destroy = _destroy,
+ },
+ .delete_after_established = lib->settings->get_bool(lib->settings,
+ "charon.plugins.load-tester.delete_after_established", FALSE),
+ .shutdown_on = shutdown_on,
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/load_tester/load_tester_listener.h b/src/libcharon/plugins/load_tester/load_tester_listener.h
index b9599294c..2621798c8 100644
--- a/src/libcharon/plugins/load_tester/load_tester_listener.h
+++ b/src/libcharon/plugins/load_tester/load_tester_listener.h
@@ -36,6 +36,13 @@ struct load_tester_listener_t {
listener_t listener;
/**
+ * Get the number of established IKE_SAs.
+ *
+ * @return number of SAs currently established
+ */
+ u_int (*get_established)(load_tester_listener_t *this);
+
+ /**
* Destroy the backend.
*/
void (*destroy)(load_tester_listener_t *this);
diff --git a/src/libcharon/plugins/load_tester/load_tester_plugin.c b/src/libcharon/plugins/load_tester/load_tester_plugin.c
index 94115e307..b260a9741 100644
--- a/src/libcharon/plugins/load_tester/load_tester_plugin.c
+++ b/src/libcharon/plugins/load_tester/load_tester_plugin.c
@@ -68,7 +68,7 @@ struct private_load_tester_plugin_t {
int initiators;
/**
- * currenly running initiators
+ * currently running initiators
*/
int running;
@@ -78,6 +78,11 @@ struct private_load_tester_plugin_t {
int delay;
/**
+ * Throttle initiation if half-open IKE_SA count reached
+ */
+ int init_limit;
+
+ /**
* mutex to lock running field
*/
mutex_t *mutex;
@@ -96,10 +101,7 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this)
int i, s = 0, ms = 0;
this->mutex->lock(this->mutex);
- if (!this->running)
- {
- this->running = this->initiators;
- }
+ this->running++;
this->mutex->unlock(this->mutex);
if (this->delay)
{
@@ -113,6 +115,23 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this)
child_cfg_t *child_cfg = NULL;
enumerator_t *enumerator;
+ if (this->init_limit)
+ {
+ while ((charon->ike_sa_manager->get_count(charon->ike_sa_manager) -
+ this->listener->get_established(this->listener)) >
+ this->init_limit)
+ {
+ if (s)
+ {
+ sleep(s);
+ }
+ if (ms)
+ {
+ usleep(ms * 1000);
+ }
+ }
+ }
+
peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends,
"load-test");
if (!peer_cfg)
@@ -129,7 +148,7 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this)
charon->controller->initiate(charon->controller,
peer_cfg, child_cfg->get_ref(child_cfg),
- NULL, NULL);
+ NULL, NULL, 0);
if (s)
{
sleep(s);
@@ -141,8 +160,8 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this)
}
this->mutex->lock(this->mutex);
this->running--;
- this->mutex->unlock(this->mutex);
this->condvar->signal(this->condvar);
+ this->mutex->unlock(this->mutex);
return JOB_REQUEUE_NONE;
}
@@ -206,25 +225,26 @@ plugin_t *load_tester_plugin_create()
"charon.plugins.load-tester.iterations", 1),
.initiators = lib->settings->get_int(lib->settings,
"charon.plugins.load-tester.initiators", 0),
+ .init_limit = lib->settings->get_int(lib->settings,
+ "charon.plugins.load-tester.init_limit", 0),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
.config = load_tester_config_create(),
.creds = load_tester_creds_create(),
- .listener = load_tester_listener_create(shutdown_on),
);
lib->crypto->add_dh(lib->crypto, MODP_NULL, plugin_name,
(dh_constructor_t)load_tester_diffie_hellman_create);
charon->backends->add_backend(charon->backends, &this->config->backend);
lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
- charon->bus->add_listener(charon->bus, &this->listener->listener);
if (lib->settings->get_bool(lib->settings,
"charon.plugins.load-tester.shutdown_when_complete", 0))
{
shutdown_on = this->iterations * this->initiators;
}
-
+ this->listener = load_tester_listener_create(shutdown_on);
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
if (lib->settings->get_bool(lib->settings,
"charon.plugins.load-tester.fake_kernel", FALSE))
@@ -232,12 +252,11 @@ plugin_t *load_tester_plugin_create()
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++)
{
- lib->processor->queue_job(lib->processor,
- (job_t*)callback_job_create((callback_job_cb_t)do_load_test,
- this, NULL, NULL));
+ lib->processor->queue_job(lib->processor, (job_t*)
+ callback_job_create_with_prio((callback_job_cb_t)do_load_test,
+ this, NULL, NULL, JOB_PRIO_CRITICAL));
}
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/maemo/Makefile.in b/src/libcharon/plugins/maemo/Makefile.in
index 27e72295c..d2b9d9a34 100644
--- a/src/libcharon/plugins/maemo/Makefile.in
+++ b/src/libcharon/plugins/maemo/Makefile.in
@@ -196,6 +196,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -204,6 +207,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -220,11 +224,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -268,6 +274,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/maemo/maemo_service.c b/src/libcharon/plugins/maemo/maemo_service.c
index 0e9fd8ccc..6675e1d21 100644
--- a/src/libcharon/plugins/maemo/maemo_service.c
+++ b/src/libcharon/plugins/maemo/maemo_service.c
@@ -217,7 +217,7 @@ static void disconnect(private_maemo_service_t *this)
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);
+ NULL, NULL, 0);
}
this->current = (g_free(this->current), NULL);
this->status = VPN_STATUS_DISCONNECTED;
@@ -502,7 +502,8 @@ maemo_service_t *maemo_service_create()
}
lib->processor->queue_job(lib->processor,
- (job_t*)callback_job_create((callback_job_cb_t)run, this, NULL, NULL));
+ (job_t*)callback_job_create_with_prio((callback_job_cb_t)run,
+ this, NULL, NULL, JOB_PRIO_CRITICAL));
return &this->public;
}
diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in
index 83b457b46..b8983ad21 100644
--- a/src/libcharon/plugins/medcli/Makefile.in
+++ b/src/libcharon/plugins/medcli/Makefile.in
@@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +205,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +222,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/medcli/medcli_config.c b/src/libcharon/plugins/medcli/medcli_config.c
index b5672dba9..ee3e95422 100644
--- a/src/libcharon/plugins/medcli/medcli_config.c
+++ b/src/libcharon/plugins/medcli/medcli_config.c
@@ -88,10 +88,8 @@ static traffic_selector_t *ts_from_string(char *str)
return traffic_selector_create_dynamic(0, 0, 65535);
}
-/**
- * implements backend_t.get_peer_cfg_by_name.
- */
-static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *name)
+METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
+ private_medcli_config_t *this, char *name)
{
enumerator_t *e;
peer_cfg_t *peer_cfg, *med_cfg;
@@ -192,11 +190,8 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
return peer_cfg;
}
-/**
- * Implementation of backend_t.create_ike_cfg_enumerator.
- */
-static enumerator_t* create_ike_cfg_enumerator(private_medcli_config_t *this,
- host_t *me, host_t *other)
+METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
+ private_medcli_config_t *this, host_t *me, host_t *other)
{
return enumerator_create_single(this->ike, NULL);
}
@@ -216,10 +211,8 @@ typedef struct {
int dpd;
} peer_enumerator_t;
-/**
- * Implementation of peer_enumerator_t.public.enumerate
- */
-static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
+METHOD(enumerator_t, peer_enumerator_enumerate, bool,
+ peer_enumerator_t *this, peer_cfg_t **cfg)
{
char *name, *local_net, *remote_net;
chunk_t me, other;
@@ -271,31 +264,29 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
return TRUE;
}
-/**
- * Implementation of peer_enumerator_t.public.destroy
- */
-static void peer_enumerator_destroy(peer_enumerator_t *this)
+METHOD(enumerator_t, peer_enumerator_destroy, void,
+ peer_enumerator_t *this)
{
DESTROY_IF(this->current);
this->inner->destroy(this->inner);
free(this);
}
-/**
- * Implementation of backend_t.create_peer_cfg_enumerator.
- */
-static enumerator_t* create_peer_cfg_enumerator(private_medcli_config_t *this,
- identification_t *me,
- identification_t *other)
+METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
+ private_medcli_config_t *this, identification_t *me,
+ identification_t *other)
{
- peer_enumerator_t *e = malloc_thing(peer_enumerator_t);
-
- e->current = NULL;
- e->ike = this->ike;
- e->rekey = this->rekey;
- e->dpd = this->dpd;
- e->public.enumerate = (void*)peer_enumerator_enumerate;
- e->public.destroy = (void*)peer_enumerator_destroy;
+ peer_enumerator_t *e;
+
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_peer_enumerator_enumerate,
+ .destroy = _peer_enumerator_destroy,
+ },
+ .ike = this->ike,
+ .rekey = this->rekey,
+ .dpd = this->dpd,
+ );
/* filter on IDs: NULL or ANY or matching KEY_ID */
e->inner = this->db->query(this->db,
@@ -335,7 +326,7 @@ static job_requeue_t initiate_config(peer_cfg_t *peer_cfg)
peer_cfg->get_ref(peer_cfg);
enumerator->destroy(enumerator);
charon->controller->initiate(charon->controller,
- peer_cfg, child_cfg, NULL, NULL);
+ peer_cfg, child_cfg, NULL, NULL, 0);
}
else
{
@@ -345,7 +336,7 @@ static job_requeue_t initiate_config(peer_cfg_t *peer_cfg)
}
/**
- * schedule initation of all "active" connections
+ * schedule initiation of all "active" connections
*/
static void schedule_autoinit(private_medcli_config_t *this)
{
@@ -374,10 +365,8 @@ static void schedule_autoinit(private_medcli_config_t *this)
}
}
-/**
- * Implementation of medcli_config_t.destroy.
- */
-static void destroy(private_medcli_config_t *this)
+METHOD(medcli_config_t, destroy, void,
+ private_medcli_config_t *this)
{
this->ike->destroy(this->ike);
free(this);
@@ -388,18 +377,23 @@ static void destroy(private_medcli_config_t *this)
*/
medcli_config_t *medcli_config_create(database_t *db)
{
- private_medcli_config_t *this = malloc_thing(private_medcli_config_t);
-
- this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator;
- this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator;
- this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
- this->public.destroy = (void(*)(medcli_config_t*))destroy;
-
- this->db = db;
- this->rekey = lib->settings->get_time(lib->settings, "medcli.rekey", 1200);
- this->dpd = lib->settings->get_time(lib->settings, "medcli.dpd", 300);
- this->ike = ike_cfg_create(FALSE, FALSE,
- "0.0.0.0", IKEV2_UDP_PORT, "0.0.0.0", IKEV2_UDP_PORT);
+ private_medcli_config_t *this;
+
+ INIT(this,
+ .public = {
+ .backend = {
+ .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
+ .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
+ .get_peer_cfg_by_name = _get_peer_cfg_by_name,
+ },
+ .destroy = _destroy,
+ },
+ .db = db,
+ .rekey = lib->settings->get_time(lib->settings, "medcli.rekey", 1200),
+ .dpd = lib->settings->get_time(lib->settings, "medcli.dpd", 300),
+ .ike = ike_cfg_create(FALSE, FALSE, "0.0.0.0", IKEV2_UDP_PORT,
+ "0.0.0.0", IKEV2_UDP_PORT),
+ );
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
schedule_autoinit(this);
diff --git a/src/libcharon/plugins/medcli/medcli_creds.c b/src/libcharon/plugins/medcli/medcli_creds.c
index 9729df3f5..9c4a0b756 100644
--- a/src/libcharon/plugins/medcli/medcli_creds.c
+++ b/src/libcharon/plugins/medcli/medcli_creds.c
@@ -49,11 +49,8 @@ typedef struct {
private_key_t *current;
} private_enumerator_t;
-/**
- * Implementation of private_enumerator_t.public.enumerate
- */
-static bool private_enumerator_enumerate(private_enumerator_t *this,
- private_key_t **key)
+METHOD(enumerator_t, private_enumerator_enumerate, bool,
+ private_enumerator_t *this, private_key_t **key)
{
chunk_t chunk;
@@ -73,21 +70,16 @@ static bool private_enumerator_enumerate(private_enumerator_t *this,
return FALSE;
}
-/**
- * Implementation of private_enumerator_t.public.destroy
- */
-static void private_enumerator_destroy(private_enumerator_t *this)
+METHOD(enumerator_t, private_enumerator_destroy, void,
+ private_enumerator_t *this)
{
DESTROY_IF(this->current);
this->inner->destroy(this->inner);
free(this);
}
-/**
- * Implementation of credential_set_t.create_private_enumerator.
- */
-static enumerator_t* create_private_enumerator(private_medcli_creds_t *this,
- key_type_t type, identification_t *id)
+METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
+ private_medcli_creds_t *this, key_type_t type, identification_t *id)
{
private_enumerator_t *e;
@@ -98,10 +90,12 @@ static enumerator_t* create_private_enumerator(private_medcli_creds_t *this,
return NULL;
}
- e = malloc_thing(private_enumerator_t);
- e->current = NULL;
- e->public.enumerate = (void*)private_enumerator_enumerate;
- e->public.destroy = (void*)private_enumerator_destroy;
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_private_enumerator_enumerate,
+ .destroy = _private_enumerator_destroy,
+ },
+ );
e->inner = this->db->query(this->db,
"SELECT PrivateKey FROM ClientConfig WHERE KeyId = ?",
DB_BLOB, id->get_encoding(id),
@@ -128,11 +122,8 @@ typedef struct {
key_type_t type;
} cert_enumerator_t;
-/**
- * Implementation of cert_enumerator_t.public.enumerate
- */
-static bool cert_enumerator_enumerate(cert_enumerator_t *this,
- certificate_t **cert)
+METHOD(enumerator_t, cert_enumerator_enumerate, bool,
+ cert_enumerator_t *this, certificate_t **cert)
{
public_key_t *public;
chunk_t chunk;
@@ -167,22 +158,17 @@ static bool cert_enumerator_enumerate(cert_enumerator_t *this,
return FALSE;
}
-/**
- * Implementation of cert_enumerator_t.public.destroy
- */
-static void cert_enumerator_destroy(cert_enumerator_t *this)
+METHOD(enumerator_t, cert_enumerator_destroy, void,
+ cert_enumerator_t *this)
{
DESTROY_IF(this->current);
this->inner->destroy(this->inner);
free(this);
}
-/**
- * Implementation of credential_set_t.create_cert_enumerator.
- */
-static enumerator_t* create_cert_enumerator(private_medcli_creds_t *this,
- certificate_type_t cert, key_type_t key,
- identification_t *id, bool trusted)
+METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
+ private_medcli_creds_t *this, certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
{
cert_enumerator_t *e;
@@ -192,11 +178,13 @@ static enumerator_t* create_cert_enumerator(private_medcli_creds_t *this,
return NULL;
}
- e = malloc_thing(cert_enumerator_t);
- e->current = NULL;
- e->type = key;
- e->public.enumerate = (void*)cert_enumerator_enumerate;
- e->public.destroy = (void*)cert_enumerator_destroy;
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_cert_enumerator_enumerate,
+ .destroy = _cert_enumerator_destroy,
+ },
+ .type = key,
+ );
e->inner = this->db->query(this->db,
"SELECT PublicKey FROM ClientConfig WHERE KeyId = ? UNION "
"SELECT PublicKey FROM MediationServerConfig WHERE KeyId = ? UNION "
@@ -213,10 +201,8 @@ static enumerator_t* create_cert_enumerator(private_medcli_creds_t *this,
return &e->public;
}
-/**
- * Implementation of backend_t.destroy.
- */
-static void destroy(private_medcli_creds_t *this)
+METHOD(medcli_creds_t, destroy, void,
+ private_medcli_creds_t *this)
{
free(this);
}
@@ -226,17 +212,21 @@ static void destroy(private_medcli_creds_t *this)
*/
medcli_creds_t *medcli_creds_create(database_t *db)
{
- private_medcli_creds_t *this = malloc_thing(private_medcli_creds_t);
-
- this->public.set.create_private_enumerator = (void*)create_private_enumerator;
- this->public.set.create_cert_enumerator = (void*)create_cert_enumerator;
- this->public.set.create_shared_enumerator = (void*)return_null;
- this->public.set.create_cdp_enumerator = (void*)return_null;
- this->public.set.cache_cert = (void*)nop;
-
- this->public.destroy = (void (*)(medcli_creds_t*))destroy;
-
- this->db = db;
+ private_medcli_creds_t *this;
+
+ INIT(this,
+ .public = {
+ .set = {
+ .create_private_enumerator = _create_private_enumerator,
+ .create_cert_enumerator = _create_cert_enumerator,
+ .create_shared_enumerator = (void*)return_null,
+ .create_cdp_enumerator = (void*)return_null,
+ .cache_cert = (void*)nop,
+ },
+ .destroy = _destroy,
+ },
+ .db = db,
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/medcli/medcli_listener.c b/src/libcharon/plugins/medcli/medcli_listener.c
index 142f02e6c..ba6b3d9d6 100644
--- a/src/libcharon/plugins/medcli/medcli_listener.c
+++ b/src/libcharon/plugins/medcli/medcli_listener.c
@@ -47,7 +47,7 @@ struct private_medcli_listener_t {
};
/**
- * Implementation of bus_listener_t.signal.
+ * Update connection status in the database
*/
static void set_state(private_medcli_listener_t *this, char *alias,
mediated_state_t state)
@@ -56,11 +56,9 @@ static void set_state(private_medcli_listener_t *this, char *alias,
"UPDATE Connection SET Status = ? WHERE Alias = ?",
DB_UINT, state, DB_TEXT, alias);
}
-/**
- * Implementation of listener_t.ike_state_change
- */
-static bool ike_state_change(private_medcli_listener_t *this,
- ike_sa_t *ike_sa, ike_sa_state_t state)
+
+METHOD(listener_t, ike_state_change, bool,
+ private_medcli_listener_t *this, ike_sa_t *ike_sa, ike_sa_state_t state)
{
if (ike_sa)
{
@@ -78,11 +76,9 @@ static bool ike_state_change(private_medcli_listener_t *this,
return TRUE;
}
-/**
- * Implementation of listener_t.child_state_change
- */
-static bool child_state_change(private_medcli_listener_t *this,
- ike_sa_t *ike_sa, child_sa_t *child_sa, child_sa_state_t state)
+METHOD(listener_t, child_state_change, bool,
+ private_medcli_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
+ child_sa_state_t state)
{
if (ike_sa && child_sa)
{
@@ -101,10 +97,8 @@ static bool child_state_change(private_medcli_listener_t *this,
return TRUE;
}
-/**
- * Implementation of backend_t.destroy.
- */
-static void destroy(private_medcli_listener_t *this)
+METHOD(medcli_listener_t, destroy, void,
+ private_medcli_listener_t *this)
{
this->db->execute(this->db, NULL, "UPDATE Connection SET Status = ?",
DB_UINT, STATE_DOWN);
@@ -116,15 +110,19 @@ static void destroy(private_medcli_listener_t *this)
*/
medcli_listener_t *medcli_listener_create(database_t *db)
{
- private_medcli_listener_t *this = malloc_thing(private_medcli_listener_t);
-
- memset(&this->public.listener, 0, sizeof(listener_t));
-
- this->public.listener.ike_state_change = (void*)ike_state_change;
- this->public.listener.child_state_change = (void*)child_state_change;
- this->public.destroy = (void (*)(medcli_listener_t*))destroy;
+ private_medcli_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .ike_state_change = _ike_state_change,
+ .child_state_change = _child_state_change,
+ },
+ .destroy = _destroy,
+ },
+ .db = db,
+ );
- this->db = db;
db->execute(db, NULL, "UPDATE Connection SET Status = ?",
DB_UINT, STATE_DOWN);
diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in
index 068f311a5..91df95cf0 100644
--- a/src/libcharon/plugins/medsrv/Makefile.in
+++ b/src/libcharon/plugins/medsrv/Makefile.in
@@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +205,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +222,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/medsrv/medsrv_config.c b/src/libcharon/plugins/medsrv/medsrv_config.c
index c23955ad0..6cacb34f6 100644
--- a/src/libcharon/plugins/medsrv/medsrv_config.c
+++ b/src/libcharon/plugins/medsrv/medsrv_config.c
@@ -52,29 +52,21 @@ struct private_medsrv_config_t {
ike_cfg_t *ike;
};
-/**
- * implements backend_t.get_peer_cfg_by_name.
- */
-static peer_cfg_t *get_peer_cfg_by_name(private_medsrv_config_t *this, char *name)
+METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
+ private_medsrv_config_t *this, char *name)
{
return NULL;
}
-/**
- * Implementation of backend_t.create_ike_cfg_enumerator.
- */
-static enumerator_t* create_ike_cfg_enumerator(private_medsrv_config_t *this,
- host_t *me, host_t *other)
+METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
+ private_medsrv_config_t *this, host_t *me, host_t *other)
{
return enumerator_create_single(this->ike, NULL);
}
-/**
- * Implementation of backend_t.create_peer_cfg_enumerator.
- */
-static enumerator_t* create_peer_cfg_enumerator(private_medsrv_config_t *this,
- identification_t *me,
- identification_t *other)
+METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
+ private_medsrv_config_t *this, identification_t *me,
+ identification_t *other)
{
enumerator_t *e;
@@ -98,11 +90,11 @@ static enumerator_t* create_peer_cfg_enumerator(private_medsrv_config_t *this,
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 */
- 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();
@@ -121,10 +113,8 @@ static enumerator_t* create_peer_cfg_enumerator(private_medsrv_config_t *this,
return NULL;
}
-/**
- * Implementation of medsrv_config_t.destroy.
- */
-static void destroy(private_medsrv_config_t *this)
+METHOD(medsrv_config_t, destroy, void,
+ private_medsrv_config_t *this)
{
this->ike->destroy(this->ike);
free(this);
@@ -135,18 +125,23 @@ static void destroy(private_medsrv_config_t *this)
*/
medsrv_config_t *medsrv_config_create(database_t *db)
{
- private_medsrv_config_t *this = malloc_thing(private_medsrv_config_t);
-
- this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator;
- this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator;
- this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
- this->public.destroy = (void(*)(medsrv_config_t*))destroy;
-
- this->db = db;
- this->rekey = lib->settings->get_time(lib->settings, "medsrv.rekey", 1200);
- this->dpd = lib->settings->get_time(lib->settings, "medsrv.dpd", 300);
- this->ike = ike_cfg_create(FALSE, FALSE,
- "0.0.0.0", IKEV2_UDP_PORT, "0.0.0.0", IKEV2_UDP_PORT);
+ private_medsrv_config_t *this;
+
+ INIT(this,
+ .public = {
+ .backend = {
+ .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
+ .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
+ .get_peer_cfg_by_name = _get_peer_cfg_by_name,
+ },
+ .destroy = _destroy,
+ },
+ .db = db,
+ .rekey = lib->settings->get_time(lib->settings, "medsrv.rekey", 1200),
+ .dpd = lib->settings->get_time(lib->settings, "medsrv.dpd", 300),
+ .ike = ike_cfg_create(FALSE, FALSE,
+ "0.0.0.0", IKEV2_UDP_PORT, "0.0.0.0", IKEV2_UDP_PORT),
+ );
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
return &this->public;
diff --git a/src/libcharon/plugins/medsrv/medsrv_creds.c b/src/libcharon/plugins/medsrv/medsrv_creds.c
index 8d1643908..3ae80f64c 100644
--- a/src/libcharon/plugins/medsrv/medsrv_creds.c
+++ b/src/libcharon/plugins/medsrv/medsrv_creds.c
@@ -51,11 +51,8 @@ typedef struct {
key_type_t type;
} cert_enumerator_t;
-/**
- * Implementation of cert_enumerator_t.public.enumerate
- */
-static bool cert_enumerator_enumerate(cert_enumerator_t *this,
- certificate_t **cert)
+METHOD(enumerator_t, cert_enumerator_enumerate, bool,
+ cert_enumerator_t *this, certificate_t **cert)
{
certificate_t *trusted;
public_key_t *public;
@@ -91,22 +88,17 @@ static bool cert_enumerator_enumerate(cert_enumerator_t *this,
return FALSE;
}
-/**
- * Implementation of cert_enumerator_t.public.destroy
- */
-static void cert_enumerator_destroy(cert_enumerator_t *this)
+METHOD(enumerator_t, cert_enumerator_destroy, void,
+ cert_enumerator_t *this)
{
DESTROY_IF(this->current);
this->inner->destroy(this->inner);
free(this);
}
-/**
- * Implementation of credential_set_t.create_cert_enumerator.
- */
-static enumerator_t* create_cert_enumerator(private_medsrv_creds_t *this,
- certificate_type_t cert, key_type_t key,
- identification_t *id, bool trusted)
+METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
+ private_medsrv_creds_t *this, certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
{
cert_enumerator_t *e;
@@ -116,15 +108,17 @@ static enumerator_t* create_cert_enumerator(private_medsrv_creds_t *this,
return NULL;
}
- e = malloc_thing(cert_enumerator_t);
- e->current = NULL;
- e->type = key;
- e->public.enumerate = (void*)cert_enumerator_enumerate;
- e->public.destroy = (void*)cert_enumerator_destroy;
- e->inner = this->db->query(this->db,
- "SELECT public_key FROM peer WHERE keyid = ?",
- DB_BLOB, id->get_encoding(id),
- DB_BLOB);
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_cert_enumerator_enumerate,
+ .destroy = _cert_enumerator_destroy,
+ },
+ .type = key,
+ .inner = this->db->query(this->db,
+ "SELECT public_key FROM peer WHERE keyid = ?",
+ DB_BLOB, id->get_encoding(id),
+ DB_BLOB),
+ );
if (!e->inner)
{
free(e);
@@ -133,10 +127,8 @@ static enumerator_t* create_cert_enumerator(private_medsrv_creds_t *this,
return &e->public;
}
-/**
- * Implementation of backend_t.destroy.
- */
-static void destroy(private_medsrv_creds_t *this)
+METHOD(medsrv_creds_t, destroy, void,
+ private_medsrv_creds_t *this)
{
free(this);
}
@@ -146,17 +138,21 @@ static void destroy(private_medsrv_creds_t *this)
*/
medsrv_creds_t *medsrv_creds_create(database_t *db)
{
- private_medsrv_creds_t *this = malloc_thing(private_medsrv_creds_t);
-
- this->public.set.create_private_enumerator = (void*)return_null;
- this->public.set.create_cert_enumerator = (void*)create_cert_enumerator;
- this->public.set.create_shared_enumerator = (void*)return_null;
- this->public.set.create_cdp_enumerator = (void*)return_null;
- this->public.set.cache_cert = (void*)nop;
-
- this->public.destroy = (void (*)(medsrv_creds_t*))destroy;
-
- this->db = db;
+ private_medsrv_creds_t *this;
+
+ INIT(this,
+ .public = {
+ .set = {
+ .create_private_enumerator = (void*)return_null,
+ .create_cert_enumerator = _create_cert_enumerator,
+ .create_shared_enumerator = (void*)return_null,
+ .create_cdp_enumerator = (void*)return_null,
+ .cache_cert = (void*)nop,
+ },
+ .destroy = _destroy,
+ },
+ .db = db,
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/nm/Makefile.in b/src/libcharon/plugins/nm/Makefile.in
index 308d27229..d9ad2388e 100644
--- a/src/libcharon/plugins/nm/Makefile.in
+++ b/src/libcharon/plugins/nm/Makefile.in
@@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -201,6 +204,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -217,11 +221,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/nm/nm_creds.c b/src/libcharon/plugins/nm/nm_creds.c
index ea98c056d..f8fae9504 100644
--- a/src/libcharon/plugins/nm/nm_creds.c
+++ b/src/libcharon/plugins/nm/nm_creds.c
@@ -170,11 +170,13 @@ static bool cert_filter(cert_data_t *data, certificate_t **in,
static enumerator_t *create_trusted_cert_enumerator(private_nm_creds_t *this,
key_type_t key, identification_t *id)
{
- cert_data_t *data = malloc_thing(cert_data_t);
+ cert_data_t *data;
- data->this = this;
- data->id = id;
- data->key = key;
+ INIT(data,
+ .this = this,
+ .id = id,
+ .key = key,
+ );
this->lock->read_lock(this->lock);
return enumerator_create_filter(
@@ -182,12 +184,9 @@ static enumerator_t *create_trusted_cert_enumerator(private_nm_creds_t *this,
(void*)cert_filter, data, (void*)cert_data_destroy);
}
-/**
- * Implements credential_set_t.create_cert_enumerator
- */
-static enumerator_t* create_cert_enumerator(private_nm_creds_t *this,
- certificate_type_t cert, key_type_t key,
- identification_t *id, bool trusted)
+METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
+ private_nm_creds_t *this, certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
{
if (id && this->usercert &&
id->equals(id, this->usercert->get_subject(this->usercert)))
@@ -201,11 +200,8 @@ static enumerator_t* create_cert_enumerator(private_nm_creds_t *this,
return NULL;
}
-/**
- * Implements credential_set_t.create_cert_enumerator
- */
-static enumerator_t* create_private_enumerator(private_nm_creds_t *this,
- key_type_t type, identification_t *id)
+METHOD(credential_set_t, create_private_enumerator, enumerator_t*,
+ private_nm_creds_t *this, key_type_t type, identification_t *id)
{
if (this->key == NULL)
{
@@ -238,11 +234,9 @@ typedef struct {
bool done;
} shared_enumerator_t;
-/**
- * enumerate function for shared enumerator
- */
-static bool shared_enumerate(shared_enumerator_t *this, shared_key_t **key,
- id_match_t *me, id_match_t *other)
+METHOD(enumerator_t, shared_enumerate, bool,
+ shared_enumerator_t *this, shared_key_t **key, id_match_t *me,
+ id_match_t *other)
{
if (this->done)
{
@@ -261,43 +255,41 @@ static bool shared_enumerate(shared_enumerator_t *this, shared_key_t **key,
return TRUE;
}
-/**
- * Destroy function for shared enumerator
- */
-static void shared_destroy(shared_enumerator_t *this)
+METHOD(enumerator_t, shared_destroy, void,
+ shared_enumerator_t *this)
{
this->key->destroy(this->key);
this->this->lock->unlock(this->this->lock);
free(this);
}
-/**
- * Implements credential_set_t.create_cert_enumerator
- */
-static enumerator_t* create_shared_enumerator(private_nm_creds_t *this,
- shared_key_type_t type, identification_t *me,
- identification_t *other)
+
+METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
+ private_nm_creds_t *this, shared_key_type_t type, identification_t *me,
+ identification_t *other)
{
shared_enumerator_t *enumerator;
chunk_t key;
+ this->lock->read_lock(this->lock);
+
switch (type)
{
case SHARED_EAP:
case SHARED_IKE:
if (!this->pass || !this->user)
{
- return NULL;
+ goto no_secret;
}
if (me && !me->equals(me, this->user))
{
- return NULL;
+ goto no_secret;
}
key = chunk_create(this->pass, strlen(this->pass));
break;
case SHARED_PRIVATE_KEY_PASS:
if (!this->keypass)
{
- return NULL;
+ goto no_secret;
}
key = chunk_create(this->keypass, strlen(this->keypass));
break;
@@ -305,28 +297,31 @@ static enumerator_t* create_shared_enumerator(private_nm_creds_t *this,
if (!this->keypass || !me ||
!chunk_equals(me->get_encoding(me), this->keyid))
{
- return NULL;
+ goto no_secret;
}
key = chunk_create(this->keypass, strlen(this->keypass));
break;
default:
- return NULL;
+ goto no_secret;
}
- enumerator = malloc_thing(shared_enumerator_t);
- enumerator->public.enumerate = (void*)shared_enumerate;
- enumerator->public.destroy = (void*)shared_destroy;
- enumerator->this = this;
- enumerator->done = FALSE;
- this->lock->read_lock(this->lock);
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)_shared_enumerate,
+ .destroy = _shared_destroy,
+ },
+ .this = this,
+ );
enumerator->key = shared_key_create(type, chunk_clone(key));
return &enumerator->public;
+
+no_secret:
+ this->lock->unlock(this->lock);
+ return NULL;
}
-/**
- * Implementation of nm_creds_t.add_certificate
- */
-static void add_certificate(private_nm_creds_t *this, certificate_t *cert)
+METHOD(nm_creds_t, add_certificate, void,
+ private_nm_creds_t *this, certificate_t *cert)
{
this->lock->write_lock(this->lock);
this->certs->insert_last(this->certs, cert);
@@ -359,10 +354,8 @@ static void load_ca_file(private_nm_creds_t *this, char *file)
}
}
-/**
- * Implementation of nm_creds_t.load_ca_dir
- */
-static void load_ca_dir(private_nm_creds_t *this, char *dir)
+METHOD(nm_creds_t, load_ca_dir, void,
+ private_nm_creds_t *this, char *dir)
{
enumerator_t *enumerator;
char *rel, *abs;
@@ -390,11 +383,8 @@ static void load_ca_dir(private_nm_creds_t *this, char *dir)
}
}
-/**
- * Implementation of nm_creds_t.set_password
- */
-static void set_username_password(private_nm_creds_t *this, identification_t *id,
- char *password)
+METHOD(nm_creds_t, set_username_password, void,
+ private_nm_creds_t *this, identification_t *id, char *password)
{
this->lock->write_lock(this->lock);
DESTROY_IF(this->user);
@@ -404,10 +394,8 @@ static void set_username_password(private_nm_creds_t *this, identification_t *id
this->lock->unlock(this->lock);
}
-/**
- * Implementation of nm_creds_t.set_key_password
- */
-static void set_key_password(private_nm_creds_t *this, char *password)
+METHOD(nm_creds_t, set_key_password, void,
+ private_nm_creds_t *this, char *password)
{
this->lock->write_lock(this->lock);
free(this->keypass);
@@ -415,10 +403,8 @@ static void set_key_password(private_nm_creds_t *this, char *password)
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)
+METHOD(nm_creds_t, set_pin, void,
+ private_nm_creds_t *this, chunk_t keyid, char *pin)
{
this->lock->write_lock(this->lock);
free(this->keypass);
@@ -428,11 +414,8 @@ static void set_pin(private_nm_creds_t *this, chunk_t keyid, char *pin)
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,
- private_key_t *key)
+METHOD(nm_creds_t, set_cert_and_key, void,
+ private_nm_creds_t *this, certificate_t *cert, private_key_t *key)
{
this->lock->write_lock(this->lock);
DESTROY_IF(this->key);
@@ -442,10 +425,8 @@ static void set_cert_and_key(private_nm_creds_t *this, certificate_t *cert,
this->lock->unlock(this->lock);
}
-/**
- * Implementation of nm_creds_t.clear
- */
-static void clear(private_nm_creds_t *this)
+METHOD(nm_creds_t, clear, void,
+ private_nm_creds_t *this)
{
certificate_t *cert;
@@ -467,10 +448,8 @@ static void clear(private_nm_creds_t *this)
this->keyid = chunk_empty;
}
-/**
- * Implementation of nm_creds_t.destroy
- */
-static void destroy(private_nm_creds_t *this)
+METHOD(nm_creds_t, destroy, void,
+ private_nm_creds_t *this)
{
clear(this);
this->certs->destroy(this->certs);
@@ -483,32 +462,29 @@ static void destroy(private_nm_creds_t *this)
*/
nm_creds_t *nm_creds_create()
{
- private_nm_creds_t *this = malloc_thing(private_nm_creds_t);
-
- this->public.set.create_private_enumerator = (void*)create_private_enumerator;
- this->public.set.create_cert_enumerator = (void*)create_cert_enumerator;
- this->public.set.create_shared_enumerator = (void*)create_shared_enumerator;
- this->public.set.create_cdp_enumerator = (void*)return_null;
- this->public.set.cache_cert = (void*)nop;
- 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;
-
- this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
-
- this->certs = linked_list_create();
- this->user = NULL;
- this->pass = NULL;
- this->usercert = NULL;
- this->key = NULL;
- this->keypass = NULL;
- this->keyid = chunk_empty;
+ private_nm_creds_t *this;
+ INIT(this,
+ .public = {
+ .set = {
+ .create_private_enumerator = _create_private_enumerator,
+ .create_cert_enumerator = _create_cert_enumerator,
+ .create_shared_enumerator = _create_shared_enumerator,
+ .create_cdp_enumerator = (void*)return_null,
+ .cache_cert = (void*)nop,
+ },
+ .add_certificate = _add_certificate,
+ .load_ca_dir = _load_ca_dir,
+ .set_username_password = _set_username_password,
+ .set_key_password = _set_key_password,
+ .set_pin = _set_pin,
+ .set_cert_and_key = _set_cert_and_key,
+ .clear = _clear,
+ .destroy = _destroy,
+ },
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ .certs = linked_list_create(),
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/nm/nm_handler.c b/src/libcharon/plugins/nm/nm_handler.c
index eacb54dda..408129ebe 100644
--- a/src/libcharon/plugins/nm/nm_handler.c
+++ b/src/libcharon/plugins/nm/nm_handler.c
@@ -40,11 +40,9 @@ struct private_nm_handler_t {
linked_list_t *nbns;
};
-/**
- * Implementation of attribute_handler_t.handle
- */
-static bool handle(private_nm_handler_t *this, identification_t *server,
- configuration_attribute_type_t type, chunk_t data)
+METHOD(attribute_handler_t, handle, bool,
+ private_nm_handler_t *this, identification_t *server,
+ configuration_attribute_type_t type, chunk_t data)
{
linked_list_t *list;
@@ -93,11 +91,8 @@ static bool enumerate_dns(enumerator_t *this,
return TRUE;
}
-/**
- * Implementation of attribute_handler_t.create_attribute_enumerator
- */
-static enumerator_t* create_attribute_enumerator(private_nm_handler_t *this,
- identification_t *server, host_t *vip)
+METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
+ private_nm_handler_t *this, identification_t *server, host_t *vip)
{
if (vip && vip->get_family(vip) == AF_INET)
{ /* no IPv6 attributes yet */
@@ -120,11 +115,8 @@ static bool filter_chunks(void* null, char **in, chunk_t *out)
return TRUE;
}
-/**
- * Implementation of nm_handler_t.create_enumerator
- */
-static enumerator_t* create_enumerator(private_nm_handler_t *this,
- configuration_attribute_type_t type)
+METHOD(nm_handler_t, create_enumerator, enumerator_t*,
+ private_nm_handler_t *this, configuration_attribute_type_t type)
{
linked_list_t *list;
@@ -143,10 +135,8 @@ static enumerator_t* create_enumerator(private_nm_handler_t *this,
(void*)filter_chunks, NULL, NULL);
}
-/**
- * Implementation of nm_handler_t.reset
- */
-static void reset(private_nm_handler_t *this)
+METHOD(nm_handler_t, reset, void,
+ private_nm_handler_t *this)
{
void *data;
@@ -160,10 +150,8 @@ static void reset(private_nm_handler_t *this)
}
}
-/**
- * Implementation of nm_handler_t.destroy.
- */
-static void destroy(private_nm_handler_t *this)
+METHOD(nm_handler_t, destroy, void,
+ private_nm_handler_t *this)
{
reset(this);
this->dns->destroy(this->dns);
@@ -176,17 +164,22 @@ static void destroy(private_nm_handler_t *this)
*/
nm_handler_t *nm_handler_create()
{
- private_nm_handler_t *this = malloc_thing(private_nm_handler_t);
-
- this->public.handler.handle = (bool(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))handle;
- this->public.handler.release = (void(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))nop;
- this->public.handler.create_attribute_enumerator = (enumerator_t*(*)(attribute_handler_t*, identification_t *server, host_t *vip))create_attribute_enumerator;
- this->public.create_enumerator = (enumerator_t*(*)(nm_handler_t*, configuration_attribute_type_t type))create_enumerator;
- this->public.reset = (void(*)(nm_handler_t*))reset;
- this->public.destroy = (void(*)(nm_handler_t*))destroy;
-
- this->dns = linked_list_create();
- this->nbns = linked_list_create();
+ private_nm_handler_t *this;
+
+ INIT(this,
+ .public = {
+ .handler = {
+ .handle = _handle,
+ .release = nop,
+ .create_attribute_enumerator = _create_attribute_enumerator,
+ },
+ .create_enumerator = _create_enumerator,
+ .reset = _reset,
+ .destroy = _destroy,
+ },
+ .dns = linked_list_create(),
+ .nbns = linked_list_create(),
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/nm/nm_plugin.c b/src/libcharon/plugins/nm/nm_plugin.c
index f1d3be7a5..84b7c810a 100644
--- a/src/libcharon/plugins/nm/nm_plugin.c
+++ b/src/libcharon/plugins/nm/nm_plugin.c
@@ -118,8 +118,8 @@ plugin_t *nm_plugin_create()
},
.creds = nm_creds_create(),
.handler = nm_handler_create(),
- .plugin = nm_strongswan_plugin_new(this->creds, this->handler),
);
+ this->plugin = nm_strongswan_plugin_new(this->creds, this->handler);
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
@@ -134,7 +134,8 @@ plugin_t *nm_plugin_create()
charon->keep_cap(charon, CAP_DAC_OVERRIDE);
lib->processor->queue_job(lib->processor,
- (job_t*)callback_job_create((callback_job_cb_t)run, this, NULL, NULL));
+ (job_t*)callback_job_create_with_prio((callback_job_cb_t)run,
+ this, NULL, NULL, JOB_PRIO_CRITICAL));
return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/nm/nm_service.c b/src/libcharon/plugins/nm/nm_service.c
index 4300b57cf..a6783fcc3 100644
--- a/src/libcharon/plugins/nm/nm_service.c
+++ b/src/libcharon/plugins/nm/nm_service.c
@@ -82,12 +82,11 @@ static void signal_ipv4_config(NMVPNPlugin *plugin,
{
GValue *val;
GHashTable *config;
- host_t *me, *other;
+ host_t *me;
nm_handler_t *handler;
config = g_hash_table_new(g_str_hash, g_str_equal);
me = ike_sa->get_my_host(ike_sa);
- other = ike_sa->get_other_host(ike_sa);
handler = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler;
/* NM requires a tundev, but netkey does not use one. Passing an invalid
@@ -632,7 +631,8 @@ static gboolean disconnect(NMVPNPlugin *plugin, GError **err)
u_int id;
/* our ike_sa pointer might be invalid, lookup sa */
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (priv->ike_sa == ike_sa)
@@ -640,7 +640,7 @@ static gboolean disconnect(NMVPNPlugin *plugin, GError **err)
id = ike_sa->get_unique_id(ike_sa);
enumerator->destroy(enumerator);
charon->controller->terminate_ike(charon->controller, id,
- controller_cb_empty, NULL);
+ controller_cb_empty, NULL, 0);
return TRUE;
}
}
diff --git a/src/libcharon/plugins/nm/nm_service.h b/src/libcharon/plugins/nm/nm_service.h
index b00000b6f..828d1a452 100644
--- a/src/libcharon/plugins/nm/nm_service.h
+++ b/src/libcharon/plugins/nm/nm_service.h
@@ -21,7 +21,7 @@
#ifndef NM_SERVICE_H_
#define NM_SERVICE_H_
-#include <glib/gtypes.h>
+#include <glib.h>
#include <glib-object.h>
#include <nm-vpn-plugin.h>
diff --git a/src/libcharon/plugins/radattr/Makefile.am b/src/libcharon/plugins/radattr/Makefile.am
new file mode 100644
index 000000000..0ea8df5d1
--- /dev/null
+++ b/src/libcharon/plugins/radattr/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/libradius
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-radattr.la
+else
+libstrongswan_radattr_la_LIBADD = $(top_builddir)/src/libradius/libradius.la
+plugin_LTLIBRARIES = libstrongswan-radattr.la
+endif
+
+libstrongswan_radattr_la_SOURCES = radattr_plugin.h radattr_plugin.c \
+ radattr_listener.h radattr_listener.c
+
+libstrongswan_radattr_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/radattr/Makefile.in b/src/libcharon/plugins/radattr/Makefile.in
new file mode 100644
index 000000000..ecea0df16
--- /dev/null
+++ b/src/libcharon/plugins/radattr/Makefile.in
@@ -0,0 +1,616 @@
+# 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/radattr
+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_radattr_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libradius/libradius.la
+am_libstrongswan_radattr_la_OBJECTS = radattr_plugin.lo \
+ radattr_listener.lo
+libstrongswan_radattr_la_OBJECTS = \
+ $(am_libstrongswan_radattr_la_OBJECTS)
+libstrongswan_radattr_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_radattr_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_radattr_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_radattr_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_radattr_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_radattr_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libradius
+
+AM_CFLAGS = -rdynamic
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-radattr.la
+@MONOLITHIC_FALSE@libstrongswan_radattr_la_LIBADD = $(top_builddir)/src/libradius/libradius.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-radattr.la
+libstrongswan_radattr_la_SOURCES = radattr_plugin.h radattr_plugin.c \
+ radattr_listener.h radattr_listener.c
+
+libstrongswan_radattr_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/radattr/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/radattr/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-radattr.la: $(libstrongswan_radattr_la_OBJECTS) $(libstrongswan_radattr_la_DEPENDENCIES)
+ $(libstrongswan_radattr_la_LINK) $(am_libstrongswan_radattr_la_rpath) $(libstrongswan_radattr_la_OBJECTS) $(libstrongswan_radattr_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radattr_listener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radattr_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/radattr/radattr_listener.c b/src/libcharon/plugins/radattr/radattr_listener.c
new file mode 100644
index 000000000..94b718a1b
--- /dev/null
+++ b/src/libcharon/plugins/radattr/radattr_listener.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 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 "radattr_listener.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+#include <daemon.h>
+
+#include <radius_message.h>
+
+/**
+ * Maximum size of an attribute to add
+ */
+#define MAX_ATTR_SIZE 1024
+
+typedef struct private_radattr_listener_t private_radattr_listener_t;
+
+/**
+ * Private data of an radattr_listener_t object.
+ */
+struct private_radattr_listener_t {
+
+ /**
+ * Public radattr_listener_t interface.
+ */
+ radattr_listener_t public;
+
+ /**
+ * Directory to look for attribute files
+ */
+ char *dir;
+
+ /**
+ * IKE_AUTH message ID to attribute
+ */
+ int mid;
+};
+
+/**
+ * Print RADIUS attributes found in IKE message notifies
+ */
+static void print_radius_attributes(private_radattr_listener_t *this,
+ message_t *message)
+{
+ radius_attribute_type_t type;
+ enumerator_t *enumerator;
+ notify_payload_t *notify;
+ payload_t *payload;
+ chunk_t data;
+
+ enumerator = message->create_payload_enumerator(message);
+ while (enumerator->enumerate(enumerator, &payload))
+ {
+ if (payload->get_type(payload) == NOTIFY)
+ {
+ notify = (notify_payload_t*)payload;
+ if (notify->get_notify_type(notify) == RADIUS_ATTRIBUTE)
+ {
+ data = notify->get_notification_data(notify);
+ if (data.len >= 2)
+ {
+ type = data.ptr[0];
+ data = chunk_skip(data, 2);
+ if (chunk_printable(data, NULL, 0))
+ {
+ DBG1(DBG_IKE, "received RADIUS %N: %.*s",
+ radius_attribute_type_names, type,
+ (int)data.len, data.ptr);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received RADIUS %N: %#B",
+ radius_attribute_type_names, type, &data);
+
+ }
+ }
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * Add a RADIUS attribute from a client-ID specific file to an IKE message
+ */
+static void add_radius_attribute(private_radattr_listener_t *this,
+ ike_sa_t *ike_sa, message_t *message)
+{
+ if (this->dir &&
+ (this->mid == -1 || message->get_message_id(message) == this->mid))
+ {
+ identification_t *id;
+ auth_cfg_t *auth;
+ char path[PATH_MAX];
+ chunk_t data;
+ struct stat sb;
+ void *addr;
+ int fd;
+
+ auth = ike_sa->get_auth_cfg(ike_sa, TRUE);
+ id = auth->get(auth, AUTH_RULE_EAP_IDENTITY);
+ if (!id)
+ {
+ id = ike_sa->get_my_id(ike_sa);
+ }
+
+ snprintf(path, sizeof(path), "%s/%Y", this->dir, id);
+ fd = open(path, O_RDONLY);
+ if (fd != -1)
+ {
+ if (fstat(fd, &sb) != -1)
+ {
+ if (sb.st_size <= MAX_ATTR_SIZE)
+ {
+ addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (addr != MAP_FAILED)
+ {
+ data = chunk_create(addr, sb.st_size);
+ if (data.len >= 2)
+ {
+ DBG1(DBG_CFG, "adding RADIUS %N attribute",
+ radius_attribute_type_names, data.ptr[0]);
+ message->add_notify(message, FALSE,
+ RADIUS_ATTRIBUTE, data);
+ }
+ munmap(addr, sb.st_size);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "mapping RADIUS attribute '%s' failed: %s",
+ path, strerror(errno));
+ }
+ }
+ else
+ {
+ DBG1(DBG_CFG, "RADIUS attribute '%s' exceeds size limit",
+ path);
+ }
+ }
+ else
+ {
+ DBG1(DBG_CFG, "fstat RADIUS attribute '%s' failed: %s",
+ path, strerror(errno));
+ }
+ close(fd);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "reading RADIUS attribute '%s' failed: %s",
+ path, strerror(errno));
+ }
+ }
+}
+
+METHOD(listener_t, message, bool,
+ private_radattr_listener_t *this,
+ ike_sa_t *ike_sa, message_t *message, bool incoming)
+{
+ if (ike_sa->supports_extension(ike_sa, EXT_STRONGSWAN) &&
+ message->get_exchange_type(message) == IKE_AUTH &&
+ message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
+ {
+ if (incoming)
+ {
+ print_radius_attributes(this, message);
+ }
+ else
+ {
+ add_radius_attribute(this, ike_sa, message);
+ }
+ }
+ return TRUE;
+}
+
+
+METHOD(radattr_listener_t, destroy, void,
+ private_radattr_listener_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+radattr_listener_t *radattr_listener_create()
+{
+ private_radattr_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .message = _message,
+ },
+ .destroy = _destroy,
+ },
+ .dir = lib->settings->get_str(lib->settings,
+ "charon.plugins.radattr.dir", NULL),
+ .mid = lib->settings->get_int(lib->settings,
+ "charon.plugins.radattr.message_id", -1),
+ );
+
+ return &this->public;
+}
diff --git a/src/libcharon/plugins/radattr/radattr_listener.h b/src/libcharon/plugins/radattr/radattr_listener.h
new file mode 100644
index 000000000..e61c441bf
--- /dev/null
+++ b/src/libcharon/plugins/radattr/radattr_listener.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 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 radattr_listener radattr_listener
+ * @{ @ingroup radattr
+ */
+
+#ifndef RADATTR_LISTENER_H_
+#define RADATTR_LISTENER_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct radattr_listener_t radattr_listener_t;
+
+/**
+ * Output received RADIUS attributes, inject custom attributes.
+ */
+struct radattr_listener_t {
+
+ /**
+ * Implements a listener.
+ */
+ listener_t listener;
+
+ /**
+ * Destroy a radattr_listener_t.
+ */
+ void (*destroy)(radattr_listener_t *this);
+};
+
+/**
+ * Create a radattr_listener instance.
+ */
+radattr_listener_t *radattr_listener_create();
+
+#endif /** RADATTR_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/radattr/radattr_plugin.c b/src/libcharon/plugins/radattr/radattr_plugin.c
new file mode 100644
index 000000000..85ea326ac
--- /dev/null
+++ b/src/libcharon/plugins/radattr/radattr_plugin.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 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 "radattr_plugin.h"
+
+#include "radattr_listener.h"
+
+#include <daemon.h>
+
+typedef struct private_radattr_plugin_t private_radattr_plugin_t;
+
+/**
+ * private data of radattr plugin
+ */
+struct private_radattr_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ radattr_plugin_t public;
+
+ /**
+ * Listener acting on messages
+ */
+ radattr_listener_t *listener;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_radattr_plugin_t *this)
+{
+ return "radattr";
+}
+
+METHOD(plugin_t, destroy, void,
+ private_radattr_plugin_t *this)
+{
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ this->listener->destroy(this->listener);
+ free(this);
+}
+
+/**
+ * Plugin constructor
+ */
+plugin_t *radattr_plugin_create()
+{
+ private_radattr_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = (void*)return_false,
+ .destroy = _destroy,
+ },
+ },
+ .listener = radattr_listener_create(),
+ );
+
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+
+ return &this->public.plugin;
+}
diff --git a/src/libcharon/plugins/radattr/radattr_plugin.h b/src/libcharon/plugins/radattr/radattr_plugin.h
new file mode 100644
index 000000000..c3bad5a3a
--- /dev/null
+++ b/src/libcharon/plugins/radattr/radattr_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 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 radattr radattr
+ * @ingroup cplugins
+ *
+ * @defgroup radattr_plugin radattr_plugin
+ * @{ @ingroup radattr
+ */
+
+#ifndef RADATTR_PLUGIN_H_
+#define RADATTR_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct radattr_plugin_t radattr_plugin_t;
+
+/**
+ * Plugin to inject/process custom RADIUS attributes.
+ */
+struct radattr_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** RADATTR_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in
index e36fa6bb4..59a560b86 100644
--- a/src/libcharon/plugins/smp/Makefile.in
+++ b/src/libcharon/plugins/smp/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/smp/smp.c b/src/libcharon/plugins/smp/smp.c
index d20f32248..2b830012d 100644
--- a/src/libcharon/plugins/smp/smp.c
+++ b/src/libcharon/plugins/smp/smp.c
@@ -208,12 +208,13 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer
/* <ikesalist> */
xmlTextWriterStartElement(writer, "ikesalist");
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
ike_sa_id_t *id;
host_t *local, *remote;
- iterator_t *children;
+ enumerator_t *children;
child_sa_t *child_sa;
id = ike_sa->get_id(ike_sa);
@@ -263,8 +264,8 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer
/* <childsalist> */
xmlTextWriterStartElement(writer, "childsalist");
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
+ children = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (children->enumerate(children, (void**)&child_sa))
{
write_child(writer, child_sa);
}
@@ -394,7 +395,8 @@ static void request_control_terminate(xmlTextReaderPtr reader,
enumerator_t *enumerator;
ike_sa_t *ike_sa;
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (streq(str, ike_sa->get_name(ike_sa)))
@@ -419,14 +421,14 @@ static void request_control_terminate(xmlTextReaderPtr reader,
if (ike)
{
status = charon->controller->terminate_ike(
- charon->controller, id,
- (controller_cb_t)xml_callback, writer);
+ charon->controller, id,
+ (controller_cb_t)xml_callback, writer, 0);
}
else
{
status = charon->controller->terminate_child(
- charon->controller, id,
- (controller_cb_t)xml_callback, writer);
+ charon->controller, id,
+ (controller_cb_t)xml_callback, writer, 0);
}
/* </log> */
xmlTextWriterEndElement(writer);
@@ -459,17 +461,21 @@ static void request_control_initiate(xmlTextReaderPtr reader,
/* <log> */
xmlTextWriterStartElement(writer, "log");
- peer = charon->backends->get_peer_cfg_by_name(charon->backends, (char*)str);
+ peer = charon->backends->get_peer_cfg_by_name(charon->backends,
+ (char*)str);
if (peer)
{
enumerator = peer->create_child_cfg_enumerator(peer);
if (ike)
{
- if (!enumerator->enumerate(enumerator, &child))
+ if (enumerator->enumerate(enumerator, &child))
+ {
+ child->get_ref(child);
+ }
+ else
{
child = NULL;
}
- child->get_ref(child);
}
else
{
@@ -488,7 +494,7 @@ static void request_control_initiate(xmlTextReaderPtr reader,
{
status = charon->controller->initiate(charon->controller,
peer, child, (controller_cb_t)xml_callback,
- writer);
+ writer, 0);
}
else
{
@@ -625,7 +631,7 @@ static job_requeue_t process(int *fdp)
int fd = *fdp;
bool oldstate;
char buffer[4096];
- size_t len;
+ ssize_t len;
xmlTextReaderPtr reader;
char *id = NULL, *type = NULL;
@@ -640,7 +646,7 @@ static job_requeue_t process(int *fdp)
DBG2(DBG_CFG, "SMP XML connection closed");
return JOB_REQUEUE_NONE;
}
- DBG3(DBG_CFG, "got XML request: %b", buffer, len);
+ DBG3(DBG_CFG, "got XML request: %b", buffer, (u_int)len);
reader = xmlReaderForMemory(buffer, len, NULL, NULL, 0);
if (reader == NULL)
@@ -772,7 +778,8 @@ plugin_t *smp_plugin_create()
return NULL;
}
- this->job = callback_job_create((callback_job_cb_t)dispatch, this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)dispatch,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
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 95cb04d14..9c4e5e7b4 100644
--- a/src/libcharon/plugins/socket_default/Makefile.in
+++ b/src/libcharon/plugins/socket_default/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/socket_default/socket_default_plugin.c b/src/libcharon/plugins/socket_default/socket_default_plugin.c
index 1bc8244d5..01d9473bf 100644
--- a/src/libcharon/plugins/socket_default/socket_default_plugin.c
+++ b/src/libcharon/plugins/socket_default/socket_default_plugin.c
@@ -43,11 +43,20 @@ METHOD(plugin_t, get_name, char*,
METHOD(plugin_t, destroy, void,
private_socket_default_plugin_t *this)
{
- charon->socket->remove_socket(charon->socket,
- (socket_constructor_t)socket_default_socket_create);
free(this);
}
+METHOD(plugin_t, get_features, int,
+ private_socket_default_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(socket_register, socket_default_socket_create),
+ PLUGIN_PROVIDE(CUSTOM, "socket"),
+ };
+ *features = f;
+ return countof(f);
+}
+
/*
* see header file
*/
@@ -59,15 +68,11 @@ plugin_t *socket_default_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- 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 e95646643..76ca1df42 100644
--- a/src/libcharon/plugins/socket_default/socket_default_socket.c
+++ b/src/libcharon/plugins/socket_default/socket_default_socket.c
@@ -461,15 +461,15 @@ static int open_socket(private_socket_default_socket_t *this,
int skt;
memset(&addr, 0, sizeof(addr));
+ addr.ss_family = family;
/* precalculate constants depending on address family */
switch (family)
{
case AF_INET:
{
struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = INADDR_ANY;
- sin->sin_port = htons(port);
+ htoun32(&sin->sin_addr.s_addr, INADDR_ANY);
+ htoun16(&sin->sin_port, port);
addrlen = sizeof(struct sockaddr_in);
sol = SOL_IP;
#ifdef IP_PKTINFO
@@ -482,9 +482,8 @@ static int open_socket(private_socket_default_socket_t *this,
case AF_INET6:
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
- sin6->sin6_family = AF_INET6;
memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
- sin6->sin6_port = htons(port);
+ htoun16(&sin6->sin6_port, port);
addrlen = sizeof(struct sockaddr_in6);
sol = SOL_IPV6;
pktinfo = IPV6_RECVPKTINFO;
diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in
index 97e3a713d..f45e3d255 100644
--- a/src/libcharon/plugins/socket_dynamic/Makefile.in
+++ b/src/libcharon/plugins/socket_dynamic/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
index c5ea37a10..c21d5240e 100644
--- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
+++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_plugin.c
@@ -34,6 +34,17 @@ struct private_socket_dynamic_plugin_t {
socket_dynamic_plugin_t public;
};
+METHOD(plugin_t, get_features, int,
+ private_socket_dynamic_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(socket_register, socket_dynamic_socket_create),
+ PLUGIN_PROVIDE(CUSTOM, "socket"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, get_name, char*,
private_socket_dynamic_plugin_t *this)
{
@@ -43,8 +54,6 @@ METHOD(plugin_t, get_name, char*,
METHOD(plugin_t, destroy, void,
private_socket_dynamic_plugin_t *this)
{
- charon->socket->remove_socket(charon->socket,
- (socket_constructor_t)socket_dynamic_socket_create);
free(this);
}
@@ -59,15 +68,12 @@ plugin_t *socket_dynamic_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- 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 74dba82cc..eee3814a8 100644
--- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
+++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
@@ -235,7 +235,7 @@ static packet_t *receive_packet(private_socket_dynamic_socket_t *this,
DBG1(DBG_NET, "receive buffer too small, packet discarded");
return NULL;
}
- DBG3(DBG_NET, "received packet %b", buffer, len);
+ DBG3(DBG_NET, "received packet %b", buffer, (u_int)len);
if (len < MARKER_LEN)
{
diff --git a/src/libcharon/plugins/socket_raw/Makefile.in b/src/libcharon/plugins/socket_raw/Makefile.in
index 6f1a09c88..5abceb6c3 100644
--- a/src/libcharon/plugins/socket_raw/Makefile.in
+++ b/src/libcharon/plugins/socket_raw/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
index 5bd28bd42..1299c30ca 100644
--- a/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
+++ b/src/libcharon/plugins/socket_raw/socket_raw_plugin.c
@@ -40,11 +40,20 @@ METHOD(plugin_t, get_name, char*,
return "socket-raw";
}
+METHOD(plugin_t, get_features, int,
+ private_socket_raw_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(socket_register, socket_raw_socket_create),
+ PLUGIN_PROVIDE(CUSTOM, "socket"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_socket_raw_plugin_t *this)
{
- charon->socket->remove_socket(charon->socket,
- (socket_constructor_t)socket_raw_socket_create);
free(this);
}
@@ -59,15 +68,12 @@ plugin_t *socket_raw_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- 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 f6e87a86f..ae37d8f2b 100644
--- a/src/libcharon/plugins/socket_raw/socket_raw_socket.c
+++ b/src/libcharon/plugins/socket_raw/socket_raw_socket.c
@@ -31,7 +31,6 @@
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
-#include <netinet/ip6.h>
#include <netinet/udp.h>
#include <linux/types.h>
#include <linux/filter.h>
@@ -259,6 +258,8 @@ METHOD(socket_t, receiver, status_t,
DBG1(DBG_NET, "error reading IPv6 ancillary data");
return FAILED;
}
+
+#ifdef HAVE_IN6_PKTINFO
if (cmsgptr->cmsg_level == SOL_IPV6 &&
cmsgptr->cmsg_type == IPV6_2292PKTINFO)
{
@@ -273,6 +274,7 @@ METHOD(socket_t, receiver, status_t,
src.sin6_port = udp->source;
dest = host_create_from_sockaddr((sockaddr_t*)&dst);
}
+#endif /* HAVE_IN6_PKTINFO */
}
/* ancillary data missing? */
if (dest == NULL)
@@ -397,6 +399,7 @@ METHOD(socket_t, sender, status_t,
sin = (struct sockaddr_in*)src->get_sockaddr(src);
memcpy(&pktinfo->ipi_spec_dst, &sin->sin_addr, sizeof(struct in_addr));
}
+#ifdef HAVE_IN6_PKTINFO
else
{
char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
@@ -414,6 +417,7 @@ METHOD(socket_t, sender, status_t,
sin = (struct sockaddr_in6*)src->get_sockaddr(src);
memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr));
}
+#endif /* HAVE_IN6_PKTINFO */
}
bytes_sent = sendmsg(skt, &msg, 0);
@@ -435,29 +439,25 @@ static int open_send_socket(private_socket_raw_socket_t *this,
int on = TRUE;
int type = UDP_ENCAP_ESPINUDP;
struct sockaddr_storage addr;
- u_int sol;
int skt;
memset(&addr, 0, sizeof(addr));
+ addr.ss_family = family;
/* precalculate constants depending on address family */
switch (family)
{
case AF_INET:
{
struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = INADDR_ANY;
- sin->sin_port = htons(port);
- sol = SOL_IP;
+ htoun32(&sin->sin_addr.s_addr, INADDR_ANY);
+ htoun16(&sin->sin_port, port);
break;
}
case AF_INET6:
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
- sin6->sin6_family = AF_INET6;
memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
- sin6->sin6_port = htons(port);
- sol = SOL_IPV6;
+ htoun16(&sin6->sin6_port, port);
break;
}
default:
@@ -514,18 +514,16 @@ static int open_recv_socket(private_socket_raw_socket_t *this, int family)
{
int skt;
int on = TRUE;
- u_int proto_offset, ip_len, sol, udp_header, ike_header;
+ u_int ip_len, sol, udp_header, ike_header;
/* precalculate constants depending on address family */
switch (family)
{
case AF_INET:
- proto_offset = IP_PROTO_OFFSET;
ip_len = IP_LEN;
sol = SOL_IP;
break;
case AF_INET6:
- proto_offset = IP6_PROTO_OFFSET;
ip_len = 0; /* IPv6 raw sockets contain no IP header */
sol = SOL_IPV6;
break;
diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in
index d7b43dcc9..d04c7f6c9 100644
--- a/src/libcharon/plugins/sql/Makefile.in
+++ b/src/libcharon/plugins/sql/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/sql/sql_logger.c b/src/libcharon/plugins/sql/sql_logger.c
index d350c4c3d..10ceacb00 100644
--- a/src/libcharon/plugins/sql/sql_logger.c
+++ b/src/libcharon/plugins/sql/sql_logger.c
@@ -47,11 +47,9 @@ struct private_sql_logger_t {
bool recursive;
};
-/**
- * Implementation of bus_listener_t.log.
- */
-static bool log_(private_sql_logger_t *this, debug_t group, level_t level,
- int thread, ike_sa_t* ike_sa, char *format, va_list args)
+METHOD(listener_t, log_, bool,
+ private_sql_logger_t *this, debug_t group, level_t level, int thread,
+ ike_sa_t* ike_sa, char *format, va_list args)
{
if (this->recursive)
{
@@ -115,10 +113,8 @@ static bool log_(private_sql_logger_t *this, debug_t group, level_t level,
return TRUE;
}
-/**
- * Implementation of sql_logger_t.destroy.
- */
-static void destroy(private_sql_logger_t *this)
+METHOD(sql_logger_t, destroy, void,
+ private_sql_logger_t *this)
{
free(this);
}
@@ -128,17 +124,19 @@ static void destroy(private_sql_logger_t *this)
*/
sql_logger_t *sql_logger_create(database_t *db)
{
- private_sql_logger_t *this = malloc_thing(private_sql_logger_t);
-
- memset(&this->public.listener, 0, sizeof(listener_t));
- this->public.listener.log = (bool(*)(listener_t*,debug_t,level_t,int,ike_sa_t*,char*,va_list))log_;
- this->public.destroy = (void(*)(sql_logger_t*))destroy;
-
- this->db = db;
- this->recursive = FALSE;
-
- this->level = lib->settings->get_int(lib->settings,
- "charon.plugins.sql.loglevel", -1);
+ private_sql_logger_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .log = _log_,
+ },
+ .destroy = _destroy,
+ },
+ .db = db,
+ .level = lib->settings->get_int(lib->settings,
+ "charon.plugins.sql.loglevel", -1),
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in
index fd859daeb..60f5f535a 100644
--- a/src/libcharon/plugins/stroke/Makefile.in
+++ b/src/libcharon/plugins/stroke/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c
index 69e13deb9..bec35a661 100644
--- a/src/libcharon/plugins/stroke/stroke_ca.c
+++ b/src/libcharon/plugins/stroke/stroke_ca.c
@@ -319,7 +319,7 @@ static void list_uris(linked_list_t *list, char *label, FILE *out)
{
if (first)
{
- fprintf(out, label);
+ fprintf(out, "%s", label);
first = FALSE;
}
else
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index 2b3164384..483e3d253 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -263,7 +264,7 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
{
identification_t *identity;
certificate_t *certificate;
- char *auth, *id, *cert, *ca;
+ char *auth, *id, *pubkey, *cert, *ca;
stroke_end_t *end, *other_end;
auth_cfg_t *cfg;
char eap_buf[32];
@@ -328,6 +329,9 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
case AUTH_CLASS_EAP:
auth = "eap";
break;
+ case AUTH_CLASS_ANY:
+ auth = "any";
+ break;
}
}
else
@@ -396,6 +400,18 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
}
cfg->add(cfg, AUTH_RULE_IDENTITY, identity);
+ /* add raw RSA public key */
+ pubkey = end->rsakey;
+ if (pubkey && !streq(pubkey, "") && !streq(pubkey, "%cert"))
+ {
+ certificate = this->cred->load_pubkey(this->cred, KEY_RSA, pubkey,
+ identity);
+ if (certificate)
+ {
+ cfg->add(cfg, AUTH_RULE_SUBJECT_CERT, certificate);
+ }
+ }
+
/* CA constraint */
if (ca)
{
@@ -775,13 +791,28 @@ static void add_ts(private_stroke_config_t *this,
}
/**
+ * map starter magic values to our action type
+ */
+static action_t map_action(int starter_action)
+{
+ switch (starter_action)
+ {
+ case 2: /* =hold */
+ return ACTION_ROUTE;
+ case 3: /* =restart */
+ return ACTION_RESTART;
+ default:
+ return ACTION_NONE;
+ }
+}
+
+/**
* build a child config from the stroke message
*/
static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
stroke_msg_t *msg)
{
child_cfg_t *child_cfg;
- action_t dpd;
lifetime_cfg_t lifetime = {
.time = {
.life = msg->add_conn.rekey.ipsec_lifetime,
@@ -808,23 +839,11 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
.mask = msg->add_conn.mark_out.mask
};
- switch (msg->add_conn.dpd.action)
- { /* map startes magic values to our action type */
- case 2: /* =hold */
- dpd = ACTION_ROUTE;
- break;
- case 3: /* =restart */
- dpd = ACTION_RESTART;
- break;
- default:
- dpd = ACTION_NONE;
- break;
- }
-
child_cfg = child_cfg_create(
- msg->add_conn.name, &lifetime,
- msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
- msg->add_conn.mode, ACTION_NONE, dpd, dpd, msg->add_conn.ipcomp,
+ msg->add_conn.name, &lifetime, msg->add_conn.me.updown,
+ msg->add_conn.me.hostaccess, msg->add_conn.mode, ACTION_NONE,
+ map_action(msg->add_conn.dpd.action),
+ map_action(msg->add_conn.close_action), msg->add_conn.ipcomp,
msg->add_conn.inactivity, msg->add_conn.reqid,
&mark_in, &mark_out, msg->add_conn.tfc);
child_cfg->set_mipv6_options(child_cfg, msg->add_conn.proxy_mode,
@@ -950,6 +969,175 @@ METHOD(stroke_config_t, del, void,
}
}
+METHOD(stroke_config_t, set_user_credentials, void,
+ private_stroke_config_t *this, stroke_msg_t *msg, FILE *prompt)
+{
+ enumerator_t *enumerator, *children, *remote_auth;
+ peer_cfg_t *peer, *found = NULL;
+ auth_cfg_t *auth_cfg, *remote_cfg;
+ auth_class_t auth_class;
+ child_cfg_t *child;
+ identification_t *id, *identity, *gw = NULL;
+ shared_key_type_t type = SHARED_ANY;
+ chunk_t password = chunk_empty;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, (void**)&peer))
+ { /* find the peer (or child) config with the given name */
+ if (streq(peer->get_name(peer), msg->user_creds.name))
+ {
+ found = peer;
+ }
+ else
+ {
+ children = peer->create_child_cfg_enumerator(peer);
+ while (children->enumerate(children, &child))
+ {
+ if (streq(child->get_name(child), msg->user_creds.name))
+ {
+ found = peer;
+ break;
+ }
+ }
+ children->destroy(children);
+ }
+
+ if (found)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ DBG1(DBG_CFG, " no config named '%s'", msg->user_creds.name);
+ fprintf(prompt, "no config named '%s'\n", msg->user_creds.name);
+ this->mutex->unlock(this->mutex);
+ return;
+ }
+
+ id = identification_create_from_string(msg->user_creds.username);
+ if (strlen(msg->user_creds.username) == 0 ||
+ !id || id->get_type(id) == ID_ANY)
+ {
+ DBG1(DBG_CFG, " invalid username '%s'", msg->user_creds.username);
+ fprintf(prompt, "invalid username '%s'\n", msg->user_creds.username);
+ this->mutex->unlock(this->mutex);
+ DESTROY_IF(id);
+ return;
+ }
+
+ /* replace/set the username in the first EAP auth_cfg, also look for a
+ * suitable remote ID.
+ * note that adding the identity here is not fully thread-safe as the
+ * peer_cfg and in turn the auth_cfg could be in use. for the default use
+ * case (setting user credentials before upping the connection) this will
+ * not be a problem, though. */
+ enumerator = found->create_auth_cfg_enumerator(found, TRUE);
+ remote_auth = found->create_auth_cfg_enumerator(found, FALSE);
+ while (enumerator->enumerate(enumerator, (void**)&auth_cfg))
+ {
+ if (remote_auth->enumerate(remote_auth, (void**)&remote_cfg))
+ { /* fall back on rightid, in case aaa_identity is not specified */
+ identity = remote_cfg->get(remote_cfg, AUTH_RULE_IDENTITY);
+ if (identity && identity->get_type(identity) != ID_ANY)
+ {
+ gw = identity;
+ }
+ }
+
+ auth_class = (uintptr_t)auth_cfg->get(auth_cfg, AUTH_RULE_AUTH_CLASS);
+ if (auth_class == AUTH_CLASS_EAP)
+ {
+ auth_cfg->add(auth_cfg, AUTH_RULE_EAP_IDENTITY, id->clone(id));
+ /* if aaa_identity is specified use that as remote ID */
+ identity = auth_cfg->get(auth_cfg, AUTH_RULE_AAA_IDENTITY);
+ if (identity && identity->get_type(identity) != ID_ANY)
+ {
+ gw = identity;
+ }
+ DBG1(DBG_CFG, " configured EAP-Identity %Y", id);
+ type = SHARED_EAP;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ remote_auth->destroy(remote_auth);
+ /* clone the gw ID before unlocking the mutex */
+ if (gw)
+ {
+ gw = gw->clone(gw);
+ }
+ this->mutex->unlock(this->mutex);
+
+ if (type == SHARED_ANY)
+ {
+ DBG1(DBG_CFG, " config '%s' unsuitable for user credentials",
+ msg->user_creds.name);
+ fprintf(prompt, "config '%s' unsuitable for user credentials\n",
+ msg->user_creds.name);
+ id->destroy(id);
+ DESTROY_IF(gw);
+ return;
+ }
+
+ if (msg->user_creds.password)
+ {
+ char *pass;
+
+ pass = msg->user_creds.password;
+ password = chunk_clone(chunk_create(pass, strlen(pass)));
+ memwipe(pass, strlen(pass));
+ }
+ else
+ { /* prompt the user for the password */
+ char buf[256];
+
+ fprintf(prompt, "Password:\n");
+ if (fgets(buf, sizeof(buf), prompt))
+ {
+ password = chunk_clone(chunk_create(buf, strlen(buf)));
+ if (password.len > 0)
+ { /* trim trailing \n */
+ password.len--;
+ }
+ memwipe(buf, sizeof(buf));
+ }
+ }
+
+ if (password.len)
+ {
+ shared_key_t *shared;
+ linked_list_t *owners;
+
+ shared = shared_key_create(type, password);
+
+ owners = linked_list_create();
+ owners->insert_last(owners, id->clone(id));
+ if (gw && gw->get_type(gw) != ID_ANY)
+ {
+ owners->insert_last(owners, gw->clone(gw));
+ DBG1(DBG_CFG, " added %N secret for %Y %Y", shared_key_type_names,
+ type, id, gw);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " added %N secret for %Y", shared_key_type_names,
+ type, id);
+ }
+ this->cred->add_shared(this->cred, shared, owners);
+ DBG4(DBG_CFG, " secret: %#B", &password);
+ }
+ else
+ { /* in case a user answers the password prompt by just pressing enter */
+ chunk_clear(&password);
+ }
+ id->destroy(id);
+ DESTROY_IF(gw);
+}
+
METHOD(stroke_config_t, destroy, void,
private_stroke_config_t *this)
{
@@ -974,6 +1162,7 @@ stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred)
},
.add = _add,
.del = _del,
+ .set_user_credentials = _set_user_credentials,
.destroy = _destroy,
},
.list = linked_list_create(),
diff --git a/src/libcharon/plugins/stroke/stroke_config.h b/src/libcharon/plugins/stroke/stroke_config.h
index 05e4665ca..450d517f3 100644
--- a/src/libcharon/plugins/stroke/stroke_config.h
+++ b/src/libcharon/plugins/stroke/stroke_config.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -53,6 +54,15 @@ struct stroke_config_t {
void (*del)(stroke_config_t *this, stroke_msg_t *msg);
/**
+ * Set the username and password for a connection in this backend.
+ *
+ * @param msg received stroke message
+ * @param prompt I/O channel to prompt for the password
+ */
+ void (*set_user_credentials)(stroke_config_t *this, stroke_msg_t *msg,
+ FILE *prompt);
+
+ /**
* Destroy a stroke_config instance.
*/
void (*destroy)(stroke_config_t *this);
diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c
index 4943ee670..729e9d757 100644
--- a/src/libcharon/plugins/stroke/stroke_control.c
+++ b/src/libcharon/plugins/stroke/stroke_control.c
@@ -15,7 +15,9 @@
#include "stroke_control.h"
+#include <hydra.h>
#include <daemon.h>
+
#include <processing/jobs/delete_ike_sa_job.h>
#include <processing/jobs/rekey_ike_sa_job.h>
#include <processing/jobs/rekey_child_sa_job.h>
@@ -101,14 +103,14 @@ static void charon_initiate(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
if (msg->output_verbosity < 0)
{
charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
- NULL, NULL);
+ NULL, NULL, 0);
}
else
{
stroke_log_info_t info = { msg->output_verbosity, out };
charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
}
@@ -275,28 +277,29 @@ METHOD(stroke_control_t, terminate, void,
if (child)
{
charon->controller->terminate_child(charon->controller, id,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
else
{
charon->controller->terminate_ike(charon->controller, id,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
return;
}
ike_list = linked_list_create();
child_list = linked_list_create();
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
child_sa_t *child_sa;
- iterator_t *children;
+ enumerator_t *children;
if (child)
{
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
+ children = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (children->enumerate(children, (void**)&child_sa))
{
if (streq(name, child_sa->get_name(child_sa)))
{
@@ -330,7 +333,7 @@ METHOD(stroke_control_t, terminate, void,
while (enumerator->enumerate(enumerator, &del))
{
charon->controller->terminate_child(charon->controller, del,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
enumerator->destroy(enumerator);
@@ -338,7 +341,7 @@ METHOD(stroke_control_t, terminate, void,
while (enumerator->enumerate(enumerator, &del))
{
charon->controller->terminate_ike(charon->controller, del,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
enumerator->destroy(enumerator);
@@ -366,16 +369,17 @@ METHOD(stroke_control_t, rekey, void,
DBG1(DBG_CFG, "error parsing specifier string");
return;
}
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
child_sa_t *child_sa;
- iterator_t *children;
+ enumerator_t *children;
if (child)
{
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
+ children = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (children->enumerate(children, (void**)&child_sa))
{
if ((name && streq(name, child_sa->get_name(child_sa))) ||
(id && id == child_sa->get_reqid(child_sa)))
@@ -442,7 +446,8 @@ METHOD(stroke_control_t, terminate_srcip, void,
chunk_end = end->get_address(end);
}
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
@@ -481,8 +486,7 @@ METHOD(stroke_control_t, terminate_srcip, void,
METHOD(stroke_control_t, purge_ike, void,
private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
{
- enumerator_t *enumerator;
- iterator_t *iterator;
+ enumerator_t *enumerator, *children;
ike_sa_t *ike_sa;
child_sa_t *child_sa;
linked_list_t *list;
@@ -493,16 +497,17 @@ METHOD(stroke_control_t, purge_ike, void,
info.level = msg->output_verbosity;
list = linked_list_create();
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
- iterator = ike_sa->create_child_sa_iterator(ike_sa);
- if (!iterator->iterate(iterator, (void**)&child_sa))
+ children = ike_sa->create_child_sa_enumerator(ike_sa);
+ if (!children->enumerate(children, (void**)&child_sa))
{
list->insert_last(list,
(void*)(uintptr_t)ike_sa->get_unique_id(ike_sa));
}
- iterator->destroy(iterator);
+ children->destroy(children);
}
enumerator->destroy(enumerator);
@@ -510,25 +515,44 @@ METHOD(stroke_control_t, purge_ike, void,
while (enumerator->enumerate(enumerator, &del))
{
charon->controller->terminate_ike(charon->controller, del,
- (controller_cb_t)stroke_log, &info);
+ (controller_cb_t)stroke_log, &info, 0);
}
enumerator->destroy(enumerator);
list->destroy(list);
}
/**
- * call charon to install a trap
+ * call charon to install a shunt or trap
*/
static void charon_route(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
char *name, FILE *out)
{
- if (charon->traps->install(charon->traps, peer_cfg, child_cfg))
+ ipsec_mode_t mode;
+
+ mode = child_cfg->get_mode(child_cfg);
+ if (mode == MODE_PASS || mode == MODE_DROP)
{
- fprintf(out, "'%s' routed\n", name);
+ if (charon->shunts->install(charon->shunts, child_cfg))
+ {
+ fprintf(out, "'%s' shunt %N policy installed\n",
+ name, ipsec_mode_names, mode);
+ }
+ else
+ {
+ fprintf(out, "'%s' shunt %N policy installation failed\n",
+ name, ipsec_mode_names, mode);
+ }
}
else
{
- fprintf(out, "routing '%s' failed\n", name);
+ if (charon->traps->install(charon->traps, peer_cfg, child_cfg))
+ {
+ fprintf(out, "'%s' routed\n", name);
+ }
+ else
+ {
+ fprintf(out, "routing '%s' failed\n", name);
+ }
}
}
@@ -609,7 +633,13 @@ METHOD(stroke_control_t, unroute, void,
{
child_sa_t *child_sa;
enumerator_t *enumerator;
- u_int32_t id;
+ u_int32_t id = 0;
+
+ if (charon->shunts->uninstall(charon->shunts, msg->unroute.name))
+ {
+ fprintf(out, "shunt policy '%s' uninstalled\n", msg->unroute.name);
+ return;
+ }
enumerator = charon->traps->create_enumerator(charon->traps);
while (enumerator->enumerate(enumerator, NULL, &child_sa))
@@ -617,14 +647,20 @@ METHOD(stroke_control_t, unroute, void,
if (streq(msg->unroute.name, child_sa->get_name(child_sa)))
{
id = child_sa->get_reqid(child_sa);
- enumerator->destroy(enumerator);
- charon->traps->uninstall(charon->traps, id);
- fprintf(out, "configuration '%s' unrouted\n", msg->unroute.name);
- return;
+ break;
}
}
enumerator->destroy(enumerator);
- fprintf(out, "configuration '%s' not found\n", msg->unroute.name);
+
+ if (id)
+ {
+ charon->traps->uninstall(charon->traps, id);
+ fprintf(out, "configuration '%s' unrouted\n", msg->unroute.name);
+ }
+ else
+ {
+ fprintf(out, "configuration '%s' not found\n", msg->unroute.name);
+ }
}
METHOD(stroke_control_t, destroy, void,
diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c
index baf02a6da..a2a6d6d9f 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.c
+++ b/src/libcharon/plugins/stroke/stroke_cred.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2010 Tobias Brunner
+ * Copyright (C) 2008-2012 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -17,13 +17,16 @@
#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>
+#ifdef HAVE_GLOB_H
+#include <glob.h>
+#endif
+
#include "stroke_cred.h"
#include <credentials/certificates/x509.h>
@@ -68,15 +71,19 @@ struct private_stroke_cred_t {
mem_cred_t *creds;
/**
+ * ignore missing CA basic constraint (i.e. treat all certificates in
+ * ipsec.conf ca sections and ipsec.d/cacert as CA certificates)
+ */
+ bool force_ca_cert;
+
+ /**
* cache CRLs to disk?
*/
bool cachecrl;
};
-/**
- * Implementation of stroke_cred_t.load_ca.
- */
-static certificate_t* load_ca(private_stroke_cred_t *this, char *filename)
+METHOD(stroke_cred_t, load_ca, certificate_t*,
+ private_stroke_cred_t *this, char *filename)
{
certificate_t *cert;
char path[PATH_MAX];
@@ -90,10 +97,21 @@ static certificate_t* load_ca(private_stroke_cred_t *this, char *filename)
snprintf(path, sizeof(path), "%s/%s", CA_CERTIFICATE_DIR, filename);
}
- cert = lib->creds->create(lib->creds,
+ if (this->force_ca_cert)
+ { /* we treat this certificate as a CA certificate even if it has no
+ * CA basic constraint */
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, path, BUILD_X509_FLAG, X509_CA,
+ BUILD_END);
+ }
+ else
+ {
+ cert = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509,
BUILD_FROM_FILE, path,
BUILD_END);
+ }
if (cert)
{
x509_t *x509 = (x509_t*)cert;
@@ -110,10 +128,8 @@ static certificate_t* load_ca(private_stroke_cred_t *this, char *filename)
return NULL;
}
-/**
- * Implementation of stroke_cred_t.load_peer.
- */
-static certificate_t* load_peer(private_stroke_cred_t *this, char *filename)
+METHOD(stroke_cred_t, load_peer, certificate_t*,
+ private_stroke_cred_t *this, char *filename)
{
certificate_t *cert;
char path[PATH_MAX];
@@ -142,6 +158,78 @@ static certificate_t* load_peer(private_stroke_cred_t *this, char *filename)
return NULL;
}
+METHOD(stroke_cred_t, load_pubkey, certificate_t*,
+ private_stroke_cred_t *this, key_type_t type, char *filename,
+ identification_t *identity)
+{
+ certificate_t *cert;
+ char path[PATH_MAX];
+
+ if (streq(filename, "%dns"))
+ {
+
+ }
+ else if (strncaseeq(filename, "0x", 2) || strncaseeq(filename, "0s", 2))
+ {
+ chunk_t printable_key, rfc3110_key;
+ public_key_t *key;
+
+ printable_key = chunk_create(filename + 2, strlen(filename) - 2);
+ rfc3110_key = strncaseeq(filename, "0x", 2) ?
+ chunk_from_hex(printable_key, NULL) :
+ chunk_from_base64(printable_key, NULL);
+ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA,
+ BUILD_BLOB_DNSKEY, rfc3110_key,
+ BUILD_END);
+ free(rfc3110_key.ptr);
+ if (key)
+ {
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
+ CERT_TRUSTED_PUBKEY,
+ BUILD_PUBLIC_KEY, key,
+ BUILD_SUBJECT, identity,
+ BUILD_END);
+ key->destroy(key);
+ if (cert)
+ {
+ cert = this->creds->add_cert_ref(this->creds, TRUE, cert);
+ DBG1(DBG_CFG, " loaded %N public key for \"%Y\"",
+ key_type_names, type, identity);
+ return cert;
+ }
+ }
+ DBG1(DBG_CFG, " loading %N public key for \"%Y\" failed",
+ key_type_names, type, identity);
+ }
+ else
+ {
+ if (*filename == '/')
+ {
+ snprintf(path, sizeof(path), "%s", filename);
+ }
+ else
+ {
+ snprintf(path, sizeof(path), "%s/%s", CERTIFICATE_DIR, filename);
+ }
+
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY,
+ BUILD_FROM_FILE, path,
+ BUILD_SUBJECT, identity,
+ BUILD_END);
+ if (cert)
+ {
+ cert = this->creds->add_cert_ref(this->creds, TRUE, cert);
+ DBG1(DBG_CFG, " loaded %N public key for \"%Y\" from '%s'",
+ key_type_names, type, identity, filename);
+ return cert;
+ }
+ DBG1(DBG_CFG, " loading %N public key for \"%Y\" from '%s' failed",
+ key_type_names, type, identity, filename);
+ }
+ return NULL;
+}
+
/**
* load trusted certificates from a directory
*/
@@ -172,11 +260,21 @@ static void load_certdir(private_stroke_cred_t *this, char *path,
{
case CERT_X509:
if (flag & X509_CA)
- { /* for CA certificates, we strictly require
- * the CA basic constraint to be set */
- cert = lib->creds->create(lib->creds,
+ {
+ if (this->force_ca_cert)
+ { /* treat this certificate as CA cert even it has no
+ * CA basic constraint */
+ cert = lib->creds->create(lib->creds,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file, BUILD_X509_FLAG,
+ X509_CA, BUILD_END);
+ }
+ else
+ {
+ cert = lib->creds->create(lib->creds,
CRED_CERTIFICATE, CERT_X509,
BUILD_FROM_FILE, file, BUILD_END);
+ }
if (cert)
{
x509_t *x509 = (x509_t*)cert;
@@ -262,10 +360,8 @@ static void load_certdir(private_stroke_cred_t *this, char *path,
enumerator->destroy(enumerator);
}
-/**
- * Implementation of credential_set_t.cache_cert.
- */
-static void cache_cert(private_stroke_cred_t *this, certificate_t *cert)
+METHOD(stroke_cred_t, cache_cert, void,
+ private_stroke_cred_t *this, certificate_t *cert)
{
if (cert->get_type(cert) == CERT_X509_CRL && this->cachecrl)
{
@@ -292,10 +388,8 @@ static void cache_cert(private_stroke_cred_t *this, certificate_t *cert)
}
}
-/**
- * Implementation of stroke_cred_t.cachecrl.
- */
-static void cachecrl(private_stroke_cred_t *this, bool enabled)
+METHOD(stroke_cred_t, cachecrl, void,
+ private_stroke_cred_t *this, bool enabled)
{
DBG1(DBG_CFG, "crl caching to %s %s",
CRL_DIR, enabled ? "enabled" : "disabled");
@@ -852,7 +946,6 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
if (line.len > strlen("include ") &&
strneq(line.ptr, "include ", strlen("include ")))
{
- glob_t buf;
char **expanded, *dir, pattern[PATH_MAX];
u_char *pos;
@@ -894,18 +987,27 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level,
dir, (int)line.len, line.ptr);
free(dir);
}
- if (glob(pattern, GLOB_ERR, NULL, &buf) != 0)
+#ifdef HAVE_GLOB_H
{
- DBG1(DBG_CFG, "expanding file expression '%s' failed", pattern);
- }
- else
- {
- for (expanded = buf.gl_pathv; *expanded != NULL; expanded++)
+ glob_t buf;
+ if (glob(pattern, GLOB_ERR, NULL, &buf) != 0)
{
- load_secrets(this, *expanded, level + 1, prompt);
+ DBG1(DBG_CFG, "expanding file expression '%s' failed",
+ pattern);
}
+ else
+ {
+ for (expanded = buf.gl_pathv; *expanded != NULL; expanded++)
+ {
+ load_secrets(this, *expanded, level + 1, prompt);
+ }
+ }
+ globfree(&buf);
}
- globfree(&buf);
+#else /* HAVE_GLOB_H */
+ /* if glob(3) is not available, try to load pattern directly */
+ load_secrets(this, pattern, level + 1, prompt);
+#endif /* HAVE_GLOB_H */
continue;
}
@@ -994,10 +1096,8 @@ static void load_certs(private_stroke_cred_t *this)
load_certdir(this, CRL_DIR, CERT_X509_CRL, 0);
}
-/**
- * Implementation of stroke_cred_t.reread.
- */
-static void reread(private_stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt)
+METHOD(stroke_cred_t, reread, void,
+ private_stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt)
{
if (msg->reread.flags & REREAD_SECRETS)
{
@@ -1037,10 +1137,14 @@ static void reread(private_stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt)
}
}
-/**
- * Implementation of stroke_cred_t.destroy
- */
-static void destroy(private_stroke_cred_t *this)
+METHOD(stroke_cred_t, add_shared, void,
+ private_stroke_cred_t *this, shared_key_t *shared, linked_list_t *owners)
+{
+ this->creds->add_shared_list(this->creds, shared, owners);
+}
+
+METHOD(stroke_cred_t, destroy, void,
+ private_stroke_cred_t *this)
{
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
this->creds->destroy(this->creds);
@@ -1052,27 +1156,36 @@ static void destroy(private_stroke_cred_t *this)
*/
stroke_cred_t *stroke_cred_create()
{
- private_stroke_cred_t *this = malloc_thing(private_stroke_cred_t);
-
- this->public.set.create_private_enumerator = (void*)return_null;
- this->public.set.create_cert_enumerator = (void*)return_null;
- this->public.set.create_shared_enumerator = (void*)return_null;
- this->public.set.create_cdp_enumerator = (void*)return_null;
- this->public.set.cache_cert = (void*)cache_cert;
- this->public.reread = (void(*)(stroke_cred_t*, stroke_msg_t *msg, FILE*))reread;
- this->public.load_ca = (certificate_t*(*)(stroke_cred_t*, char *filename))load_ca;
- this->public.load_peer = (certificate_t*(*)(stroke_cred_t*, char *filename))load_peer;
- this->public.cachecrl = (void(*)(stroke_cred_t*, bool enabled))cachecrl;
- this->public.destroy = (void(*)(stroke_cred_t*))destroy;
-
- this->creds = mem_cred_create();
+ private_stroke_cred_t *this;
+
+ INIT(this,
+ .public = {
+ .set = {
+ .create_private_enumerator = (void*)return_null,
+ .create_cert_enumerator = (void*)return_null,
+ .create_shared_enumerator = (void*)return_null,
+ .create_cdp_enumerator = (void*)return_null,
+ .cache_cert = (void*)_cache_cert,
+ },
+ .reread = _reread,
+ .load_ca = _load_ca,
+ .load_peer = _load_peer,
+ .load_pubkey = _load_pubkey,
+ .add_shared = _add_shared,
+ .cachecrl = _cachecrl,
+ .destroy = _destroy,
+ },
+ .creds = mem_cred_create(),
+ );
+
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
+ this->force_ca_cert = lib->settings->get_bool(lib->settings,
+ "charon.plugins.stroke.ignore_missing_ca_basic_constraint", FALSE);
+
load_certs(this);
load_secrets(this, SECRETS_FILE, 0, NULL);
- this->cachecrl = FALSE;
-
return &this->public;
}
diff --git a/src/libcharon/plugins/stroke/stroke_cred.h b/src/libcharon/plugins/stroke/stroke_cred.h
index ccee7d87c..83e648819 100644
--- a/src/libcharon/plugins/stroke/stroke_cred.h
+++ b/src/libcharon/plugins/stroke/stroke_cred.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -26,6 +27,7 @@
#include <stroke_msg.h>
#include <credentials/credential_set.h>
#include <credentials/certificates/certificate.h>
+#include <utils/linked_list.h>
typedef struct stroke_cred_t stroke_cred_t;
@@ -56,7 +58,7 @@ struct stroke_cred_t {
certificate_t* (*load_ca)(stroke_cred_t *this, char *filename);
/**
- * Load a peer certificate and serve it rhrough the credential_set.
+ * Load a peer certificate and serve it through the credential_set.
*
* @param filename file to load peer cert from
* @return reference to loaded certificate, or NULL
@@ -64,6 +66,26 @@ struct stroke_cred_t {
certificate_t* (*load_peer)(stroke_cred_t *this, char *filename);
/**
+ * Load a raw public key and serve it through the credential_set.
+ *
+ * @param type type of the raw public key (RSA or ECDSA)
+ * @param filename file to load raw public key from
+ * @param identity identity of the raw public key owner
+ * @return reference to loaded raw public key, or NULL
+ */
+ certificate_t* (*load_pubkey)(stroke_cred_t *this, key_type_t type,
+ char *filename, identification_t *identity);
+
+ /**
+ * Add a shared secret to serve through the credential_set.
+ *
+ * @param shared shared key to add, gets owned
+ * @param owners list of owners (identification_t*), gets owned
+ */
+ void (*add_shared)(stroke_cred_t *this, shared_key_t *shared,
+ linked_list_t *owners);
+
+ /**
* Enable/Disable CRL caching to disk.
*
* @param enabled TRUE to enable, FALSE to disable
diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c
index 6c42f8f8a..514a91e2b 100644
--- a/src/libcharon/plugins/stroke/stroke_list.c
+++ b/src/libcharon/plugins/stroke/stroke_list.c
@@ -15,6 +15,7 @@
#include "stroke_list.h"
+#include <inttypes.h>
#include <time.h>
#ifdef HAVE_MALLINFO
@@ -24,6 +25,7 @@
#include <hydra.h>
#include <daemon.h>
#include <utils/linked_list.h>
+#include <plugins/plugin.h>
#include <credentials/certificates/x509.h>
#include <credentials/certificates/ac.h>
#include <credentials/certificates/crl.h>
@@ -116,7 +118,7 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
ike_proposal = ike_sa->get_proposal(ike_sa);
- fprintf(out, "%12s[%d]: IKE SPIs: %.16llx_i%s %.16llx_r%s",
+ fprintf(out, "%12s[%d]: IKE SPIs: %.16"PRIx64"_i%s %.16"PRIx64"_r%s",
ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
id->get_initiator_spi(id), id->is_initiator(id) ? "*" : "",
id->get_responder_spi(id), id->is_initiator(id) ? "" : "*");
@@ -221,11 +223,14 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
{
u_int16_t encr_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED;
u_int16_t encr_size = 0, int_size = 0;
+ u_int16_t esn = NO_EXT_SEQ_NUMBERS;
proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
&encr_alg, &encr_size);
proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
&int_alg, &int_size);
+ proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS,
+ &esn, NULL);
if (encr_alg != ENCR_UNDEFINED)
{
@@ -243,21 +248,25 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
fprintf(out, "_%u", int_size);
}
}
+ if (esn == EXT_SEQ_NUMBERS)
+ {
+ fprintf(out, "/ESN");
+ }
}
now = time_monotonic(NULL);
child_sa->get_usestats(child_sa, TRUE, &use_in, &bytes_in);
- fprintf(out, ", %llu bytes_i", bytes_in);
+ fprintf(out, ", %" PRIu64 " bytes_i", bytes_in);
if (use_in)
{
- fprintf(out, " (%ds ago)", now - use_in);
+ fprintf(out, " (%" PRIu64 "s ago)", (u_int64_t)(now - use_in));
}
child_sa->get_usestats(child_sa, FALSE, &use_out, &bytes_out);
- fprintf(out, ", %llu bytes_o", bytes_out);
+ fprintf(out, ", %" PRIu64 " bytes_o", bytes_out);
if (use_out)
{
- fprintf(out, " (%ds ago)", now - use_out);
+ fprintf(out, " (%" PRIu64 "s ago)", (u_int64_t)(now - use_out));
}
fprintf(out, ", rekeying ");
@@ -324,7 +333,7 @@ static void log_auth_cfgs(FILE *out, peer_cfg_t *peer_cfg, bool local)
{
if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR))
{
- fprintf(out, "EAP_%d-%d authentication",
+ fprintf(out, "EAP_%" PRIuPTR "-%" PRIuPTR " authentication",
(uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE),
(uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR));
}
@@ -389,25 +398,27 @@ static void log_auth_cfgs(FILE *out, peer_cfg_t *peer_cfg, bool local)
}
METHOD(stroke_list_t, status, void,
- private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all)
+ private_stroke_list_t *this, stroke_msg_t *msg, FILE *out,
+ bool all, bool wait)
{
enumerator_t *enumerator, *children;
ike_cfg_t *ike_cfg;
child_cfg_t *child_cfg;
child_sa_t *child_sa;
ike_sa_t *ike_sa;
+ linked_list_t *my_ts, *other_ts;
bool first, found = FALSE;
char *name = msg->status.name;
+ u_int half_open;
if (all)
{
peer_cfg_t *peer_cfg;
- plugin_t *plugin;
char *pool;
host_t *host;
u_int32_t dpd;
time_t since, now;
- u_int size, online, offline;
+ u_int size, online, offline, i;
now = time_monotonic(NULL);
since = time(NULL) - (now - this->uptime);
@@ -421,21 +432,24 @@ METHOD(stroke_list_t, status, void,
mi.arena, mi.hblkhd, mi.uordblks, mi.fordblks);
}
#endif /* HAVE_MALLINFO */
- fprintf(out, " worker threads: %d idle of %d,",
+ fprintf(out, " worker threads: %d of %d idle, ",
lib->processor->get_idle_threads(lib->processor),
lib->processor->get_total_threads(lib->processor));
- fprintf(out, " job queue load: %d,",
- lib->processor->get_job_load(lib->processor));
- fprintf(out, " scheduled events: %d\n",
- lib->scheduler->get_job_load(lib->scheduler));
- fprintf(out, " loaded plugins: ");
- enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
- while (enumerator->enumerate(enumerator, &plugin))
+ for (i = 0; i < JOB_PRIO_MAX; i++)
{
- fprintf(out, "%s ", plugin->get_name(plugin));
+ fprintf(out, "%s%d", i == 0 ? "" : "/",
+ lib->processor->get_working_threads(lib->processor, i));
}
- enumerator->destroy(enumerator);
- fprintf(out, "\n");
+ fprintf(out, " working, job queue: ");
+ for (i = 0; i < JOB_PRIO_MAX; i++)
+ {
+ fprintf(out, "%s%d", i == 0 ? "" : "/",
+ lib->processor->get_job_load(lib->processor, i));
+ }
+ fprintf(out, ", scheduled: %d\n",
+ lib->scheduler->get_job_load(lib->scheduler));
+ fprintf(out, " loaded plugins: %s\n",
+ lib->plugins->loaded_plugins(lib->plugins));
first = TRUE;
enumerator = this->attribute->create_pool_enumerator(this->attribute);
@@ -491,12 +505,11 @@ METHOD(stroke_list_t, status, void,
children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
while (children->enumerate(children, &child_cfg))
{
- linked_list_t *my_ts, *other_ts;
-
my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
- fprintf(out, "%12s: child: %#R=== %#R", child_cfg->get_name(child_cfg),
- my_ts, other_ts);
+ fprintf(out, "%12s: child: %#R=== %#R%N",
+ child_cfg->get_name(child_cfg), my_ts, other_ts,
+ ipsec_mode_names, child_cfg->get_mode(child_cfg));
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
@@ -512,10 +525,39 @@ METHOD(stroke_list_t, status, void,
enumerator->destroy(enumerator);
}
+ /* Enumerate shunt policies */
+ first = TRUE;
+ enumerator = charon->shunts->create_enumerator(charon->shunts);
+ while (enumerator->enumerate(enumerator, &child_cfg))
+ {
+ if (name && !streq(name, child_cfg->get_name(child_cfg)))
+ {
+ continue;
+ }
+ if (first)
+ {
+ fprintf(out, "Shunted Connections:\n");
+ first = FALSE;
+ }
+ my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
+ other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
+ fprintf(out, "%12s: %#R=== %#R%N\n",
+ child_cfg->get_name(child_cfg), my_ts, other_ts,
+ ipsec_mode_names, child_cfg->get_mode(child_cfg));
+ my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
+ other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
+ }
+ enumerator->destroy(enumerator);
+
+ /* Enumerate traps */
first = TRUE;
enumerator = charon->traps->create_enumerator(charon->traps);
while (enumerator->enumerate(enumerator, NULL, &child_sa))
{
+ if (name && !streq(name, child_sa->get_name(child_sa)))
+ {
+ continue;
+ }
if (first)
{
fprintf(out, "Routed Connections:\n");
@@ -525,12 +567,17 @@ METHOD(stroke_list_t, status, void,
}
enumerator->destroy(enumerator);
- fprintf(out, "Security Associations:\n");
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ half_open = charon->ike_sa_manager->get_half_open_count(
+ charon->ike_sa_manager, NULL);
+ fprintf(out, "Security Associations (%u up, %u connecting):\n",
+ charon->ike_sa_manager->get_count(charon->ike_sa_manager) - half_open,
+ half_open);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, wait);
while (enumerator->enumerate(enumerator, &ike_sa))
{
bool ike_printed = FALSE;
- iterator_t *children = ike_sa->create_child_sa_iterator(ike_sa);
+ enumerator_t *children = ike_sa->create_child_sa_enumerator(ike_sa);
if (name == NULL || streq(name, ike_sa->get_name(ike_sa)))
{
@@ -539,7 +586,7 @@ METHOD(stroke_list_t, status, void,
ike_printed = TRUE;
}
- while (children->iterate(children, (void**)&child_sa))
+ while (children->enumerate(children, (void**)&child_sa))
{
if (name == NULL || streq(name, child_sa->get_name(child_sa)))
{
@@ -582,35 +629,30 @@ static linked_list_t* create_unique_cert_list(certificate_type_t type)
while (enumerator->enumerate(enumerator, (void**)&cert))
{
- iterator_t *iterator = list->create_iterator(list, TRUE);
+ enumerator_t *added = list->create_enumerator(list);
identification_t *issuer = cert->get_issuer(cert);
- bool previous_same, same = FALSE, last = TRUE;
+ bool previous_same, same = FALSE, found = FALSE;
certificate_t *list_cert;
- while (iterator->iterate(iterator, (void**)&list_cert))
+ while (added->enumerate(added, (void**)&list_cert))
{
- /* exit if we have a duplicate? */
if (list_cert->equals(list_cert, cert))
- {
- last = FALSE;
+ { /* stop if we found a duplicate*/
+ found = TRUE;
break;
}
- /* group certificates with same issuer */
previous_same = same;
same = list_cert->has_issuer(list_cert, issuer);
if (previous_same && !same)
- {
- iterator->insert_before(iterator, (void *)cert->get_ref(cert));
- last = FALSE;
+ { /* group certificates with same issuer */
break;
}
}
- iterator->destroy(iterator);
-
- if (last)
+ if (!found)
{
- list->insert_last(list, (void *)cert->get_ref(cert));
+ list->insert_before(list, added, cert->get_ref(cert));
}
+ added->destroy(added);
}
enumerator->destroy(enumerator);
return list;
@@ -657,12 +699,14 @@ static void list_public_key(public_key_t *public, FILE *out)
static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out)
{
bool first = TRUE;
-
- enumerator_t *enumerator = list->create_enumerator(list);
+ time_t now = time(NULL), notBefore, notAfter;
+ enumerator_t *enumerator;
certificate_t *cert;
+ enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, (void**)&cert))
{
+ identification_t *subject = cert->get_subject(cert);
public_key_t *public = cert->get_public_key(cert);
if (public)
@@ -675,6 +719,41 @@ static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out)
}
fprintf(out, "\n");
+ /* list subject if available */
+ if (subject->get_type(subject) != ID_KEY_ID)
+ {
+ fprintf(out, " subject: %#Y\n", subject);
+ }
+
+ /* list validity if available*/
+ cert->get_validity(cert, &now, &notBefore, &notAfter);
+ if (notBefore != UNDEFINED_TIME && notAfter != UNDEFINED_TIME)
+ {
+ fprintf(out, " validity: not before %T, ", &notBefore, utc);
+ if (now < notBefore)
+ {
+ fprintf(out, "not valid yet (valid in %V)\n", &now, &notBefore);
+ }
+ else
+ {
+ fprintf(out, "ok\n");
+ }
+ fprintf(out, " not after %T, ", &notAfter, utc);
+ if (now > notAfter)
+ {
+ fprintf(out, "expired (%V ago)\n", &now, &notAfter);
+ }
+ else
+ {
+ fprintf(out, "ok");
+ if (now > notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
+ {
+ fprintf(out, " (expires in %V)", &now, &notAfter);
+ }
+ fprintf(out, " \n");
+ }
+ }
+
list_public_key(public, out);
public->destroy(public);
}
@@ -791,7 +870,7 @@ static void stroke_list_certs(linked_list_t *list, char *label,
fprintf(out, " subject: \"%Y\"\n", cert->get_subject(cert));
fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
- serial = x509->get_serial(x509);
+ serial = chunk_skip_zero(x509->get_serial(x509));
fprintf(out, " serial: %#B\n", &serial);
/* list validity */
@@ -904,7 +983,7 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
{
fprintf(out, " hissuer: \"%Y\"\n", id);
}
- chunk = ac->get_holderSerial(ac);
+ chunk = chunk_skip_zero(ac->get_holderSerial(ac));
if (chunk.ptr)
{
fprintf(out, " hserial: %#B\n", &chunk);
@@ -916,7 +995,7 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
groups->destroy(groups);
}
fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
- chunk = ac->get_serial(ac);
+ chunk = chunk_skip_zero(ac->get_serial(ac));
fprintf(out, " serial: %#B\n", &chunk);
/* list validity */
@@ -973,13 +1052,14 @@ static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out)
fprintf(out, " issuer: \"%Y\"\n", cert->get_issuer(cert));
/* list optional crlNumber */
- chunk = crl->get_serial(crl);
+ chunk = chunk_skip_zero(crl->get_serial(crl));
if (chunk.ptr)
{
fprintf(out, " serial: %#B\n", &chunk);
}
if (crl->is_delta_crl(crl, &chunk))
{
+ chunk = chunk_skip_zero(chunk);
fprintf(out, " delta for: %#B\n", &chunk);
}
@@ -1157,6 +1237,58 @@ static void list_algs(FILE *out)
fprintf(out, "\n");
}
+/**
+ * List loaded plugin information
+ */
+static void list_plugins(FILE *out)
+{
+ plugin_feature_t *features, *fp;
+ enumerator_t *enumerator;
+ linked_list_t *list;
+ plugin_t *plugin;
+ int count, i;
+ bool loaded;
+ char *str;
+
+ fprintf(out, "\n");
+ fprintf(out, "List of loaded Plugins:\n");
+ fprintf(out, "\n");
+
+ enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
+ while (enumerator->enumerate(enumerator, &plugin, &list))
+ {
+ fprintf(out, "%s:\n", plugin->get_name(plugin));
+ if (plugin->get_features)
+ {
+ count = plugin->get_features(plugin, &features);
+ for (i = 0; i < count; i++)
+ {
+ str = plugin_feature_get_string(&features[i]);
+ switch (features[i].kind)
+ {
+ case FEATURE_PROVIDE:
+ fp = &features[i];
+ loaded = list->find_first(list, NULL,
+ (void**)&fp) == SUCCESS;
+ fprintf(out, " %s%s\n",
+ str, loaded ? "" : " (not loaded)");
+ break;
+ case FEATURE_DEPENDS:
+ fprintf(out, " %s\n", str);
+ break;
+ case FEATURE_SDEPEND:
+ fprintf(out, " %s(soft)\n", str);
+ break;
+ default:
+ break;
+ }
+ free(str);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
METHOD(stroke_list_t, list, void,
private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
{
@@ -1228,6 +1360,10 @@ METHOD(stroke_list_t, list, void,
{
list_algs(out);
}
+ if (msg->list.flags & LIST_PLUGINS)
+ {
+ list_plugins(out);
+ }
}
/**
diff --git a/src/libcharon/plugins/stroke/stroke_list.h b/src/libcharon/plugins/stroke/stroke_list.h
index b5bedc6c2..a0d2d18cc 100644
--- a/src/libcharon/plugins/stroke/stroke_list.h
+++ b/src/libcharon/plugins/stroke/stroke_list.h
@@ -47,8 +47,10 @@ struct stroke_list_t {
* @param msg stroke message
* @param out stroke console stream
* @param all TRUE for "statusall"
+ * @param wait TRUE to wait for IKE_SA entries, FALSE to skip if locked
*/
- void (*status)(stroke_list_t *this, stroke_msg_t *msg, FILE *out, bool all);
+ void (*status)(stroke_list_t *this, stroke_msg_t *msg, FILE *out,
+ bool all, bool wait);
/**
* Log pool leases to stroke console.
diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c
index 88d0270d8..57648feb8 100644
--- a/src/libcharon/plugins/stroke/stroke_socket.c
+++ b/src/libcharon/plugins/stroke/stroke_socket.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2011-2012 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -20,13 +21,15 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
-#include <sys/fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <hydra.h>
#include <daemon.h>
+#include <threading/mutex.h>
#include <threading/thread.h>
+#include <threading/condvar.h>
+#include <utils/linked_list.h>
#include <processing/jobs/callback_job.h>
#include "stroke_config.h"
@@ -36,6 +39,12 @@
#include "stroke_attribute.h"
#include "stroke_list.h"
+/**
+ * To avoid clogging the thread pool with (blocking) jobs, we limit the number
+ * of concurrently handled stroke commands.
+ */
+#define MAX_CONCURRENT_DEFAULT 4
+
typedef struct stroke_job_context_t stroke_job_context_t;
typedef struct private_stroke_socket_t private_stroke_socket_t;
@@ -57,7 +66,37 @@ struct private_stroke_socket_t {
/**
* job accepting stroke messages
*/
- callback_job_t *job;
+ callback_job_t *receiver;
+
+ /**
+ * job handling stroke messages
+ */
+ callback_job_t *handler;
+
+ /**
+ * queued stroke commands
+ */
+ linked_list_t *commands;
+
+ /**
+ * lock for command list
+ */
+ mutex_t *mutex;
+
+ /**
+ * condvar to signal the arrival or completion of commands
+ */
+ condvar_t *condvar;
+
+ /**
+ * the number of currently handled commands
+ */
+ u_int handling;
+
+ /**
+ * the maximum number of concurrently handled commands
+ */
+ u_int max_concurrent;
/**
* configuration backend
@@ -85,7 +124,7 @@ struct private_stroke_socket_t {
stroke_ca_t *ca;
/**
- * Status information logging
+ * status information logging
*/
stroke_list_t *list;
};
@@ -146,6 +185,7 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
pop_string(msg, &end->auth2);
pop_string(msg, &end->id);
pop_string(msg, &end->id2);
+ pop_string(msg, &end->rsakey);
pop_string(msg, &end->cert);
pop_string(msg, &end->cert2);
pop_string(msg, &end->ca);
@@ -161,6 +201,7 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
DBG2(DBG_CFG, " %sauth2=%s", label, end->auth2);
DBG2(DBG_CFG, " %sid=%s", label, end->id);
DBG2(DBG_CFG, " %sid2=%s", label, end->id2);
+ DBG2(DBG_CFG, " %srsakey=%s", label, end->rsakey);
DBG2(DBG_CFG, " %scert=%s", label, end->cert);
DBG2(DBG_CFG, " %scert2=%s", label, end->cert2);
DBG2(DBG_CFG, " %sca=%s", label, end->ca);
@@ -190,6 +231,9 @@ static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg)
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, " dpddelay=%d", msg->add_conn.dpd.delay);
+ DBG2(DBG_CFG, " dpdaction=%d", msg->add_conn.dpd.action);
+ DBG2(DBG_CFG, " closeaction=%d", msg->add_conn.close_action);
DBG2(DBG_CFG, " mediation=%s", msg->add_conn.ikeme.mediation ? "yes" : "no");
DBG2(DBG_CFG, " mediated_by=%s", msg->add_conn.ikeme.mediated_by);
DBG2(DBG_CFG, " me_peerid=%s", msg->add_conn.ikeme.peerid);
@@ -322,11 +366,11 @@ static void stroke_del_ca(private_stroke_socket_t *this,
* show status of daemon
*/
static void stroke_status(private_stroke_socket_t *this,
- stroke_msg_t *msg, FILE *out, bool all)
+ stroke_msg_t *msg, FILE *out, bool all, bool wait)
{
pop_string(msg, &(msg->status.name));
- this->list->status(this->list, msg, out, all);
+ this->list->status(this->list, msg, out, all, wait);
}
/**
@@ -382,7 +426,7 @@ static void stroke_export(private_stroke_socket_t *this,
{
pop_string(msg, &msg->export.selector);
- if (msg->purge.flags & EXPORT_X509)
+ if (msg->export.flags & EXPORT_X509)
{
enumerator_t *enumerator;
identification_t *id;
@@ -418,6 +462,33 @@ static void stroke_leases(private_stroke_socket_t *this,
}
/**
+ * Show memory usage
+ */
+static void stroke_memusage(private_stroke_socket_t *this,
+ stroke_msg_t *msg, FILE *out)
+{
+ if (lib->leak_detective)
+ {
+ lib->leak_detective->usage(lib->leak_detective, out);
+ }
+}
+
+/**
+ * Set username and password for a connection
+ */
+static void stroke_user_creds(private_stroke_socket_t *this,
+ stroke_msg_t *msg, FILE *out)
+{
+ pop_string(msg, &msg->user_creds.name);
+ pop_string(msg, &msg->user_creds.username);
+ pop_string(msg, &msg->user_creds.password);
+
+ DBG1(DBG_CFG, "received stroke: user-creds '%s'", msg->user_creds.name);
+
+ this->config->set_user_credentials(this->config, msg, out);
+}
+
+/**
* set the verbosity debug output
*/
static void stroke_loglevel(private_stroke_socket_t *this,
@@ -433,7 +504,7 @@ static void stroke_loglevel(private_stroke_socket_t *this,
msg->loglevel.level, msg->loglevel.type);
group = enum_from_name(debug_names, msg->loglevel.type);
- if (group < 0)
+ if ((int)group < 0)
{
fprintf(out, "invalid type (%s)!\n", msg->loglevel.type);
return;
@@ -475,6 +546,18 @@ static void stroke_job_context_destroy(stroke_job_context_t *this)
}
/**
+ * called to signal the completion of a command
+ */
+static inline job_requeue_t job_processed(private_stroke_socket_t *this)
+{
+ this->mutex->lock(this->mutex);
+ this->handling--;
+ this->condvar->signal(this->condvar);
+ this->mutex->unlock(this->mutex);
+ return JOB_REQUEUE_NONE;
+}
+
+/**
* process a stroke request from the socket pointed by "fd"
*/
static job_requeue_t process(stroke_job_context_t *ctx)
@@ -492,7 +575,7 @@ static job_requeue_t process(stroke_job_context_t *ctx)
{
DBG1(DBG_CFG, "reading length of stroke message failed: %s",
strerror(errno));
- return JOB_REQUEUE_NONE;
+ return job_processed(this);
}
/* read message */
@@ -501,14 +584,14 @@ static job_requeue_t process(stroke_job_context_t *ctx)
if (bytes_read != msg_length)
{
DBG1(DBG_CFG, "reading stroke message failed: %s", strerror(errno));
- return JOB_REQUEUE_NONE;
+ return job_processed(this);
}
out = fdopen(strokefd, "w+");
if (out == NULL)
{
DBG1(DBG_CFG, "opening stroke output channel failed: %s", strerror(errno));
- return JOB_REQUEUE_NONE;
+ return job_processed(this);
}
DBG3(DBG_CFG, "stroke message %b", (void*)msg, msg_length);
@@ -534,10 +617,13 @@ static job_requeue_t process(stroke_job_context_t *ctx)
stroke_rekey(this, msg, out);
break;
case STR_STATUS:
- stroke_status(this, msg, out, FALSE);
+ stroke_status(this, msg, out, FALSE, TRUE);
break;
case STR_STATUS_ALL:
- stroke_status(this, msg, out, TRUE);
+ stroke_status(this, msg, out, TRUE, TRUE);
+ break;
+ case STR_STATUS_ALL_NOBLK:
+ stroke_status(this, msg, out, TRUE, FALSE);
break;
case STR_ADD_CONN:
stroke_add_conn(this, msg);
@@ -572,6 +658,12 @@ static job_requeue_t process(stroke_job_context_t *ctx)
case STR_LEASES:
stroke_leases(this, msg, out);
break;
+ case STR_MEMUSAGE:
+ stroke_memusage(this, msg, out);
+ break;
+ case STR_USER_CREDS:
+ stroke_user_creds(this, msg, out);
+ break;
default:
DBG1(DBG_CFG, "received unknown stroke");
break;
@@ -579,11 +671,38 @@ static job_requeue_t process(stroke_job_context_t *ctx)
fclose(out);
/* fclose() closes underlying FD */
ctx->fd = 0;
- return JOB_REQUEUE_NONE;
+ return job_processed(this);
+}
+
+/**
+ * Handle queued stroke commands
+ */
+static job_requeue_t handle(private_stroke_socket_t *this)
+{
+ stroke_job_context_t *ctx;
+ callback_job_t *job;
+ bool oldstate;
+
+ this->mutex->lock(this->mutex);
+ thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
+ oldstate = thread_cancelability(TRUE);
+ while (this->commands->get_count(this->commands) == 0 ||
+ this->handling >= this->max_concurrent)
+ {
+ this->condvar->wait(this->condvar, this->mutex);
+ }
+ thread_cancelability(oldstate);
+ this->commands->remove_first(this->commands, (void**)&ctx);
+ this->handling++;
+ thread_cleanup_pop(TRUE);
+ job = callback_job_create_with_prio((callback_job_cb_t)process, ctx,
+ (void*)stroke_job_context_destroy, this->handler, JOB_PRIO_HIGH);
+ lib->processor->queue_job(lib->processor, (job_t*)job);
+ return JOB_REQUEUE_DIRECT;
}
/**
- * Implementation of private_stroke_socket_t.stroke_receive.
+ * Accept stroke commands and queue them to be handled
*/
static job_requeue_t receive(private_stroke_socket_t *this)
{
@@ -591,7 +710,6 @@ static job_requeue_t receive(private_stroke_socket_t *this)
int strokeaddrlen = sizeof(strokeaddr);
int strokefd;
bool oldstate;
- callback_job_t *job;
stroke_job_context_t *ctx;
oldstate = thread_cancelability(TRUE);
@@ -604,17 +722,18 @@ static job_requeue_t receive(private_stroke_socket_t *this)
return JOB_REQUEUE_FAIR;
}
- ctx = malloc_thing(stroke_job_context_t);
- ctx->fd = strokefd;
- ctx->this = this;
- job = callback_job_create((callback_job_cb_t)process,
- ctx, (void*)stroke_job_context_destroy, this->job);
- lib->processor->queue_job(lib->processor, (job_t*)job);
+ INIT(ctx,
+ .fd = strokefd,
+ .this = this,
+ );
+ this->mutex->lock(this->mutex);
+ this->commands->insert_last(this->commands, ctx);
+ this->condvar->signal(this->condvar);
+ this->mutex->unlock(this->mutex);
return JOB_REQUEUE_FAIR;
}
-
/**
* initialize and open stroke socket
*/
@@ -659,12 +778,14 @@ static bool open_socket(private_stroke_socket_t *this)
return TRUE;
}
-/**
- * Implementation of stroke_socket_t.destroy
- */
-static void destroy(private_stroke_socket_t *this)
+METHOD(stroke_socket_t, destroy, void,
+ private_stroke_socket_t *this)
{
- this->job->cancel(this->job);
+ this->handler->cancel(this->handler);
+ this->receiver->cancel(this->receiver);
+ this->commands->destroy_function(this->commands, (void*)stroke_job_context_destroy);
+ this->condvar->destroy(this->condvar);
+ this->mutex->destroy(this->mutex);
lib->credmgr->remove_set(lib->credmgr, &this->ca->set);
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
charon->backends->remove_backend(charon->backends, &this->config->backend);
@@ -683,9 +804,13 @@ static void destroy(private_stroke_socket_t *this)
*/
stroke_socket_t *stroke_socket_create()
{
- private_stroke_socket_t *this = malloc_thing(private_stroke_socket_t);
+ private_stroke_socket_t *this;
- this->public.destroy = (void(*)(stroke_socket_t*))destroy;
+ INIT(this,
+ .public = {
+ .destroy = _destroy,
+ },
+ );
if (!open_socket(this))
{
@@ -700,14 +825,24 @@ stroke_socket_t *stroke_socket_create()
this->control = stroke_control_create();
this->list = stroke_list_create(this->attribute);
+ this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
+ this->condvar = condvar_create(CONDVAR_TYPE_DEFAULT);
+ this->commands = linked_list_create();
+ this->max_concurrent = lib->settings->get_int(lib->settings,
+ "charon.plugins.stroke.max_concurrent", MAX_CONCURRENT_DEFAULT);
+
lib->credmgr->add_set(lib->credmgr, &this->ca->set);
lib->credmgr->add_set(lib->credmgr, &this->cred->set);
charon->backends->add_backend(charon->backends, &this->config->backend);
hydra->attributes->add_provider(hydra->attributes, &this->attribute->provider);
- this->job = callback_job_create((callback_job_cb_t)receive,
- this, NULL, NULL);
- lib->processor->queue_job(lib->processor, (job_t*)this->job);
+ this->receiver = callback_job_create_with_prio((callback_job_cb_t)receive,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
+ lib->processor->queue_job(lib->processor, (job_t*)this->receiver);
+
+ this->handler = callback_job_create_with_prio((callback_job_cb_t)handle,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
+ lib->processor->queue_job(lib->processor, (job_t*)this->handler);
return &this->public;
}
diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.am b/src/libcharon/plugins/tnc_ifmap/Makefile.am
new file mode 100644
index 000000000..b8a57b119
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap/Makefile.am
@@ -0,0 +1,21 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon ${axis2c_CFLAGS}
+
+AM_CFLAGS = -rdynamic
+
+libstrongswan_tnc_ifmap_la_LIBADD = ${axis2c_LIBS} -laxutil -laxis2_engine -laxis2_http_sender
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-tnc-ifmap.la
+else
+plugin_LTLIBRARIES = libstrongswan-tnc-ifmap.la
+endif
+
+libstrongswan_tnc_ifmap_la_SOURCES = \
+ tnc_ifmap_plugin.h tnc_ifmap_plugin.c \
+ tnc_ifmap_listener.h tnc_ifmap_listener.c \
+ tnc_ifmap_soap.h tnc_ifmap_soap.c
+
+libstrongswan_tnc_ifmap_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.in b/src/libcharon/plugins/tnc_ifmap/Makefile.in
new file mode 100644
index 000000000..54deb7cd7
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap/Makefile.in
@@ -0,0 +1,620 @@
+# 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/tnc_ifmap
+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)
+am__DEPENDENCIES_1 =
+libstrongswan_tnc_ifmap_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libstrongswan_tnc_ifmap_la_OBJECTS = tnc_ifmap_plugin.lo \
+ tnc_ifmap_listener.lo tnc_ifmap_soap.lo
+libstrongswan_tnc_ifmap_la_OBJECTS = \
+ $(am_libstrongswan_tnc_ifmap_la_OBJECTS)
+libstrongswan_tnc_ifmap_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_tnc_ifmap_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_tnc_ifmap_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_tnc_ifmap_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_tnc_ifmap_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_tnc_ifmap_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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 ${axis2c_CFLAGS}
+
+AM_CFLAGS = -rdynamic
+libstrongswan_tnc_ifmap_la_LIBADD = ${axis2c_LIBS} -laxutil -laxis2_engine -laxis2_http_sender
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-ifmap.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-ifmap.la
+libstrongswan_tnc_ifmap_la_SOURCES = \
+ tnc_ifmap_plugin.h tnc_ifmap_plugin.c \
+ tnc_ifmap_listener.h tnc_ifmap_listener.c \
+ tnc_ifmap_soap.h tnc_ifmap_soap.c
+
+libstrongswan_tnc_ifmap_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/tnc_ifmap/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_ifmap/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-tnc-ifmap.la: $(libstrongswan_tnc_ifmap_la_OBJECTS) $(libstrongswan_tnc_ifmap_la_DEPENDENCIES)
+ $(libstrongswan_tnc_ifmap_la_LINK) $(am_libstrongswan_tnc_ifmap_la_rpath) $(libstrongswan_tnc_ifmap_la_OBJECTS) $(libstrongswan_tnc_ifmap_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_ifmap_listener.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_ifmap_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_ifmap_soap.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/tnc_ifmap/tnc_ifmap_listener.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c
new file mode 100644
index 000000000..4fd33696c
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2011 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_ifmap_listener.h"
+#include "tnc_ifmap_soap.h"
+
+#include <daemon.h>
+#include <hydra.h>
+#include <debug.h>
+
+typedef struct private_tnc_ifmap_listener_t private_tnc_ifmap_listener_t;
+
+/**
+ * Private data of an tnc_ifmap_listener_t object.
+ */
+struct private_tnc_ifmap_listener_t {
+
+ /**
+ * Public tnc_ifmap_listener_t interface.
+ */
+ tnc_ifmap_listener_t public;
+
+ /**
+ * TNC IF-MAP 2.0 SOAP interface
+ */
+ tnc_ifmap_soap_t *ifmap;
+
+};
+
+/**
+ * Publish PEP device-ip metadata
+ */
+static bool publish_device_ip_addresses(private_tnc_ifmap_listener_t *this)
+{
+ enumerator_t *enumerator;
+ host_t *host;
+ bool success = TRUE;
+
+ enumerator = hydra->kernel_interface->create_address_enumerator(
+ hydra->kernel_interface, FALSE, FALSE);
+ while (enumerator->enumerate(enumerator, &host))
+ {
+ if (!this->ifmap->publish_device_ip(this->ifmap, host))
+ {
+ success = FALSE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return success;
+}
+
+/**
+ * Publish all IKE_SA metadata
+ */
+static bool reload_metadata(private_tnc_ifmap_listener_t *this)
+{
+ enumerator_t *enumerator;
+ ike_sa_t *ike_sa;
+ bool success = TRUE;
+
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, FALSE);
+ while (enumerator->enumerate(enumerator, &ike_sa))
+ {
+ if (ike_sa->get_state(ike_sa) != IKE_ESTABLISHED)
+ {
+ continue;
+ }
+ if (!this->ifmap->publish_ike_sa(this->ifmap, ike_sa, TRUE))
+ {
+ success = FALSE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return success;
+}
+
+METHOD(listener_t, ike_updown, bool,
+ private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, bool up)
+{
+ if (ike_sa->get_state(ike_sa) != IKE_CONNECTING)
+ {
+ this->ifmap->publish_ike_sa(this->ifmap, ike_sa, up);
+ }
+ return TRUE;
+}
+
+METHOD(listener_t, alert, bool,
+ private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, alert_t alert,
+ va_list args)
+{
+ if (alert == ALERT_PEER_AUTH_FAILED)
+ {
+ this->ifmap->publish_enforcement_report(this->ifmap,
+ ike_sa->get_other_host(ike_sa),
+ "block", "authentication failed");
+ }
+ return TRUE;
+}
+
+METHOD(tnc_ifmap_listener_t, destroy, void,
+ private_tnc_ifmap_listener_t *this)
+{
+ DESTROY_IF(this->ifmap);
+ free(this);
+}
+
+/**
+ * See header
+ */
+tnc_ifmap_listener_t *tnc_ifmap_listener_create(bool reload)
+{
+ private_tnc_ifmap_listener_t *this;
+
+ INIT(this,
+ .public = {
+ .listener = {
+ .ike_updown = _ike_updown,
+ .alert = _alert,
+ },
+ .destroy = _destroy,
+ },
+ .ifmap = tnc_ifmap_soap_create(),
+ );
+
+ if (!this->ifmap)
+ {
+ destroy(this);
+ return NULL;
+ }
+ if (!this->ifmap->newSession(this->ifmap))
+ {
+ destroy(this);
+ return NULL;
+ }
+ if (!this->ifmap->purgePublisher(this->ifmap))
+ {
+ destroy(this);
+ return NULL;
+ }
+ if (!publish_device_ip_addresses(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ if (reload)
+ {
+ if (!reload_metadata(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+ }
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h
new file mode 100644
index 000000000..878505b38
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 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_ifmap_listener tnc_ifmap_listener
+ * @{ @ingroup tnc_ifmap
+ */
+
+#ifndef TNC_IFMAP_LISTENER_H_
+#define TNC_IFMAP_LISTENER_H_
+
+#include <bus/bus.h>
+
+typedef struct tnc_ifmap_listener_t tnc_ifmap_listener_t;
+
+/**
+ * Listener which collects information on IKE_SAs
+ */
+struct tnc_ifmap_listener_t {
+
+ /**
+ * Implements listener_t.
+ */
+ listener_t listener;
+
+ /**
+ * Destroy a tnc_ifmap_listener_t.
+ */
+ void (*destroy)(tnc_ifmap_listener_t *this);
+};
+
+/**
+ * Create a tnc_ifmap_listener instance.
+ *
+ * @param reload reload all IKE_SA metadata
+ */
+tnc_ifmap_listener_t *tnc_ifmap_listener_create(bool reload);
+
+#endif /** TNC_IFMAP_LISTENER_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.c
new file mode 100644
index 000000000..de4d12e0b
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 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_ifmap_plugin.h"
+#include "tnc_ifmap_listener.h"
+
+#include <daemon.h>
+
+typedef struct private_tnc_ifmap_plugin_t private_tnc_ifmap_plugin_t;
+
+/**
+ * private data of tnc_ifmap plugin
+ */
+struct private_tnc_ifmap_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ tnc_ifmap_plugin_t public;
+
+ /**
+ * Listener interface, listens to CHILD_SA state changes
+ */
+ tnc_ifmap_listener_t *listener;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_tnc_ifmap_plugin_t *this)
+{
+ return "tnc-ifmap";
+}
+
+METHOD(plugin_t, reload, bool,
+ private_tnc_ifmap_plugin_t *this)
+{
+ if (this->listener)
+ {
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ this->listener->destroy(this->listener);
+ }
+
+ this->listener = tnc_ifmap_listener_create(TRUE);
+ if (!this->listener)
+ {
+ return FALSE;
+ }
+
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+ return TRUE;
+}
+
+METHOD(plugin_t, destroy, void,
+ private_tnc_ifmap_plugin_t *this)
+{
+ if (this->listener)
+ {
+ charon->bus->remove_listener(charon->bus, &this->listener->listener);
+ this->listener->destroy(this->listener);
+ }
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *tnc_ifmap_plugin_create()
+{
+ private_tnc_ifmap_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .reload = _reload,
+ .destroy = _destroy,
+ },
+ },
+ .listener = tnc_ifmap_listener_create(FALSE),
+ );
+
+ if (this->listener)
+ {
+ charon->bus->add_listener(charon->bus, &this->listener->listener);
+ }
+ return &this->public.plugin;
+}
+
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.h
new file mode 100644
index 000000000..8172be7c9
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 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_ifmap tnc_ifmap
+ * @ingroup cplugins
+ *
+ * @defgroup tnc_ifmap_plugin tnc_ifmap_plugin
+ * @{ @ingroup tnc_ifmap
+ */
+
+#ifndef TNC_IFMAP_PLUGIN_H_
+#define TNC_IFMAP_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct tnc_ifmap_plugin_t tnc_ifmap_plugin_t;
+
+/**
+ * TNC IF-MAP plugin
+ */
+struct tnc_ifmap_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** TNC_IFMAP_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c
new file mode 100644
index 000000000..913cdab12
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.c
@@ -0,0 +1,859 @@
+/*
+ * Copyright (C) 2011 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_ifmap_soap.h"
+
+#include <debug.h>
+
+#include <axis2_util.h>
+#include <axis2_client.h>
+#include <axis2_http_transport.h>
+#include <axis2_http_transport_sender.h>
+#include <axiom_soap.h>
+
+#define IFMAP_NS "http://www.trustedcomputinggroup.org/2010/IFMAP/2"
+#define IFMAP_META_NS "http://www.trustedcomputinggroup.org/2010/IFMAP-METADATA/2"
+#define IFMAP_LOGFILE "strongswan_ifmap.log"
+#define IFMAP_SERVER "https://localhost:8443/"
+
+typedef struct private_tnc_ifmap_soap_t private_tnc_ifmap_soap_t;
+
+/**
+ * Private data of an tnc_ifmap_soap_t object.
+ */
+struct private_tnc_ifmap_soap_t {
+
+ /**
+ * Public tnc_ifmap_soap_t interface.
+ */
+ tnc_ifmap_soap_t public;
+
+ /**
+ * Axis2/C environment
+ */
+ axutil_env_t *env;
+
+ /**
+ * Axis2 service client
+ */
+ axis2_svc_client_t* svc_client;
+
+ /**
+ * SOAP Session ID
+ */
+ char *session_id;
+
+ /**
+ * IF-MAP Publisher ID
+ */
+ char *ifmap_publisher_id;
+
+ /**
+ * PEP and PDP device name
+ */
+ char *device_name;
+
+};
+
+/**
+ * Send request and receive result via SOAP
+ */
+static axiom_element_t* send_receive(private_tnc_ifmap_soap_t *this,
+ char *request_qname, axiom_node_t *request,
+ char *receipt_qname, axiom_node_t **result)
+
+{
+ axiom_node_t *parent, *node;
+ axiom_element_t *parent_el, *el;
+ axutil_qname_t *qname;
+
+ /* send request and receive result */
+ DBG2(DBG_TNC, "sending ifmap %s", request_qname);
+
+ parent = axis2_svc_client_send_receive(this->svc_client, this->env, request);
+ if (!parent)
+ {
+ DBG1(DBG_TNC, "no ifmap %s received from MAP server", receipt_qname);
+ return NULL;
+ }
+ DBG2(DBG_TNC, "received ifmap %s", receipt_qname);
+
+ /* extract the parent element */
+ parent_el = (axiom_element_t*)axiom_node_get_data_element(parent, this->env);
+
+ /* look for a child node with the given receipt qname */
+ qname = axutil_qname_create_from_string(this->env, strdup(receipt_qname));
+ el = axiom_element_get_first_child_with_qname(parent_el, this->env, qname,
+ parent, &node);
+ axutil_qname_free(qname, this->env);
+
+ if (el)
+ {
+ if (result)
+ {
+ *result = parent;
+ }
+ else
+ {
+ /* no further processing requested */
+ axiom_node_free_tree(parent, this->env);
+ }
+ return el;
+ }
+ DBG1(DBG_TNC, "child node with qname '%s' not found", receipt_qname);
+
+ /* free parent in the error case */
+ axiom_node_free_tree(parent, this->env);
+
+ return NULL;
+}
+
+METHOD(tnc_ifmap_soap_t, newSession, bool,
+ private_tnc_ifmap_soap_t *this)
+{
+ axiom_node_t *request, *result;
+ axiom_element_t *el;
+ axiom_namespace_t *ns;
+ axis2_char_t *value;
+
+
+ /* build newSession request */
+ ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
+ el = axiom_element_create(this->env, NULL, "newSession", ns, &request);
+
+ /* send newSession request and receive newSessionResult */
+ el = send_receive(this, "newSession", request, "newSessionResult", &result);
+ if (!el)
+ {
+ return FALSE;
+ }
+
+ /* get session-id */
+ value = axiom_element_get_attribute_value_by_name(el, this->env,
+ "session-id");
+ this->session_id = strdup(value);
+
+ /* get ifmap-publisher-id */
+ value = axiom_element_get_attribute_value_by_name(el, this->env,
+ "ifmap-publisher-id");
+ this->ifmap_publisher_id = strdup(value);
+
+ DBG1(DBG_TNC, "session-id: %s, ifmap-publisher-id: %s",
+ this->session_id, this->ifmap_publisher_id);
+
+ /* set PEP and PDP device name (defaults to IF-MAP Publisher ID) */
+ this->device_name = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.device_name",
+ this->ifmap_publisher_id);
+ this->device_name = strdup(this->device_name);
+
+ /* free result */
+ axiom_node_free_tree(result, this->env);
+
+ return this->session_id && this->ifmap_publisher_id;
+}
+
+METHOD(tnc_ifmap_soap_t, purgePublisher, bool,
+ private_tnc_ifmap_soap_t *this)
+{
+ axiom_node_t *request;
+ axiom_element_t *el;
+ axiom_namespace_t *ns;
+ axiom_attribute_t *attr;
+
+ /* build purgePublisher request */
+ ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
+ el = axiom_element_create(this->env, NULL, "purgePublisher", ns, &request);
+ attr = axiom_attribute_create(this->env, "session-id",
+ this->session_id, NULL);
+ axiom_element_add_attribute(el, this->env, attr, request);
+ attr = axiom_attribute_create(this->env, "ifmap-publisher-id",
+ this->ifmap_publisher_id, NULL);
+ axiom_element_add_attribute(el, this->env, attr, request);
+
+ /* send purgePublisher request and receive purgePublisherReceived */
+ return send_receive(this, "purgePublisher", request,
+ "purgePublisherReceived", NULL);
+}
+
+/**
+ * Create an access-request based on device_name and ike_sa_id
+ */
+static axiom_node_t* create_access_request(private_tnc_ifmap_soap_t *this,
+ u_int32_t id)
+{
+ axiom_element_t *el;
+ axiom_node_t *node;
+ axiom_attribute_t *attr;
+ char buf[BUF_LEN];
+
+ el = axiom_element_create(this->env, NULL, "access-request", NULL, &node);
+
+ snprintf(buf, BUF_LEN, "%s:%d", this->device_name, id);
+ attr = axiom_attribute_create(this->env, "name", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+
+ return node;
+}
+
+/**
+ * Create an identity
+ */
+static axiom_node_t* create_identity(private_tnc_ifmap_soap_t *this,
+ identification_t *id, bool is_user)
+{
+ axiom_element_t *el;
+ axiom_node_t *node;
+ axiom_attribute_t *attr;
+ char buf[BUF_LEN], *id_type;
+
+ el = axiom_element_create(this->env, NULL, "identity", NULL, &node);
+
+ snprintf(buf, BUF_LEN, "%Y", id);
+ attr = axiom_attribute_create(this->env, "name", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+
+ switch (id->get_type(id))
+ {
+ case ID_IPV4_ADDR:
+ id_type = "other";
+ attr = axiom_attribute_create(this->env, "other-type-definition",
+ "36906:ipv4-address", NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+ break;
+ case ID_FQDN:
+ id_type = is_user ? "username" : "dns-name";
+ break;
+ case ID_RFC822_ADDR:
+ id_type = "email-address";
+ break;
+ case ID_IPV6_ADDR:
+ id_type = "other";
+ attr = axiom_attribute_create(this->env, "other-type-definition",
+ "36906:ipv6-address", NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+ break;
+ case ID_DER_ASN1_DN:
+ id_type = "distinguished-name";
+ break;
+ case ID_KEY_ID:
+ id_type = "other";
+ attr = axiom_attribute_create(this->env, "other-type-definition",
+ "36906:key-id", NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+ break;
+ default:
+ id_type = "other";
+ attr = axiom_attribute_create(this->env, "other-type-definition",
+ "36906:other", NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+ }
+ attr = axiom_attribute_create(this->env, "type", id_type, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+
+ return node;
+}
+
+/**
+ * Create an ip-address
+ */
+static axiom_node_t* create_ip_address(private_tnc_ifmap_soap_t *this,
+ host_t *host)
+{
+ axiom_element_t *el;
+ axiom_node_t *node;
+ axiom_attribute_t *attr;
+ char buf[BUF_LEN];
+
+ el = axiom_element_create(this->env, NULL, "ip-address", NULL, &node);
+
+ if (host->get_family(host) == AF_INET6)
+ {
+ chunk_t address;
+ int len, written, i;
+ char *pos;
+ bool first = TRUE;
+
+ /* output IPv6 address in canonical IF-MAP 2.0 format */
+ address = host->get_address(host);
+ pos = buf;
+ len = sizeof(buf);
+
+ for (i = 0; i < address.len; i = i + 2)
+ {
+ written = snprintf(pos, len, "%s%x", first ? "" : ":",
+ 256*address.ptr[i] + address.ptr[i+1]);
+ if (written < 0 || written > len)
+ {
+ break;
+ }
+ pos += written;
+ len -= written;
+ first = FALSE;
+ }
+ }
+ else
+ {
+ snprintf(buf, BUF_LEN, "%H", host);
+ }
+ attr = axiom_attribute_create(this->env, "value", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+
+ attr = axiom_attribute_create(this->env, "type",
+ host->get_family(host) == AF_INET ? "IPv4" : "IPv6", NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+
+ return node;
+}
+
+/**
+ * Create a device
+ */
+static axiom_node_t* create_device(private_tnc_ifmap_soap_t *this)
+{
+ axiom_element_t *el;
+ axiom_node_t *node, *node2, *node3;
+ axiom_text_t *text;
+
+ el = axiom_element_create(this->env, NULL, "device", NULL, &node);
+ el = axiom_element_create(this->env, NULL, "name", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+ text = axiom_text_create(this->env, node2, this->device_name, &node3);
+
+ return node;
+}
+
+/**
+ * Create metadata
+ */
+static axiom_node_t* create_metadata(private_tnc_ifmap_soap_t *this,
+ char *metadata)
+{
+ axiom_element_t *el;
+ axiom_node_t *node, *node2;
+ axiom_attribute_t *attr;
+ axiom_namespace_t *ns_meta;
+
+ el = axiom_element_create(this->env, NULL, "metadata", NULL, &node);
+ ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
+
+ el = axiom_element_create(this->env, NULL, metadata, ns_meta, &node2);
+ axiom_node_add_child(node, this->env, node2);
+ attr = axiom_attribute_create(this->env, "ifmap-cardinality", "singleValue",
+ NULL);
+ axiom_element_add_attribute(el, this->env, attr, node2);
+
+ return node;
+}
+
+/**
+ * Create capability metadata
+ */
+static axiom_node_t* create_capability(private_tnc_ifmap_soap_t *this,
+ identification_t *name)
+{
+ axiom_element_t *el;
+ axiom_node_t *node, *node2, *node3;
+ axiom_namespace_t *ns_meta;
+ axiom_attribute_t *attr;
+ axiom_text_t *text;
+ char buf[BUF_LEN];
+
+ ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
+ el = axiom_element_create(this->env, NULL, "capability", ns_meta, &node);
+ attr = axiom_attribute_create(this->env, "ifmap-cardinality", "multiValue",
+ NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+
+ el = axiom_element_create(this->env, NULL, "name", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+ snprintf(buf, BUF_LEN, "%Y", name);
+ text = axiom_text_create(this->env, node2, buf, &node3);
+
+ el = axiom_element_create(this->env, NULL, "administrative-domain", NULL, &node2);
+ axiom_node_add_child(node, this->env, node2);
+ text = axiom_text_create(this->env, node2, "strongswan", &node3);
+
+ return node;
+}
+
+/**
+ * Create enforcement-report metadata
+ */
+static axiom_node_t* create_enforcement_report(private_tnc_ifmap_soap_t *this,
+ char *action, char *reason)
+{
+ axiom_element_t *el;
+ axiom_node_t *node, *node2, *node3, *node4;
+ axiom_namespace_t *ns_meta;
+ axiom_attribute_t *attr;
+ axiom_text_t *text;
+
+ el = axiom_element_create(this->env, NULL, "metadata", NULL, &node);
+
+ ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
+ el = axiom_element_create(this->env, NULL, "enforcement-report", ns_meta,
+ &node2);
+ attr = axiom_attribute_create(this->env, "ifmap-cardinality",
+ "multiValue", NULL);
+ axiom_element_add_attribute(el, this->env, attr, node2);
+ axiom_node_add_child(node, this->env, node2);
+
+ el = axiom_element_create(this->env, NULL, "enforcement-action", NULL,
+ &node3);
+ axiom_node_add_child(node2, this->env, node3);
+ text = axiom_text_create(this->env, node3, action, &node4);
+
+ el = axiom_element_create(this->env, NULL, "enforcement-reason", NULL,
+ &node3);
+ axiom_node_add_child(node2, this->env, node3);
+ text = axiom_text_create(this->env, node3, reason, &node4);
+
+ return node;
+}
+
+/**
+ * Create delete filter
+ */
+static axiom_node_t* create_delete_filter(private_tnc_ifmap_soap_t *this,
+ char *metadata)
+{
+ axiom_element_t *el;
+ axiom_node_t *node;
+ axiom_attribute_t *attr;
+ char buf[BUF_LEN];
+
+ el = axiom_element_create(this->env, NULL, "delete", NULL, &node);
+
+ snprintf(buf, BUF_LEN, "meta:%s[@ifmap-publisher-id='%s']",
+ metadata, this->ifmap_publisher_id);
+ attr = axiom_attribute_create(this->env, "filter", buf, NULL);
+ axiom_element_add_attribute(el, this->env, attr, node);
+
+ return node;
+}
+
+/**
+ * Create a publish request
+ */
+static axiom_node_t* create_publish_request(private_tnc_ifmap_soap_t *this)
+{
+ axiom_element_t *el;
+ axiom_node_t *request;
+ axiom_namespace_t *ns, *ns_meta;
+ axiom_attribute_t *attr;
+
+ ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
+ el = axiom_element_create(this->env, NULL, "publish", ns, &request);
+ ns_meta = axiom_namespace_create(this->env, IFMAP_META_NS, "meta");
+ axiom_element_declare_namespace(el, this->env, request, ns_meta);
+ attr = axiom_attribute_create(this->env, "session-id", this->session_id,
+ NULL);
+ axiom_element_add_attribute(el, this->env, attr, request);
+
+ return request;
+}
+
+METHOD(tnc_ifmap_soap_t, publish_ike_sa, bool,
+ private_tnc_ifmap_soap_t *this, ike_sa_t *ike_sa, bool up)
+{
+ axiom_node_t *request, *node, *node2;
+ axiom_element_t *el;
+
+ enumerator_t *e1, *e2;
+ auth_rule_t type;
+ identification_t *id, *eap_id, *group;
+ host_t *host;
+ auth_cfg_t *auth;
+ u_int32_t ike_sa_id;
+ bool is_user = FALSE, first = TRUE;
+
+ /* extract relevant data from IKE_SA*/
+ ike_sa_id = ike_sa->get_unique_id(ike_sa);
+ id = ike_sa->get_other_id(ike_sa);
+ eap_id = ike_sa->get_other_eap_id(ike_sa);
+ host = ike_sa->get_other_host(ike_sa);
+
+ /* in the presence of an EAP Identity, treat it as a username */
+ if (!id->equals(id, eap_id))
+ {
+ is_user = TRUE;
+ id = eap_id;
+ }
+
+ /* build publish request */
+ request = create_publish_request(this);
+
+ /* delete any existing enforcement reports */
+ if (up)
+ {
+ node = create_delete_filter(this, "enforcement-report");
+ axiom_node_add_child(request, this->env, node);
+ axiom_node_add_child(node, this->env,
+ create_ip_address(this, host));
+ axiom_node_add_child(node, this->env,
+ create_device(this));
+ }
+
+ /**
+ * update or delete authenticated-as metadata
+ */
+ if (up)
+ {
+ el = axiom_element_create(this->env, NULL, "update", NULL, &node);
+ }
+ else
+ {
+ node = create_delete_filter(this, "authenticated-as");
+ }
+ axiom_node_add_child(request, this->env, node);
+
+ /* add access-request, identity and [if up] metadata */
+ axiom_node_add_child(node, this->env,
+ create_access_request(this, ike_sa_id));
+ axiom_node_add_child(node, this->env,
+ create_identity(this, id, is_user));
+ if (up)
+ {
+ axiom_node_add_child(node, this->env,
+ create_metadata(this, "authenticated-as"));
+ }
+
+ /**
+ * update or delete access-request-ip metadata
+ */
+ if (up)
+ {
+ el = axiom_element_create(this->env, NULL, "update", NULL, &node);
+ }
+ else
+ {
+ node = create_delete_filter(this, "access-request-ip");
+ }
+ axiom_node_add_child(request, this->env, node);
+
+ /* add access-request, ip-address and [if up] metadata */
+ axiom_node_add_child(node, this->env,
+ create_access_request(this, ike_sa_id));
+ axiom_node_add_child(node, this->env,
+ create_ip_address(this, host));
+ if (up)
+ {
+ axiom_node_add_child(node, this->env,
+ create_metadata(this, "access-request-ip"));
+ }
+
+ /**
+ * update or delete authenticated-by metadata
+ */
+ if (up)
+ {
+ el = axiom_element_create(this->env, NULL, "update", NULL, &node);
+ }
+ else
+ {
+ node = create_delete_filter(this, "authenticated-by");
+ }
+ axiom_node_add_child(request, this->env, node);
+
+ /* add access-request, device and [if up] metadata */
+ axiom_node_add_child(node, this->env,
+ create_access_request(this, ike_sa_id));
+ axiom_node_add_child(node, this->env,
+ create_device(this));
+ if (up)
+ {
+ axiom_node_add_child(node, this->env,
+ create_metadata(this, "authenticated-by"));
+ }
+
+ /**
+ * update or delete capability metadata
+ */
+ e1 = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE);
+ while (e1->enumerate(e1, &auth))
+ {
+ e2 = auth->create_enumerator(auth);
+ while (e2->enumerate(e2, &type, &group))
+ {
+ /* look for group memberships */
+ if (type == AUTH_RULE_GROUP)
+ {
+ if (first)
+ {
+ first = FALSE;
+
+ if (up)
+ {
+ el = axiom_element_create(this->env, NULL, "update",
+ NULL, &node);
+ }
+ else
+ {
+ node = create_delete_filter(this, "capability");
+ }
+ axiom_node_add_child(request, this->env, node);
+
+ /* add access-request */
+ axiom_node_add_child(node, this->env,
+ create_access_request(this, ike_sa_id));
+ if (!up)
+ {
+ break;
+ }
+ el = axiom_element_create(this->env, NULL, "metadata", NULL,
+ &node2);
+ axiom_node_add_child(node, this->env, node2);
+ }
+ axiom_node_add_child(node2, this->env,
+ create_capability(this, group));
+ }
+ if (!first && !up)
+ {
+ break;
+ }
+ }
+ e2->destroy(e2);
+ }
+ e1->destroy(e1);
+
+ /* send publish request and receive publishReceived */
+ return send_receive(this, "publish", request, "publishReceived", NULL);
+}
+
+METHOD(tnc_ifmap_soap_t, publish_device_ip, bool,
+ private_tnc_ifmap_soap_t *this, host_t *host)
+{
+ axiom_node_t *request, *node;
+ axiom_element_t *el;
+
+ /* build publish update request */
+ request = create_publish_request(this);
+ el = axiom_element_create(this->env, NULL, "update", NULL, &node);
+ axiom_node_add_child(request, this->env, node);
+
+ /* add device, ip-address and metadata */
+ axiom_node_add_child(node, this->env,
+ create_device(this));
+ axiom_node_add_child(node, this->env,
+ create_ip_address(this, host));
+ axiom_node_add_child(node, this->env,
+ create_metadata(this, "device-ip"));
+
+ /* send publish request and receive publishReceived */
+ return send_receive(this, "publish", request, "publishReceived", NULL);
+}
+
+METHOD(tnc_ifmap_soap_t, publish_enforcement_report, bool,
+ private_tnc_ifmap_soap_t *this, host_t *host, char *action, char *reason)
+{
+ axiom_node_t *request, *node;
+ axiom_element_t *el;
+
+ /* build publish update request */
+ request = create_publish_request(this);
+ el = axiom_element_create(this->env, NULL, "update", NULL, &node);
+ axiom_node_add_child(request, this->env, node);
+
+ /* add ip-address and metadata */
+ axiom_node_add_child(node, this->env,
+ create_ip_address(this, host));
+ axiom_node_add_child(node, this->env,
+ create_device(this));
+ axiom_node_add_child(node, this->env,
+ create_enforcement_report(this, action, reason));
+
+ /* send publish request and receive publishReceived */
+ return send_receive(this, "publish", request, "publishReceived", NULL);
+}
+
+METHOD(tnc_ifmap_soap_t, endSession, bool,
+ private_tnc_ifmap_soap_t *this)
+{
+ axiom_node_t *request;
+ axiom_element_t *el;
+ axiom_namespace_t *ns;
+ axiom_attribute_t *attr;
+
+ /* build endSession request */
+ ns = axiom_namespace_create(this->env, IFMAP_NS, "ifmap");
+ el = axiom_element_create(this->env, NULL, "endSession", ns, &request);
+ attr = axiom_attribute_create(this->env, "session-id", this->session_id, NULL);
+ axiom_element_add_attribute(el, this->env, attr, request);
+
+ /* send endSession request and receive end SessionResult */
+ return send_receive(this, "endSession", request, "endSessionResult", NULL);
+}
+
+METHOD(tnc_ifmap_soap_t, destroy, void,
+ private_tnc_ifmap_soap_t *this)
+{
+ if (this->session_id)
+ {
+ endSession(this);
+ free(this->session_id);
+ free(this->ifmap_publisher_id);
+ free(this->device_name);
+ }
+ if (this->svc_client)
+ {
+ axis2_svc_client_free(this->svc_client, this->env);
+ }
+ if (this->env)
+ {
+ axutil_env_free(this->env);
+ }
+ free(this);
+}
+
+static bool axis2c_init(private_tnc_ifmap_soap_t *this)
+{
+ axis2_char_t *server, *server_cert, *key_file, *client_home;
+ axis2_char_t *ssl_passphrase, *username, *password;
+ axis2_endpoint_ref_t* endpoint_ref = NULL;
+ axis2_options_t *options = NULL;
+ axis2_transport_in_desc_t *transport_in;
+ axis2_transport_out_desc_t *transport_out;
+ axis2_transport_sender_t *transport_sender;
+ axutil_property_t* property;
+
+ /* Getting configuration parameters from strongswan.conf */
+ client_home = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.client_home",
+ AXIS2_GETENV("AXIS2C_HOME"));
+ server = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.server", IFMAP_SERVER);
+ server_cert = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.server_cert", NULL);
+ key_file = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.key_file", NULL);
+ ssl_passphrase = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.ssl_passphrase", NULL);
+ username = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.username", NULL);
+ password = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-ifmap.password", NULL);
+
+ if (!server_cert)
+ {
+ DBG1(DBG_TNC, "MAP server certificate not defined");
+ return FALSE;
+ }
+
+ if (!key_file && (!username || !password))
+ {
+ DBG1(DBG_TNC, "MAP client keyfile or %s%s%s not defined",
+ (!username) ? "username" : "",
+ (!username && ! password) ? " and " : "",
+ (!password) ? "password" : "");
+ return FALSE;
+ }
+
+ /* Create Axis2/C environment and options */
+ this->env = axutil_env_create_all(IFMAP_LOGFILE, AXIS2_LOG_LEVEL_TRACE);
+ options = axis2_options_create(this->env);
+
+ /* Set path to the MAP server certificate */
+ property =axutil_property_create_with_args(this->env, 0, 0, 0,
+ server_cert);
+ axis2_options_set_property(options, this->env,
+ AXIS2_SSL_SERVER_CERT, property);
+
+ if (key_file)
+ {
+ /* Set path to the MAP client certificate */
+ property =axutil_property_create_with_args(this->env, 0, 0, 0,
+ key_file);
+ axis2_options_set_property(options, this->env,
+ AXIS2_SSL_KEY_FILE, property);
+ if (ssl_passphrase)
+ {
+ /* Provide SSL passphrase */
+ property =axutil_property_create_with_args(this->env, 0, 0, 0,
+ ssl_passphrase);
+ axis2_options_set_property(options, this->env,
+ AXIS2_SSL_PASSPHRASE, property);
+ }
+ }
+ else
+ {
+ /* Set up HTTP Basic MAP client authentication */
+ axis2_options_set_http_auth_info(options, this->env,
+ username, password, "Basic");
+ }
+
+ /* Define the MAP server as the to endpoint reference */
+ endpoint_ref = axis2_endpoint_ref_create(this->env, server);
+ axis2_options_set_to(options, this->env, endpoint_ref);
+
+ /* Set up https transport */
+ transport_in = axis2_transport_in_desc_create(this->env,
+ AXIS2_TRANSPORT_ENUM_HTTPS);
+ transport_out = axis2_transport_out_desc_create(this->env,
+ AXIS2_TRANSPORT_ENUM_HTTPS);
+ transport_sender = axis2_http_transport_sender_create(this->env);
+ axis2_transport_out_desc_set_sender(transport_out, this->env,
+ transport_sender);
+ axis2_options_set_transport_in(options, this->env, transport_in);
+ axis2_options_set_transport_out(options, this->env, transport_out);
+
+ /* Create the axis2 service client */
+ this->svc_client = axis2_svc_client_create(this->env, client_home);
+ if (!this->svc_client)
+ {
+ DBG1(DBG_TNC, "could not create axis2 service client");
+ AXIS2_LOG_ERROR(this->env->log, AXIS2_LOG_SI,
+ "Stub invoke FAILED: Error code: %d :: %s",
+ this->env->error->error_number,
+ AXIS2_ERROR_GET_MESSAGE(this->env->error));
+ destroy(this);
+ return FALSE;
+ }
+
+ axis2_svc_client_set_options(this->svc_client, this->env, options);
+ DBG1(DBG_TNC, "connecting as MAP client '%s' to MAP server at '%s'",
+ username, server);
+
+ return TRUE;
+}
+
+/**
+ * See header
+ */
+tnc_ifmap_soap_t *tnc_ifmap_soap_create()
+{
+ private_tnc_ifmap_soap_t *this;
+
+ INIT(this,
+ .public = {
+ .newSession = _newSession,
+ .purgePublisher = _purgePublisher,
+ .publish_ike_sa = _publish_ike_sa,
+ .publish_device_ip = _publish_device_ip,
+ .publish_enforcement_report = _publish_enforcement_report,
+ .endSession = _endSession,
+ .destroy = _destroy,
+ },
+ );
+
+ if (!axis2c_init(this))
+ {
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h
new file mode 100644
index 000000000..4bf421e33
--- /dev/null
+++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 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_ifmap_soap tnc_ifmap_soap
+ * @{ @ingroup tnc_ifmap
+ */
+
+#ifndef TNC_IFMAP_SOAP_H_
+#define TNC_IFMAP_SOAP_H_
+
+#include <library.h>
+#include <utils/host.h>
+#include <sa/ike_sa.h>
+
+typedef struct tnc_ifmap_soap_t tnc_ifmap_soap_t;
+
+/**
+ * Implements the TNC IF-MAP 2.0 SOAP Binding
+ */
+struct tnc_ifmap_soap_t {
+
+ /**
+ * Creates a new IF-MAP session
+ *
+ * @return TRUE if command was successful
+ */
+ bool (*newSession)(tnc_ifmap_soap_t *this);
+
+ /**
+ * Purges all metadata published by this publisher
+ *
+ * @return TRUE if command was successful
+ */
+ bool (*purgePublisher)(tnc_ifmap_soap_t *this);
+
+ /**
+ * Publish metadata about established/deleted IKE_SAs
+ *
+ * @param ike_sa IKE_SA for which metadate is published
+ * @param up TRUE if IKE_SEA is up, FALSE if down
+ * @return TRUE if command was successful
+ */
+ bool (*publish_ike_sa)(tnc_ifmap_soap_t *this, ike_sa_t *ike_sa, bool up);
+
+ /**
+ * Publish PEP device-ip metadata
+ *
+ * @param host IP address of local endpoint
+ * @return TRUE if command was successful
+ */
+ bool (*publish_device_ip)(tnc_ifmap_soap_t *this, host_t *host);
+
+ /**
+ * Publish enforcement-report metadata
+ *
+ * @param host Host to be enforced
+ * @param action Enforcement action ("block" or "quarantine")
+ * @param reason Enforcement reason
+ * @return TRUE if command was successful
+ */
+ bool (*publish_enforcement_report)(tnc_ifmap_soap_t *this, host_t *host,
+ char *action, char *reason);
+
+ /**
+ * Ends an IF-MAP session
+ *
+ * @return TRUE if command was successful
+ */
+ bool (*endSession)(tnc_ifmap_soap_t *this);
+
+ /**
+ * Destroy a tnc_ifmap_soap_t.
+ */
+ void (*destroy)(tnc_ifmap_soap_t *this);
+};
+
+/**
+ * Create a tnc_ifmap_soap instance.
+ */
+tnc_ifmap_soap_t *tnc_ifmap_soap_create();
+
+#endif /** TNC_IFMAP_SOAP_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_imc/Makefile.am b/src/libcharon/plugins/tnc_imc/Makefile.am
index 2c551813e..fc1979525 100644
--- a/src/libcharon/plugins/tnc_imc/Makefile.am
+++ b/src/libcharon/plugins/tnc_imc/Makefile.am
@@ -1,6 +1,8 @@
-INCLUDES = -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/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@@ -8,6 +10,9 @@ if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-tnc-imc.la
else
plugin_LTLIBRARIES = libstrongswan-tnc-imc.la
+libstrongswan_tnc_imc_la_LIBADD = \
+ $(top_builddir)/src/libtncif/libtncif.la \
+ $(top_builddir)/src/libtnccs/libtnccs.la
endif
libstrongswan_tnc_imc_la_SOURCES = \
diff --git a/src/libcharon/plugins/tnc_imc/Makefile.in b/src/libcharon/plugins/tnc_imc/Makefile.in
index c2bc35dc5..550c0516c 100644
--- a/src/libcharon/plugins/tnc_imc/Makefile.in
+++ b/src/libcharon/plugins/tnc_imc/Makefile.in
@@ -74,7 +74,9 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_tnc_imc_la_LIBADD =
+@MONOLITHIC_FALSE@libstrongswan_tnc_imc_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
am_libstrongswan_tnc_imc_la_OBJECTS = tnc_imc_plugin.lo tnc_imc.lo \
tnc_imc_manager.lo tnc_imc_bind_function.lo
libstrongswan_tnc_imc_la_OBJECTS = \
@@ -194,6 +196,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +207,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +224,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +274,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -276,12 +285,18 @@ 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
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imc.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imc.la
+@MONOLITHIC_FALSE@libstrongswan_tnc_imc_la_LIBADD = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+
libstrongswan_tnc_imc_la_SOURCES = \
tnc_imc_plugin.h tnc_imc_plugin.c tnc_imc.h tnc_imc.c \
tnc_imc_manager.h tnc_imc_manager.c tnc_imc_bind_function.c
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc.c b/src/libcharon/plugins/tnc_imc/tnc_imc.c
index d7fc2c65d..a1f2d770f 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Mike McCauley
- * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010-2011 Andreas Steffen,
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -17,8 +18,11 @@
#include <dlfcn.h>
+#include <tncif_pa_subtypes.h>
+
#include <debug.h>
#include <library.h>
+#include <utils/linked_list.h>
#include <threading/mutex.h>
typedef struct private_tnc_imc_t private_tnc_imc_t;
@@ -54,9 +58,19 @@ struct private_tnc_imc_t {
TNC_IMCID id;
/**
- * List of message types supported by IMC
+ * list of additional IMC IDs
*/
- TNC_MessageTypeList supported_types;
+ linked_list_t *additional_ids;
+
+ /**
+ * List of message types supported by IMC - Vendor ID part
+ */
+ TNC_VendorIDList supported_vids;
+
+ /**
+ * List of message types supported by IMC - Subtype part
+ */
+ TNC_MessageSubtypeList supported_subtypes;
/**
* Number of supported message types
@@ -81,6 +95,54 @@ METHOD(imc_t, get_id, TNC_IMCID,
return this->id;
}
+METHOD(imc_t, add_id, void,
+ private_tnc_imc_t *this, TNC_IMCID id)
+{
+ void *pointer;
+
+ /* store the scalar value in the pointer */
+ pointer = (void*)id;
+ this->additional_ids->insert_last(this->additional_ids, pointer);
+}
+
+METHOD(imc_t, has_id, bool,
+ private_tnc_imc_t *this, TNC_IMCID id)
+{
+ enumerator_t *enumerator;
+ TNC_IMCID additional_id;
+ void *pointer;
+ bool found = FALSE;
+
+ /* check primary IMC ID */
+ if (id == this->id)
+ {
+ return TRUE;
+ }
+
+ /* return if there are no additional IMC IDs */
+ if (this->additional_ids->get_count(this->additional_ids) == 0)
+ {
+ return FALSE;
+ }
+
+ /* check additional IMC IDs */
+ enumerator = this->additional_ids->create_enumerator(this->additional_ids);
+ while (enumerator->enumerate(enumerator, &pointer))
+ {
+ /* interpret pointer as scalar value */
+ additional_id = (TNC_UInt32)pointer;
+
+ if (id == additional_id)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
METHOD(imc_t, get_name, char*,
private_tnc_imc_t *this)
{
@@ -91,66 +153,150 @@ METHOD(imc_t, set_message_types, void,
private_tnc_imc_t *this, TNC_MessageTypeList supported_types,
TNC_UInt32 type_count)
{
- char buf[512];
+ char buf[BUF_LEN];
char *pos = buf;
int len = sizeof(buf);
- int written;
+ int i, written;
+ size_t size;
+ TNC_VendorID vid;
+ TNC_MessageSubtype subtype;
+ enum_name_t *pa_subtype_names;
/* lock the imc_t instance */
this->mutex->lock(this->mutex);
- /* Free an existing MessageType list */
- free(this->supported_types);
- this->supported_types = NULL;
+ /* Free existing VendorID and MessageSubtype lists */
+ free(this->supported_vids);
+ this->supported_vids = NULL;
+ free(this->supported_subtypes);
+ this->supported_subtypes = NULL;
/* Store the new MessageType list */
this->type_count = type_count;
if (type_count && supported_types)
{
- size_t size = type_count * sizeof(TNC_MessageType);
- int i;
+ size = type_count * sizeof(TNC_VendorID);
+ this->supported_vids = malloc(size);
+ size = type_count * sizeof(TNC_MessageSubtype);
+ this->supported_subtypes = malloc(size);
for (i = 0; i < type_count; i++)
{
- written = snprintf(pos, len, " 0x%08x", supported_types[i]);
+ vid = (supported_types[i] >> 8) & TNC_VENDORID_ANY;
+ subtype = supported_types[i] & TNC_SUBTYPE_ANY;
+
+ pa_subtype_names = get_pa_subtype_names(vid);
+ if (pa_subtype_names)
+ {
+ written = snprintf(pos, len," '%N/%N' 0x%06x/0x%02x",
+ pen_names, vid, pa_subtype_names, subtype,
+ vid, subtype);
+ }
+ else
+ {
+ written = snprintf(pos, len," '%N' 0x%06x/0x%02x",
+ pen_names, vid, vid, subtype);
+ }
if (written >= len)
{
break;
}
pos += written;
len -= written;
+
+ this->supported_vids[i] = vid;
+ this->supported_subtypes[i] = subtype;
}
- this->supported_types = malloc(size);
- memcpy(this->supported_types, supported_types, size);
}
*pos = '\0';
- DBG2(DBG_TNC, "IMC %u supports %u message types:%s",
- this->id, type_count, buf);
+ DBG2(DBG_TNC, "IMC %u supports %u message type%s:%s",
+ this->id, type_count, (type_count == 1) ? "":"s", buf);
+
+ /* unlock the imc_t instance */
+ this->mutex->unlock(this->mutex);
+}
+
+METHOD(imc_t, set_message_types_long, void,
+ private_tnc_imc_t *this, TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes, TNC_UInt32 type_count)
+{
+ char buf[BUF_LEN];
+ char *pos = buf;
+ int len = sizeof(buf);
+ int i, written;
+ size_t size;
+ TNC_VendorID vid;
+ TNC_MessageSubtype subtype;
+ enum_name_t *pa_subtype_names;
/* lock the imc_t instance */
+ this->mutex->lock(this->mutex);
+
+ /* Free existing VendorID and MessageSubtype lists */
+ free(this->supported_vids);
+ this->supported_vids = NULL;
+ free(this->supported_subtypes);
+ this->supported_subtypes = NULL;
+
+ /* Store the new MessageType list */
+ this->type_count = type_count;
+ if (type_count && supported_vids && supported_subtypes)
+ {
+ size = type_count * sizeof(TNC_VendorID);
+ this->supported_vids = malloc(size);
+ memcpy(this->supported_vids, supported_vids, size);
+ size = type_count * sizeof(TNC_MessageSubtype);
+ this->supported_subtypes = malloc(size);
+ memcpy(this->supported_subtypes, supported_subtypes, size);
+
+ for (i = 0; i < type_count; i++)
+ {
+ vid = supported_vids[i];
+ subtype = supported_subtypes[i];
+
+ pa_subtype_names = get_pa_subtype_names(vid);
+ if (pa_subtype_names)
+ {
+ written = snprintf(pos, len," '%N/%N' 0x%06x/0x%08x",
+ pen_names, vid, pa_subtype_names, subtype,
+ vid, subtype);
+ }
+ else
+ {
+ written = snprintf(pos, len," '%N' 0x%06x/0x%08x",
+ pen_names, vid, vid, subtype);
+ }
+ if (written >= len)
+ {
+ break;
+ }
+ pos += written;
+ len -= written;
+ }
+ }
+ *pos = '\0';
+ DBG2(DBG_TNC, "IMC %u supports %u message type%s:%s",
+ this->id, type_count, (type_count == 1) ? "":"s", buf);
+
+ /* unlock the imc_t instance */
this->mutex->unlock(this->mutex);
}
METHOD(imc_t, type_supported, bool,
- private_tnc_imc_t *this, TNC_MessageType message_type)
+ private_tnc_imc_t *this, TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype)
{
- TNC_VendorID msg_vid, vid;
- TNC_MessageSubtype msg_subtype, subtype;
+ TNC_VendorID vid;
+ TNC_MessageSubtype subtype;
int i;
- msg_vid = (message_type >> 8) & TNC_VENDORID_ANY;
- msg_subtype = message_type & TNC_SUBTYPE_ANY;
-
for (i = 0; i < this->type_count; i++)
{
- vid = (this->supported_types[i] >> 8) & TNC_VENDORID_ANY;
- subtype = this->supported_types[i] & TNC_SUBTYPE_ANY;
-
- if (this->supported_types[i] == message_type
- || (subtype == TNC_SUBTYPE_ANY
- && (msg_vid == vid || vid == TNC_VENDORID_ANY))
- || (vid == TNC_VENDORID_ANY
- && (msg_subtype == subtype || subtype == TNC_SUBTYPE_ANY)))
+ vid = this->supported_vids[i];
+ subtype = this->supported_subtypes[i];
+
+ if ((vid == TNC_VENDORID_ANY && subtype == TNC_SUBTYPE_ANY) ||
+ (vid == msg_vid && (subtype == TNC_SUBTYPE_ANY ||
+ subtype == msg_subtype)))
{
return TRUE;
}
@@ -163,7 +309,9 @@ METHOD(imc_t, destroy, void,
{
dlclose(this->handle);
this->mutex->destroy(this->mutex);
- free(this->supported_types);
+ this->additional_ids->destroy(this->additional_ids);
+ free(this->supported_vids);
+ free(this->supported_subtypes);
free(this->name);
free(this->path);
free(this);
@@ -180,13 +328,17 @@ imc_t* tnc_imc_create(char *name, char *path)
.public = {
.set_id = _set_id,
.get_id = _get_id,
+ .add_id = _add_id,
+ .has_id = _has_id,
.get_name = _get_name,
.set_message_types = _set_message_types,
+ .set_message_types_long = _set_message_types_long,
.type_supported = _type_supported,
.destroy = _destroy,
},
.name = name,
.path = path,
+ .additional_ids = linked_list_create(),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
);
@@ -220,6 +372,8 @@ imc_t* tnc_imc_create(char *name, char *path)
}
this->public.receive_message =
dlsym(this->handle, "TNC_IMC_ReceiveMessage");
+ this->public.receive_message_long =
+ dlsym(this->handle, "TNC_IMC_ReceiveMessageLong");
this->public.batch_ending =
dlsym(this->handle, "TNC_IMC_BatchEnding");
this->public.terminate =
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c b/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
index 25a6a1cc4..90a607ccc 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_bind_function.c
@@ -13,12 +13,11 @@
* for more details.
*/
-#include "tnc_imc.h"
+#include <tnc/tnc.h>
+#include <tnc/imc/imc_manager.h>
+#include <tnc/tnccs/tnccs_manager.h>
#include <debug.h>
-#include <daemon.h>
-
-#define TNC_IMVID_ANY 0xffff
/**
* Called by the IMC to inform a TNCC about the set of message types the IMC
@@ -28,14 +27,33 @@ TNC_Result TNC_TNCC_ReportMessageTypes(TNC_IMCID imc_id,
TNC_MessageTypeList supported_types,
TNC_UInt32 type_count)
{
- if (!charon->imcs->is_registered(charon->imcs, imc_id))
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
{
DBG1(DBG_TNC, "ignoring ReportMessageTypes() from unregistered IMC %u",
imc_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->imcs->set_message_types(charon->imcs, imc_id,
- supported_types, type_count);
+ return tnc->imcs->set_message_types(tnc->imcs, imc_id, supported_types,
+ type_count);
+}
+
+/**
+ * Called by the IMC to inform a TNCC about the set of message types the IMC
+ * is able to receive. This function supports long message types.
+ */
+TNC_Result TNC_TNCC_ReportMessageTypesLong(TNC_IMCID imc_id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count)
+{
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
+ {
+ DBG1(DBG_TNC, "ignoring ReportMessageTypesLong() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return tnc->imcs->set_message_types_long(tnc->imcs, imc_id, supported_vids,
+ supported_subtypes, type_count);
}
/**
@@ -45,14 +63,14 @@ TNC_Result TNC_TNCC_RequestHandshakeRetry(TNC_IMCID imc_id,
TNC_ConnectionID connection_id,
TNC_RetryReason reason)
{
- if (!charon->imcs->is_registered(charon->imcs, imc_id))
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
{
DBG1(DBG_TNC, "ignoring RequestHandshakeRetry() from unregistered IMC %u",
imc_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->request_handshake_retry(charon->tnccs, TRUE, imc_id,
- connection_id, reason);
+ return tnc->tnccs->request_handshake_retry(tnc->tnccs, TRUE, imc_id,
+ connection_id, reason);
}
/**
@@ -64,14 +82,97 @@ TNC_Result TNC_TNCC_SendMessage(TNC_IMCID imc_id,
TNC_UInt32 msg_len,
TNC_MessageType msg_type)
{
- if (!charon->imcs->is_registered(charon->imcs, imc_id))
+ TNC_VendorID msg_vid;
+ TNC_MessageSubtype msg_subtype;
+
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
+ {
+ DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY;
+ msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+
+ return tnc->tnccs->send_message(tnc->tnccs, imc_id, TNC_IMVID_ANY,
+ connection_id, 0, msg, msg_len, msg_vid, msg_subtype);
+}
+
+/**
+ * Called by the IMC when an IMC-IMV message is to be sent over IF-TNCCS 2.0
+ */
+TNC_Result TNC_TNCC_SendMessageLong(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 imv_id)
+{
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
{
DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMC %u",
imc_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->send_message(charon->tnccs, imc_id, TNC_IMVID_ANY,
- connection_id, msg, msg_len, msg_type);
+ return tnc->tnccs->send_message(tnc->tnccs, imc_id, imv_id, connection_id,
+ msg_flags, msg, msg_len, msg_vid, msg_subtype);
+}
+
+/**
+ * Called by the IMC to get the value of an attribute associated with a
+ * connection or with the TNCC as a whole.
+ */
+TNC_Result TNC_TNCC_GetAttribute(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer,
+ TNC_UInt32 *out_value_len)
+{
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
+ {
+ DBG1(DBG_TNC, "ignoring GetAttribute() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return tnc->tnccs->get_attribute(tnc->tnccs, TRUE, imc_id, connection_id,
+ attribute_id, buffer_len, buffer, out_value_len);
+}
+
+/**
+ * Called by the IMC to set the value of an attribute associated with a
+ * connection or with the TNCC as a whole.
+ */
+TNC_Result TNC_TNCC_SetAttribute(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer)
+{
+ if (!tnc->imcs->is_registered(tnc->imcs, imc_id))
+ {
+ DBG1(DBG_TNC, "ignoring SetAttribute() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return tnc->tnccs->set_attribute(tnc->tnccs, TRUE, imc_id, connection_id,
+ attribute_id, buffer_len, buffer);
+}
+
+/**
+ * Called by the IMC when it wants to reserve an additional IMC ID for itself
+ */
+TNC_Result TNC_TNCC_ReserveAdditionalIMCID(TNC_IMCID imc_id, TNC_UInt32 *new_id)
+{
+ if (tnc->imcs->reserve_id(tnc->imcs, imc_id, new_id))
+ {
+ return TNC_RESULT_SUCCESS;
+ }
+ DBG1(DBG_TNC, "ignoring ReserveAdditionalIMCID() from unregistered IMC %u",
+ imc_id);
+ return TNC_RESULT_INVALID_PARAMETER;
}
/**
@@ -85,6 +186,10 @@ TNC_Result TNC_TNCC_BindFunction(TNC_IMCID id,
{
*function_pointer = (void*)TNC_TNCC_ReportMessageTypes;
}
+ else if (streq(function_name, "TNC_TNCC_ReportMessageTypesLong"))
+ {
+ *function_pointer = (void*)TNC_TNCC_ReportMessageTypesLong;
+ }
else if (streq(function_name, "TNC_TNCC_RequestHandshakeRetry"))
{
*function_pointer = (void*)TNC_TNCC_RequestHandshakeRetry;
@@ -93,6 +198,22 @@ TNC_Result TNC_TNCC_BindFunction(TNC_IMCID id,
{
*function_pointer = (void*)TNC_TNCC_SendMessage;
}
+ else if (streq(function_name, "TNC_TNCC_SendMessageLong"))
+ {
+ *function_pointer = (void*)TNC_TNCC_SendMessageLong;
+ }
+ else if (streq(function_name, "TNC_TNCC_GetAttribute"))
+ {
+ *function_pointer = (void*)TNC_TNCC_GetAttribute;
+ }
+ else if (streq(function_name, "TNC_TNCC_SetAttribute"))
+ {
+ *function_pointer = (void*)TNC_TNCC_SetAttribute;
+ }
+ else if (streq(function_name, "TNC_TNCC_ReserveAdditionalIMCID"))
+ {
+ *function_pointer = (void*)TNC_TNCC_ReserveAdditionalIMCID;
+ }
else
{
return TNC_RESULT_INVALID_PARAMETER;
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
index ccf6aea67..e101cf974 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Mike McCauley
- * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010-2011 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
@@ -14,13 +15,12 @@
*/
#include "tnc_imc_manager.h"
+#include "tnc_imc.h"
-#include <tnc/imc/imc_manager.h>
-#include <tnc/tncifimc.h>
+#include <tncifimc.h>
-#include <debug.h>
-#include <library.h>
#include <utils/linked_list.h>
+#include <debug.h>
typedef struct private_tnc_imc_manager_t private_tnc_imc_manager_t;
@@ -94,6 +94,33 @@ METHOD(imc_manager_t, remove_, imc_t*,
return removed_imc;
}
+METHOD(imc_manager_t, load, bool,
+ private_tnc_imc_manager_t *this, char *name, char *path)
+{
+ imc_t *imc;
+
+ imc = tnc_imc_create(name, path);
+ if (!imc)
+ {
+ free(name);
+ free(path);
+ return FALSE;
+ }
+ if (!add(this, imc))
+ {
+ if (imc->terminate &&
+ imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
+ imc->get_name(imc));
+ }
+ imc->destroy(imc);
+ return FALSE;
+ }
+ DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc), name, path);
+ return TRUE;
+}
+
METHOD(imc_manager_t, is_registered, bool,
private_tnc_imc_manager_t *this, TNC_IMCID id)
{
@@ -104,9 +131,34 @@ METHOD(imc_manager_t, is_registered, bool,
enumerator = this->imcs->create_enumerator(this->imcs);
while (enumerator->enumerate(enumerator, &imc))
{
- if (id == imc->get_id(imc))
+ if (imc->has_id(imc, id))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
+METHOD(imc_manager_t, reserve_id, bool,
+ private_tnc_imc_manager_t *this, TNC_IMCID id, TNC_UInt32 *new_id)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+ bool found = FALSE;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ if (imc->get_id(imc))
{
found = TRUE;
+ *new_id = this->next_imc_id++;
+ imc->add_id(imc, *new_id);
+ DBG2(DBG_TNC, "additional ID %u reserved for IMC with primary ID %u",
+ *new_id, id);
break;
}
}
@@ -177,30 +229,77 @@ METHOD(imc_manager_t, set_message_types, TNC_Result,
return result;
}
+METHOD(imc_manager_t, set_message_types_long, TNC_Result,
+ private_tnc_imc_manager_t *this, TNC_IMCID id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+ TNC_Result result = TNC_RESULT_FATAL;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ if (id == imc->get_id(imc))
+ {
+ imc->set_message_types_long(imc, supported_vids, supported_subtypes,
+ type_count);
+ result = TNC_RESULT_SUCCESS;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return result;
+}
+
METHOD(imc_manager_t, receive_message, void,
private_tnc_imc_manager_t *this, TNC_ConnectionID connection_id,
- TNC_BufferReference message,
- TNC_UInt32 message_len,
- TNC_MessageType message_type)
+ bool excl,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imv_id,
+ TNC_UInt32 dst_imc_id)
{
bool type_supported = FALSE;
+ TNC_MessageType msg_type;
+ TNC_UInt32 msg_flags;
enumerator_t *enumerator;
imc_t *imc;
enumerator = this->imcs->create_enumerator(this->imcs);
while (enumerator->enumerate(enumerator, &imc))
{
- if (imc->receive_message && imc->type_supported(imc, message_type))
+ if (imc->type_supported(imc, msg_vid, msg_subtype) &&
+ (!excl || (excl && imc->has_id(imc, dst_imc_id)) ))
{
- type_supported = TRUE;
- imc->receive_message(imc->get_id(imc), connection_id,
- message, message_len, message_type);
+ if (imc->receive_message_long && src_imv_id)
+ {
+ type_supported = TRUE;
+ msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0;
+ imc->receive_message_long(imc->get_id(imc), connection_id,
+ msg_flags, msg, msg_len, msg_vid, msg_subtype,
+ src_imv_id, dst_imc_id);
+
+ }
+ else if (imc->receive_message && msg_vid <= TNC_VENDORID_ANY &&
+ msg_subtype <= TNC_SUBTYPE_ANY)
+ {
+ type_supported = TRUE;
+ msg_type = (msg_vid << 8) | msg_subtype;
+ imc->receive_message(imc->get_id(imc), connection_id,
+ msg, msg_len, msg_type);
+ }
}
}
enumerator->destroy(enumerator);
if (!type_supported)
{
- DBG2(DBG_TNC, "message type 0x%08x not supported by any IMC", message_type);
+ DBG2(DBG_TNC, "message type 0x%06x/0x%08x not supported by any IMC",
+ msg_vid, msg_subtype);
}
}
@@ -251,11 +350,14 @@ imc_manager_t* tnc_imc_manager_create(void)
.public = {
.add = _add,
.remove = _remove_, /* avoid name conflict with stdio.h */
+ .load = _load,
.is_registered = _is_registered,
+ .reserve_id = _reserve_id,
.get_preferred_language = _get_preferred_language,
.notify_connection_change = _notify_connection_change,
.begin_handshake = _begin_handshake,
.set_message_types = _set_message_types,
+ .set_message_types_long = _set_message_types_long,
.receive_message = _receive_message,
.batch_ending = _batch_ending,
.destroy = _destroy,
diff --git a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
index bc13b8735..a25b1843c 100644
--- a/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
+++ b/src/libcharon/plugins/tnc_imc/tnc_imc_plugin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010-2011 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,180 +15,63 @@
#include "tnc_imc_plugin.h"
#include "tnc_imc_manager.h"
-#include "tnc_imc.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
+#include <tnc/tnc.h>
-#include <daemon.h>
-#include <utils/lexparser.h>
+typedef struct private_tnc_imc_plugin_t private_tnc_imc_plugin_t;
/**
- * load IMCs from a configuration file
+ * Private data of a tnc_imc_plugin_t object.
*/
-static bool load_imcs(char *filename)
-{
- int fd, line_nr = 0;
- chunk_t src, line;
- struct stat sb;
- void *addr;
-
- DBG1(DBG_TNC, "loading IMCs from '%s'", filename);
- fd = open(filename, O_RDONLY);
- if (fd == -1)
- {
- DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
- strerror(errno));
- return FALSE;
- }
- if (fstat(fd, &sb) == -1)
- {
- DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
- strerror(errno));
- close(fd);
- return FALSE;
- }
- 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", filename, strerror(errno));
- close(fd);
- return FALSE;
- }
- src = chunk_create(addr, sb.st_size);
-
- while (fetchline(&src, &line))
- {
- char *name, *path;
- chunk_t token;
- imc_t *imc;
-
- line_nr++;
-
- /* skip comments or empty lines */
- if (*line.ptr == '#' || !eat_whitespace(&line))
- {
- continue;
- }
-
- /* determine keyword */
- if (!extract_token(&token, ' ', &line))
- {
- DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
- line_nr);
- return FALSE;
- }
-
- /* only interested in IMCs */
- if (!match("IMC", &token))
- {
- continue;
- }
-
- /* advance to the IMC name and extract it */
- if (!extract_token(&token, '"', &line) ||
- !extract_token(&token, '"', &line))
- {
- DBG1(DBG_TNC, "line %d: IMC name must be set in double quotes",
- line_nr);
- return FALSE;
- }
+struct private_tnc_imc_plugin_t {
- /* copy the IMC name */
- name = malloc(token.len + 1);
- memcpy(name, token.ptr, token.len);
- name[token.len] = '\0';
-
- /* advance to the IMC path and extract it */
- if (!eat_whitespace(&line))
- {
- DBG1(DBG_TNC, "line %d: IMC path is missing", line_nr);
- free(name);
- return FALSE;
- }
- if (!extract_token(&token, ' ', &line))
- {
- token = line;
- }
-
- /* copy the IMC path */
- path = malloc(token.len + 1);
- memcpy(path, token.ptr, token.len);
- path[token.len] = '\0';
-
- /* load and register IMC instance */
- imc = tnc_imc_create(name, path);
- if (!imc)
- {
- free(name);
- free(path);
- return FALSE;
- }
- if (!charon->imcs->add(charon->imcs, imc))
- {
- if (imc->terminate &&
- imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
- {
- DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
- imc->get_name(imc));
- }
- imc->destroy(imc);
- return FALSE;
- }
- DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc),
- name, path);
- }
- munmap(addr, sb.st_size);
- close(fd);
- return TRUE;
-}
+ /**
+ * Public interface.
+ */
+ tnc_imc_plugin_t public;
+};
METHOD(plugin_t, get_name, char*,
- tnc_imc_plugin_t *this)
+ private_tnc_imc_plugin_t *this)
{
return "tnc-imc";
}
+METHOD(plugin_t, get_features, int,
+ private_tnc_imc_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(tnc_manager_register, tnc_imc_manager_create),
+ PLUGIN_PROVIDE(CUSTOM, "imc-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
- tnc_imc_plugin_t *this)
+ private_tnc_imc_plugin_t *this)
{
- charon->imcs->destroy(charon->imcs);
free(this);
}
/*
* see header file
*/
-plugin_t *tnc_imc_plugin_create()
+plugin_t *tnc_imc_plugin_create(void)
{
- char *tnc_config;
- tnc_imc_plugin_t *this;
+ private_tnc_imc_plugin_t *this;
INIT(this,
- .plugin = {
- .get_name = _get_name,
- .reload = (void*)return_false,
- .destroy = _destroy,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
},
);
- /* Create IMC manager */
- charon->imcs = tnc_imc_manager_create();
-
- /* Load IMCs and abort if not all instances initalize successfully */
- tnc_config = lib->settings->get_str(lib->settings,
- "charon.plugins.tnc-imc.tnc_config", "/etc/tnc_config");
- if (!load_imcs(tnc_config))
- {
- charon->imcs->destroy(charon->imcs);
- charon->imcs = NULL;
- free(this);
- return NULL;
- }
- return &this->plugin;
+ return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/tnc_imv/Makefile.am b/src/libcharon/plugins/tnc_imv/Makefile.am
index 3ba283bb7..eca3b377b 100644
--- a/src/libcharon/plugins/tnc_imv/Makefile.am
+++ b/src/libcharon/plugins/tnc_imv/Makefile.am
@@ -1,6 +1,10 @@
-INCLUDES = -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 \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@@ -8,6 +12,9 @@ if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-tnc-imv.la
else
plugin_LTLIBRARIES = libstrongswan-tnc-imv.la
+libstrongswan_tnc_imv_la_LIBADD = \
+ $(top_builddir)/src/libtncif/libtncif.la \
+ $(top_builddir)/src/libtnccs/libtnccs.la
endif
libstrongswan_tnc_imv_la_SOURCES = \
diff --git a/src/libcharon/plugins/tnc_imv/Makefile.in b/src/libcharon/plugins/tnc_imv/Makefile.in
index fb96150f4..cf58f0dc3 100644
--- a/src/libcharon/plugins/tnc_imv/Makefile.in
+++ b/src/libcharon/plugins/tnc_imv/Makefile.in
@@ -74,7 +74,9 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
-libstrongswan_tnc_imv_la_LIBADD =
+@MONOLITHIC_FALSE@libstrongswan_tnc_imv_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
am_libstrongswan_tnc_imv_la_OBJECTS = tnc_imv_plugin.lo tnc_imv.lo \
tnc_imv_manager.lo tnc_imv_bind_function.lo \
tnc_imv_recommendations.lo
@@ -195,6 +197,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +208,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +225,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +275,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -277,12 +286,20 @@ 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
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-imv.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-imv.la
+@MONOLITHIC_FALSE@libstrongswan_tnc_imv_la_LIBADD = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+
libstrongswan_tnc_imv_la_SOURCES = \
tnc_imv_plugin.h tnc_imv_plugin.c tnc_imv.h tnc_imv.c \
tnc_imv_manager.h tnc_imv_manager.c tnc_imv_bind_function.c \
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv.c b/src/libcharon/plugins/tnc_imv/tnc_imv.c
index fe628ee7e..f0b150743 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Mike McCauley
- * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010-2011 Andreas Steffen,
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -17,8 +18,11 @@
#include <dlfcn.h>
+#include <tncif_pa_subtypes.h>
+
#include <debug.h>
#include <library.h>
+#include <utils/linked_list.h>
#include <threading/mutex.h>
typedef struct private_tnc_imv_t private_tnc_imv_t;
@@ -54,9 +58,19 @@ struct private_tnc_imv_t {
TNC_IMVID id;
/**
- * List of message types supported by IMC
+ * List of additional IMV IDs
*/
- TNC_MessageTypeList supported_types;
+ linked_list_t *additional_ids;
+
+ /**
+ * List of message types supported by IMV - Vendor ID part
+ */
+ TNC_VendorIDList supported_vids;
+
+ /**
+ * List of message types supported by IMV - Subtype part
+ */
+ TNC_MessageSubtypeList supported_subtypes;
/**
* Number of supported message types
@@ -81,6 +95,50 @@ METHOD(imv_t, get_id, TNC_IMVID,
return this->id;
}
+METHOD(imv_t, add_id, void,
+ private_tnc_imv_t *this, TNC_IMVID id)
+{
+ TNC_IMVID *new_id;
+
+ new_id = malloc_thing(TNC_IMVID);
+ *new_id = id;
+ this->additional_ids->insert_last(this->additional_ids, new_id);
+}
+
+METHOD(imv_t, has_id, bool,
+ private_tnc_imv_t *this, TNC_IMVID id)
+{
+ enumerator_t *enumerator;
+ TNC_IMVID *additional_id;
+ bool found = FALSE;
+
+ /* check primary IMV ID */
+ if (id == this->id)
+ {
+ return TRUE;
+ }
+
+ /* return if there are no additional IMV IDs */
+ if (this->additional_ids->get_count(this->additional_ids) == 0)
+ {
+ return FALSE;
+ }
+
+ /* check additional IMV IDs */
+ enumerator = this->additional_ids->create_enumerator(this->additional_ids);
+ while (enumerator->enumerate(enumerator, &additional_id))
+ {
+ if (id == *additional_id)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
METHOD(imv_t, get_name, char*,
private_tnc_imv_t *this)
{
@@ -91,67 +149,150 @@ METHOD(imv_t, set_message_types, void,
private_tnc_imv_t *this, TNC_MessageTypeList supported_types,
TNC_UInt32 type_count)
{
- char buf[512];
+ char buf[BUF_LEN];
char *pos = buf;
int len = sizeof(buf);
- int written;
+ int i, written;
+ size_t size;
+ TNC_VendorID vid;
+ TNC_MessageSubtype subtype;
+ enum_name_t *pa_subtype_names;
/* lock the imv_t instance */
this->mutex->lock(this->mutex);
- /* Free an existing MessageType list */
- free(this->supported_types);
- this->supported_types = NULL;
+ /* Free existing VendorID and MessageSubtype lists */
+ free(this->supported_vids);
+ this->supported_vids = NULL;
+ free(this->supported_subtypes);
+ this->supported_subtypes = NULL;
/* Store the new MessageType list */
this->type_count = type_count;
if (type_count && supported_types)
{
- size_t size = type_count * sizeof(TNC_MessageType);
-
- int i;
+ size = type_count * sizeof(TNC_VendorID);
+ this->supported_vids = malloc(size);
+ size = type_count * sizeof(TNC_MessageSubtype);
+ this->supported_subtypes = malloc(size);
for (i = 0; i < type_count; i++)
{
- written = snprintf(pos, len, " 0x%08x", supported_types[i]);
+ vid = (supported_types[i] >> 8) & TNC_VENDORID_ANY;
+ subtype = supported_types[i] & TNC_SUBTYPE_ANY;
+
+ pa_subtype_names = get_pa_subtype_names(vid);
+ if (pa_subtype_names)
+ {
+ written = snprintf(pos, len," '%N/%N' 0x%06x/0x%02x",
+ pen_names, vid, pa_subtype_names, subtype,
+ vid, subtype);
+ }
+ else
+ {
+ written = snprintf(pos, len," '%N' 0x%06x/0x%02x",
+ pen_names, vid, vid, subtype);
+ }
if (written >= len)
{
break;
}
pos += written;
len -= written;
+
+ this->supported_vids[i] = vid;
+ this->supported_subtypes[i] = subtype;
}
- this->supported_types = malloc(size);
- memcpy(this->supported_types, supported_types, size);
}
*pos = '\0';
- DBG2(DBG_TNC, "IMV %u supports %u message types:%s",
- this->id, type_count, buf);
+ DBG2(DBG_TNC, "IMV %u supports %u message type%s:%s",
+ this->id, type_count, (type_count == 1) ? "":"s", buf);
+
+ /* unlock the imv_t instance */
+ this->mutex->unlock(this->mutex);
+}
+
+METHOD(imv_t, set_message_types_long, void,
+ private_tnc_imv_t *this, TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes, TNC_UInt32 type_count)
+{
+ char buf[BUF_LEN];
+ char *pos = buf;
+ int len = sizeof(buf);
+ int i, written;
+ size_t size;
+ TNC_VendorID vid;
+ TNC_MessageSubtype subtype;
+ enum_name_t *pa_subtype_names;
/* lock the imv_t instance */
+ this->mutex->lock(this->mutex);
+
+ /* Free existing VendorID and MessageSubtype lists */
+ free(this->supported_vids);
+ this->supported_vids = NULL;
+ free(this->supported_subtypes);
+ this->supported_subtypes = NULL;
+
+ /* Store the new MessageType list */
+ this->type_count = type_count;
+ if (type_count && supported_vids && supported_subtypes)
+ {
+ size = type_count * sizeof(TNC_VendorID);
+ this->supported_vids = malloc(size);
+ memcpy(this->supported_vids, supported_vids, size);
+ size = type_count * sizeof(TNC_MessageSubtype);
+ this->supported_subtypes = malloc(size);
+ memcpy(this->supported_subtypes, supported_subtypes, size);
+
+ for (i = 0; i < type_count; i++)
+ {
+ vid = supported_vids[i];
+ subtype = supported_subtypes[i];
+
+ pa_subtype_names = get_pa_subtype_names(vid);
+ if (pa_subtype_names)
+ {
+ written = snprintf(pos, len," '%N/%N' 0x%06x/0x%08x",
+ pen_names, vid, pa_subtype_names, subtype,
+ vid, subtype);
+ }
+ else
+ {
+ written = snprintf(pos, len," '%N' 0x%06x/0x%08x",
+ pen_names, vid, vid, subtype);
+ }
+ if (written >= len)
+ {
+ break;
+ }
+ pos += written;
+ len -= written;
+ }
+ }
+ *pos = '\0';
+ DBG2(DBG_TNC, "IMV %u supports %u message type%s:%s",
+ this->id, type_count, (type_count == 1) ? "":"s", buf);
+
+ /* unlock the imv_t instance */
this->mutex->unlock(this->mutex);
}
METHOD(imv_t, type_supported, bool,
- private_tnc_imv_t *this, TNC_MessageType message_type)
+ private_tnc_imv_t *this, TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype)
{
- TNC_VendorID msg_vid, vid;
- TNC_MessageSubtype msg_subtype, subtype;
+ TNC_VendorID vid;
+ TNC_MessageSubtype subtype;
int i;
- msg_vid = (message_type >> 8) & TNC_VENDORID_ANY;
- msg_subtype = message_type & TNC_SUBTYPE_ANY;
-
for (i = 0; i < this->type_count; i++)
{
- vid = (this->supported_types[i] >> 8) & TNC_VENDORID_ANY;
- subtype = this->supported_types[i] & TNC_SUBTYPE_ANY;
-
- if (this->supported_types[i] == message_type
- || (subtype == TNC_SUBTYPE_ANY
- && (msg_vid == vid || vid == TNC_VENDORID_ANY))
- || (vid == TNC_VENDORID_ANY
- && (msg_subtype == subtype || subtype == TNC_SUBTYPE_ANY)))
+ vid = this->supported_vids[i];
+ subtype = this->supported_subtypes[i];
+
+ if ((vid == TNC_VENDORID_ANY && subtype == TNC_SUBTYPE_ANY) ||
+ (vid == msg_vid && (subtype == TNC_SUBTYPE_ANY ||
+ subtype == msg_subtype)))
{
return TRUE;
}
@@ -164,7 +305,9 @@ METHOD(imv_t, destroy, void,
{
dlclose(this->handle);
this->mutex->destroy(this->mutex);
- free(this->supported_types);
+ this->additional_ids->destroy_function(this->additional_ids, free);
+ free(this->supported_vids);
+ free(this->supported_subtypes);
free(this->name);
free(this->path);
free(this);
@@ -181,13 +324,17 @@ imv_t* tnc_imv_create(char *name, char *path)
.public = {
.set_id = _set_id,
.get_id = _get_id,
+ .add_id = _add_id,
+ .has_id = _has_id,
.get_name = _get_name,
.set_message_types = _set_message_types,
+ .set_message_types_long = _set_message_types_long,
.type_supported = _type_supported,
.destroy = _destroy,
},
.name = name,
.path = path,
+ .additional_ids = linked_list_create(),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
);
@@ -222,6 +369,8 @@ imv_t* tnc_imv_create(char *name, char *path)
}
this->public.receive_message =
dlsym(this->handle, "TNC_IMV_ReceiveMessage");
+ this->public.receive_message_long =
+ dlsym(this->handle, "TNC_IMV_ReceiveMessageLong");
this->public.batch_ending =
dlsym(this->handle, "TNC_IMV_BatchEnding");
this->public.terminate =
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c b/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
index 0ed00b001..dd11c5009 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_bind_function.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Mike McCauley
- * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010-2011 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,12 +14,11 @@
* for more details.
*/
-#include "tnc_imv.h"
+#include <tnc/tnc.h>
+#include <tnc/imv/imv_manager.h>
+#include <tnc/tnccs/tnccs_manager.h>
#include <debug.h>
-#include <daemon.h>
-
-#define TNC_IMCID_ANY 0xffff
/**
* Called by the IMV to inform a TNCS about the set of message types the IMV
@@ -28,14 +28,33 @@ TNC_Result TNC_TNCS_ReportMessageTypes(TNC_IMVID imv_id,
TNC_MessageTypeList supported_types,
TNC_UInt32 type_count)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring ReportMessageTypes() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->imvs->set_message_types(charon->imvs, imv_id,
- supported_types, type_count);
+ return tnc->imvs->set_message_types(tnc->imvs, imv_id, supported_types,
+ type_count);
+}
+
+/**
+ * Called by the IMV to inform a TNCS about the set of message types the IMV
+ * is able to receive. This function supports long message types.
+ */
+TNC_Result TNC_TNCS_ReportMessageTypesLong(TNC_IMVID imv_id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count)
+{
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
+ {
+ DBG1(DBG_TNC, "ignoring ReportMessageTypesLong() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return tnc->imvs->set_message_types_long(tnc->imvs, imv_id, supported_vids,
+ supported_subtypes, type_count);
}
/**
@@ -45,14 +64,14 @@ TNC_Result TNC_TNCS_RequestHandshakeRetry(TNC_IMVID imv_id,
TNC_ConnectionID connection_id,
TNC_RetryReason reason)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring RequestHandshakeRetry() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->request_handshake_retry(charon->tnccs, FALSE, imv_id,
- connection_id, reason);
+ return tnc->tnccs->request_handshake_retry(tnc->tnccs, FALSE, imv_id,
+ connection_id, reason);
}
/**
@@ -64,14 +83,42 @@ TNC_Result TNC_TNCS_SendMessage(TNC_IMVID imv_id,
TNC_UInt32 msg_len,
TNC_MessageType msg_type)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ TNC_VendorID msg_vid;
+ TNC_MessageSubtype msg_subtype;
+
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring SendMessage() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->send_message(charon->tnccs, TNC_IMCID_ANY, imv_id,
- connection_id, msg, msg_len, msg_type);
+ msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY;
+ msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+
+ return tnc->tnccs->send_message(tnc->tnccs, TNC_IMCID_ANY, imv_id,
+ connection_id, 0, msg, msg_len, msg_vid, msg_subtype);
+}
+
+/**
+ * Called by the IMV when an IMV-IMC message is to be sent over IF-TNCCS 2.0
+ */
+TNC_Result TNC_TNCS_SendMessageLong(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 imc_id)
+{
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
+ {
+ DBG1(DBG_TNC, "ignoring SendMessageLong() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return tnc->tnccs->send_message(tnc->tnccs, imc_id, imv_id, connection_id,
+ msg_flags, msg, msg_len, msg_vid, msg_subtype);
}
/**
@@ -83,14 +130,14 @@ TNC_Result TNC_TNCS_ProvideRecommendation(TNC_IMVID imv_id,
TNC_IMV_Action_Recommendation recommendation,
TNC_IMV_Evaluation_Result evaluation)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring ProvideRecommendation() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->provide_recommendation(charon->tnccs, imv_id,
- connection_id, recommendation, evaluation);
+ return tnc->tnccs->provide_recommendation(tnc->tnccs, imv_id, connection_id,
+ recommendation, evaluation);
}
/**
@@ -104,13 +151,13 @@ TNC_Result TNC_TNCS_GetAttribute(TNC_IMVID imv_id,
TNC_BufferReference buffer,
TNC_UInt32 *out_value_len)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring GetAttribute() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->get_attribute(charon->tnccs, imv_id, connection_id,
+ return tnc->tnccs->get_attribute(tnc->tnccs, FALSE, imv_id, connection_id,
attribute_id, buffer_len, buffer, out_value_len);
}
@@ -124,14 +171,28 @@ TNC_Result TNC_TNCS_SetAttribute(TNC_IMVID imv_id,
TNC_UInt32 buffer_len,
TNC_BufferReference buffer)
{
- if (!charon->imvs->is_registered(charon->imvs, imv_id))
+ if (!tnc->imvs->is_registered(tnc->imvs, imv_id))
{
DBG1(DBG_TNC, "ignoring SetAttribute() from unregistered IMV %u",
imv_id);
return TNC_RESULT_INVALID_PARAMETER;
}
- return charon->tnccs->set_attribute(charon->tnccs, imv_id, connection_id,
- attribute_id, buffer_len, buffer);
+ return tnc->tnccs->set_attribute(tnc->tnccs, FALSE, imv_id, connection_id,
+ attribute_id, buffer_len, buffer);
+}
+
+/**
+ * Called by the IMV when it wants to reserve an additional IMV ID for itself
+ */
+TNC_Result TNC_TNCS_ReserveAdditionalIMVID(TNC_IMVID imv_id, TNC_UInt32 *new_id)
+{
+ if (tnc->imvs->reserve_id(tnc->imvs, imv_id, new_id))
+ {
+ return TNC_RESULT_SUCCESS;
+ }
+ DBG1(DBG_TNC, "ignoring ReserveAdditionalIMVID() from unregistered IMV %u",
+ imv_id);
+ return TNC_RESULT_INVALID_PARAMETER;
}
/**
@@ -145,6 +206,10 @@ TNC_Result TNC_TNCS_BindFunction(TNC_IMVID id,
{
*function_pointer = (void*)TNC_TNCS_ReportMessageTypes;
}
+ else if (streq(function_name, "TNC_TNCS_ReportMessageTypesLong"))
+ {
+ *function_pointer = (void*)TNC_TNCS_ReportMessageTypesLong;
+ }
else if (streq(function_name, "TNC_TNCS_RequestHandshakeRetry"))
{
*function_pointer = (void*)TNC_TNCS_RequestHandshakeRetry;
@@ -153,6 +218,10 @@ TNC_Result TNC_TNCS_BindFunction(TNC_IMVID id,
{
*function_pointer = (void*)TNC_TNCS_SendMessage;
}
+ else if (streq(function_name, "TNC_TNCS_SendMessageLong"))
+ {
+ *function_pointer = (void*)TNC_TNCS_SendMessageLong;
+ }
else if (streq(function_name, "TNC_TNCS_ProvideRecommendation"))
{
*function_pointer = (void*)TNC_TNCS_ProvideRecommendation;
@@ -165,6 +234,10 @@ TNC_Result TNC_TNCS_BindFunction(TNC_IMVID id,
{
*function_pointer = (void*)TNC_TNCS_SetAttribute;
}
+ else if (streq(function_name, "TNC_TNCS_ReserveAdditionalIMVID"))
+ {
+ *function_pointer = (void*)TNC_TNCS_ReserveAdditionalIMVID;
+ }
else
{
return TNC_RESULT_INVALID_PARAMETER;
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
index 579ab06ff..b1da73156 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006 Mike McCauley
- * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010-2011 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
@@ -14,13 +15,22 @@
*/
#include "tnc_imv_manager.h"
+#include "tnc_imv.h"
#include "tnc_imv_recommendations.h"
-#include <tnc/imv/imv_manager.h>
-#include <tnc/tncifimv.h>
+#include <tncifimv.h>
+#include <tncif_names.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
-#include <debug.h>
#include <daemon.h>
+#include <utils/lexparser.h>
+#include <debug.h>
#include <threading/mutex.h>
typedef struct private_tnc_imv_manager_t private_tnc_imv_manager_t;
@@ -101,6 +111,33 @@ METHOD(imv_manager_t, remove_, imv_t*,
return removed_imv;
}
+METHOD(imv_manager_t, load, bool,
+ private_tnc_imv_manager_t *this, char *name, char *path)
+{
+ imv_t *imv;
+
+ imv = tnc_imv_create(name, path);
+ if (!imv)
+ {
+ free(name);
+ free(path);
+ return FALSE;
+ }
+ if (!add(this, imv))
+ {
+ if (imv->terminate &&
+ imv->terminate(imv->get_id(imv)) != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_TNC, "IMV \"%s\" not terminated successfully",
+ imv->get_name(imv));
+ }
+ imv->destroy(imv);
+ return FALSE;
+ }
+ DBG1(DBG_TNC, "IMV %u \"%s\" loaded from '%s'", imv->get_id(imv), name, path);
+ return TRUE;
+}
+
METHOD(imv_manager_t, is_registered, bool,
private_tnc_imv_manager_t *this, TNC_IMVID id)
{
@@ -111,9 +148,34 @@ METHOD(imv_manager_t, is_registered, bool,
enumerator = this->imvs->create_enumerator(this->imvs);
while (enumerator->enumerate(enumerator, &imv))
{
- if (id == imv->get_id(imv))
+ if (imv->has_id(imv, id))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return found;
+}
+
+METHOD(imv_manager_t, reserve_id, bool,
+ private_tnc_imv_manager_t *this, TNC_IMVID id, TNC_UInt32 *new_id)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+ bool found = FALSE;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ if (imv->get_id(imv))
{
found = TRUE;
+ *new_id = this->next_imv_id++;
+ imv->add_id(imv, *new_id);
+ DBG2(DBG_TNC, "additional ID %u reserved for IMV with primary ID %u",
+ *new_id, id);
break;
}
}
@@ -231,6 +293,31 @@ METHOD(imv_manager_t, set_message_types, TNC_Result,
return result;
}
+METHOD(imv_manager_t, set_message_types_long, TNC_Result,
+ private_tnc_imv_manager_t *this, TNC_IMVID id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+ TNC_Result result = TNC_RESULT_FATAL;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ if (id == imv->get_id(imv))
+ {
+ imv->set_message_types_long(imv, supported_vids, supported_subtypes,
+ type_count);
+ result = TNC_RESULT_SUCCESS;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return result;
+}
+
METHOD(imv_manager_t, solicit_recommendation, void,
private_tnc_imv_manager_t *this, TNC_ConnectionID id)
{
@@ -247,28 +334,52 @@ METHOD(imv_manager_t, solicit_recommendation, void,
METHOD(imv_manager_t, receive_message, void,
private_tnc_imv_manager_t *this, TNC_ConnectionID connection_id,
- TNC_BufferReference message,
- TNC_UInt32 message_len,
- TNC_MessageType message_type)
+ bool excl,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id)
{
bool type_supported = FALSE;
+ TNC_MessageType msg_type;
+ TNC_UInt32 msg_flags;
enumerator_t *enumerator;
imv_t *imv;
+ msg_type = (msg_vid << 8) | msg_subtype;
+
enumerator = this->imvs->create_enumerator(this->imvs);
while (enumerator->enumerate(enumerator, &imv))
{
- if (imv->receive_message && imv->type_supported(imv, message_type))
+ if (imv->type_supported(imv, msg_vid, msg_subtype) &&
+ (!excl || (excl && imv->has_id(imv, dst_imv_id)) ))
{
- type_supported = TRUE;
- imv->receive_message(imv->get_id(imv), connection_id,
- message, message_len, message_type);
+ if (imv->receive_message_long && src_imc_id)
+ {
+ type_supported = TRUE;
+ msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0;
+ imv->receive_message_long(imv->get_id(imv), connection_id,
+ msg_flags, msg, msg_len, msg_vid, msg_subtype,
+ src_imc_id, dst_imv_id);
+
+ }
+ else if (imv->receive_message && msg_vid <= TNC_VENDORID_ANY &&
+ msg_subtype <= TNC_SUBTYPE_ANY)
+ {
+ type_supported = TRUE;
+ msg_type = (msg_vid << 8) | msg_subtype;
+ imv->receive_message(imv->get_id(imv), connection_id,
+ msg, msg_len, msg_type);
+ }
}
}
enumerator->destroy(enumerator);
if (!type_supported)
{
- DBG2(DBG_TNC, "message type 0x%08x not supported by any IMV", message_type);
+ DBG2(DBG_TNC, "message type 0x%06x/0x%08x not supported by any IMV",
+ msg_vid, msg_subtype);
}
}
@@ -289,6 +400,7 @@ METHOD(imv_manager_t, batch_ending, void,
enumerator->destroy(enumerator);
}
+
METHOD(imv_manager_t, destroy, void,
private_tnc_imv_manager_t *this)
{
@@ -320,12 +432,15 @@ imv_manager_t* tnc_imv_manager_create(void)
.public = {
.add = _add,
.remove = _remove_, /* avoid name conflict with stdio.h */
+ .load = _load,
.is_registered = _is_registered,
+ .reserve_id = _reserve_id,
.get_recommendation_policy = _get_recommendation_policy,
.create_recommendations = _create_recommendations,
.enforce_recommendation = _enforce_recommendation,
.notify_connection_change = _notify_connection_change,
.set_message_types = _set_message_types,
+ .set_message_types_long = _set_message_types_long,
.solicit_recommendation = _solicit_recommendation,
.receive_message = _receive_message,
.batch_ending = _batch_ending,
@@ -334,6 +449,7 @@ imv_manager_t* tnc_imv_manager_create(void)
.imvs = linked_list_create(),
.next_imv_id = 1,
);
+
policy = enum_from_name(recommendation_policy_names,
lib->settings->get_str(lib->settings,
"charon.plugins.tnc-imv.recommendation_policy", "default"));
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
index 45cf95c1b..c16f6b9e1 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_plugin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010-2011 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,137 +15,24 @@
#include "tnc_imv_plugin.h"
#include "tnc_imv_manager.h"
-#include "tnc_imv.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
+#include <tnc/tnc.h>
-#include <daemon.h>
-#include <utils/lexparser.h>
+
+typedef struct private_tnc_imv_plugin_t private_tnc_imv_plugin_t;
/**
- * load IMVs from a configuration file
+ * Private data of a tnc_imv_plugin_t object.
*/
-static bool load_imvs(char *filename)
-{
- int fd, line_nr = 0;
- chunk_t src, line;
- struct stat sb;
- void *addr;
-
- DBG1(DBG_TNC, "loading IMVs from '%s'", filename);
- fd = open(filename, O_RDONLY);
- if (fd == -1)
- {
- DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
- strerror(errno));
- return FALSE;
- }
- if (fstat(fd, &sb) == -1)
- {
- DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
- strerror(errno));
- close(fd);
- return FALSE;
- }
- 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", filename, strerror(errno));
- close(fd);
- return FALSE;
- }
- src = chunk_create(addr, sb.st_size);
-
- while (fetchline(&src, &line))
- {
- char *name, *path;
- chunk_t token;
- imv_t *imv;
-
- line_nr++;
-
- /* skip comments or empty lines */
- if (*line.ptr == '#' || !eat_whitespace(&line))
- {
- continue;
- }
-
- /* determine keyword */
- if (!extract_token(&token, ' ', &line))
- {
- DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
- line_nr);
- return FALSE;
- }
-
- /* only interested in IMVs */
- if (!match("IMV", &token))
- {
- continue;
- }
-
- /* advance to the IMV name and extract it */
- if (!extract_token(&token, '"', &line) ||
- !extract_token(&token, '"', &line))
- {
- DBG1(DBG_TNC, "line %d: IMV name must be set in double quotes",
- line_nr);
- return FALSE;
- }
+struct private_tnc_imv_plugin_t {
- /* copy the IMV name */
- name = malloc(token.len + 1);
- memcpy(name, token.ptr, token.len);
- name[token.len] = '\0';
+ /**
+ * Public interface.
+ */
+ tnc_imv_plugin_t public;
- /* advance to the IMV path and extract it */
- if (!eat_whitespace(&line))
- {
- DBG1(DBG_TNC, "line %d: IMV path is missing", line_nr);
- free(name);
- return FALSE;
- }
- if (!extract_token(&token, ' ', &line))
- {
- token = line;
- }
+};
- /* copy the IMV path */
- path = malloc(token.len + 1);
- memcpy(path, token.ptr, token.len);
- path[token.len] = '\0';
-
- /* load and register IMV instance */
- imv = tnc_imv_create(name, path);
- if (!imv)
- {
- free(name);
- free(path);
- return FALSE;
- }
- if (!charon->imvs->add(charon->imvs, imv))
- {
- if (imv->terminate &&
- imv->terminate(imv->get_id(imv)) != TNC_RESULT_SUCCESS)
- {
- DBG1(DBG_TNC, "IMV \"%s\" not terminated successfully",
- imv->get_name(imv));
- }
- imv->destroy(imv);
- return FALSE;
- }
- DBG1(DBG_TNC, "IMV %u \"%s\" loaded from '%s'", imv->get_id(imv),
- name, path);
- }
- munmap(addr, sb.st_size);
- close(fd);
- return TRUE;
-}
METHOD(plugin_t, get_name, char*,
tnc_imv_plugin_t *this)
@@ -153,10 +40,21 @@ METHOD(plugin_t, get_name, char*,
return "tnc-imv";
}
+METHOD(plugin_t, get_features, int,
+ private_tnc_imv_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(tnc_manager_register, tnc_imv_manager_create),
+ PLUGIN_PROVIDE(CUSTOM, "imv-manager"),
+ PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
- tnc_imv_plugin_t *this)
+ private_tnc_imv_plugin_t *this)
{
- charon->imvs->destroy(charon->imvs);
free(this);
}
@@ -165,31 +63,18 @@ METHOD(plugin_t, destroy, void,
*/
plugin_t *tnc_imv_plugin_create()
{
- char *tnc_config;
- tnc_imv_plugin_t *this;
+ private_tnc_imv_plugin_t *this;
INIT(this,
- .plugin = {
- .get_name = _get_name,
- .reload = (void*)return_false,
- .destroy = _destroy,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
},
);
- tnc_config = lib->settings->get_str(lib->settings,
- "charon.plugins.tnc-imv.tnc_config", "/etc/tnc_config");
-
- /* Create IMV manager */
- charon->imvs = tnc_imv_manager_create();
-
- /* Load IMVs and abort if not all instances initalize successfully */
- if (!load_imvs(tnc_config))
- {
- charon->imvs->destroy(charon->imvs);
- charon->imvs = NULL;
- free(this);
- return NULL;
- }
- return &this->plugin;
+ return &this->public.plugin;
}
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c b/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c
index 5cc6b0ced..7843293a1 100644
--- a/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c
+++ b/src/libcharon/plugins/tnc_imv/tnc_imv_recommendations.c
@@ -12,12 +12,17 @@
* for more details.
*/
-#include <debug.h>
-#include <daemon.h>
-#include <tnc/tncifimv.h>
+#include <tncifimv.h>
+#include <tncif_names.h>
+
+#include <tnc/tnc.h>
#include <tnc/imv/imv.h>
+#include <tnc/imv/imv_manager.h>
#include <tnc/imv/imv_recommendations.h>
+#include <debug.h>
+#include <utils/linked_list.h>
+
typedef struct private_tnc_imv_recommendations_t private_tnc_imv_recommendations_t;
typedef struct recommendation_entry_t recommendation_entry_t;
@@ -126,7 +131,7 @@ METHOD(recommendations_t, have_recommendation, bool,
DBG1(DBG_TNC, "there are no IMVs to make a recommendation");
return TRUE;
}
- policy = charon->imvs->get_recommendation_policy(charon->imvs);
+ policy = tnc->imvs->get_recommendation_policy(tnc->imvs);
enumerator = this->recs->create_enumerator(this->recs);
while (enumerator->enumerate(enumerator, &entry))
@@ -357,6 +362,21 @@ METHOD(recommendations_t, create_reason_enumerator, enumerator_t*,
(void*)reason_filter, NULL, NULL);
}
+METHOD(recommendations_t, clear_reasons, void,
+ private_tnc_imv_recommendations_t *this)
+{
+ enumerator_t *enumerator;
+ recommendation_entry_t *entry;
+
+ enumerator = this->recs->create_enumerator(this->recs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ chunk_clear(&entry->reason);
+ chunk_clear(&entry->reason_language);
+ }
+ enumerator->destroy(enumerator);
+}
+
METHOD(recommendations_t, destroy, void,
private_tnc_imv_recommendations_t *this)
{
@@ -392,6 +412,7 @@ recommendations_t* tnc_imv_recommendations_create(linked_list_t *imv_list)
.set_reason_string = _set_reason_string,
.set_reason_language = _set_reason_language,
.create_reason_enumerator = _create_reason_enumerator,
+ .clear_reasons = _clear_reasons,
.destroy = _destroy,
},
.recs = linked_list_create(),
diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.am b/src/libcharon/plugins/tnc_pdp/Makefile.am
new file mode 100644
index 000000000..2d4c4d55a
--- /dev/null
+++ b/src/libcharon/plugins/tnc_pdp/Makefile.am
@@ -0,0 +1,24 @@
+
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libcharon \
+ -I$(top_srcdir)/src/libradius
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-tnc-pdp.la
+else
+plugin_LTLIBRARIES = libstrongswan-tnc-pdp.la
+libstrongswan_tnc_pdp_la_LIBADD = \
+ $(top_builddir)/src/libradius/libradius.la \
+ $(top_builddir)/src/libtls/libtls.la \
+ $(top_builddir)/src/libtnccs/libtnccs.la
+endif
+
+libstrongswan_tnc_pdp_la_SOURCES = \
+ tnc_pdp_plugin.h tnc_pdp_plugin.c \
+ tnc_pdp.h tnc_pdp.c tnc_pdp_connections.h tnc_pdp_connections.c
+
+libstrongswan_tnc_pdp_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.in b/src/libcharon/plugins/tnc_pdp/Makefile.in
new file mode 100644
index 000000000..70d3d6249
--- /dev/null
+++ b/src/libcharon/plugins/tnc_pdp/Makefile.in
@@ -0,0 +1,627 @@
+# 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/tnc_pdp
+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_tnc_pdp_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libradius/libradius.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+am_libstrongswan_tnc_pdp_la_OBJECTS = tnc_pdp_plugin.lo tnc_pdp.lo \
+ tnc_pdp_connections.lo
+libstrongswan_tnc_pdp_la_OBJECTS = \
+ $(am_libstrongswan_tnc_pdp_la_OBJECTS)
+libstrongswan_tnc_pdp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_tnc_pdp_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_tnc_pdp_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_tnc_pdp_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_tnc_pdp_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_tnc_pdp_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libradius
+
+AM_CFLAGS = -rdynamic
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-pdp.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-pdp.la
+@MONOLITHIC_FALSE@libstrongswan_tnc_pdp_la_LIBADD = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libradius/libradius.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+
+libstrongswan_tnc_pdp_la_SOURCES = \
+ tnc_pdp_plugin.h tnc_pdp_plugin.c \
+ tnc_pdp.h tnc_pdp.c tnc_pdp_connections.h tnc_pdp_connections.c
+
+libstrongswan_tnc_pdp_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/tnc_pdp/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_pdp/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-tnc-pdp.la: $(libstrongswan_tnc_pdp_la_OBJECTS) $(libstrongswan_tnc_pdp_la_DEPENDENCIES)
+ $(libstrongswan_tnc_pdp_la_LINK) $(am_libstrongswan_tnc_pdp_la_rpath) $(libstrongswan_tnc_pdp_la_OBJECTS) $(libstrongswan_tnc_pdp_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_pdp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_pdp_connections.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_pdp_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/tnc_pdp/tnc_pdp.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c
new file mode 100644
index 000000000..0625baa90
--- /dev/null
+++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c
@@ -0,0 +1,648 @@
+/*
+ * Copyright (C) 2012 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_pdp.h"
+#include "tnc_pdp_connections.h"
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <radius_message.h>
+#include <radius_mppe.h>
+
+#include <daemon.h>
+#include <debug.h>
+#include <pen/pen.h>
+#include <threading/thread.h>
+#include <processing/jobs/callback_job.h>
+#include <sa/authenticators/eap/eap_method.h>
+
+typedef struct private_tnc_pdp_t private_tnc_pdp_t;
+
+/**
+ * Maximum size of a RADIUS IP packet
+ */
+#define MAX_PACKET 4096
+
+/**
+ * private data of tnc_pdp_t
+ */
+struct private_tnc_pdp_t {
+
+ /**
+ * implements tnc_pdp_t interface
+ */
+ tnc_pdp_t public;
+
+ /**
+ * ID of the server
+ */
+ identification_t *server;
+
+ /**
+ * EAP method type to be used
+ */
+ eap_type_t type;
+
+ /**
+ * IPv4 RADIUS socket
+ */
+ int ipv4;
+
+ /**
+ * IPv6 RADIUS socket
+ */
+ int ipv6;
+
+ /**
+ * Callback job dispatching commands
+ */
+ callback_job_t *job;
+
+ /**
+ * RADIUS shared secret
+ */
+ chunk_t secret;
+
+ /**
+ * MD5 hasher
+ */
+ hasher_t *hasher;
+
+ /**
+ * HMAC MD5 signer, with secret set
+ */
+ signer_t *signer;
+
+ /**
+ * Random number generator for MS-MPPE salt values
+ */
+ rng_t *rng;
+
+ /**
+ * List of registered TNC-PDP connections
+ */
+ tnc_pdp_connections_t *connections;
+};
+
+
+/**
+ * Open IPv4 or IPv6 UDP RADIUS socket
+ */
+static int open_socket(int family, u_int16_t port)
+{
+ int on = TRUE;
+ struct sockaddr_storage addr;
+ socklen_t addrlen;
+ int skt;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.ss_family = family;
+
+ /* precalculate constants depending on address family */
+ switch (family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
+
+ htoun32(&sin->sin_addr.s_addr, INADDR_ANY);
+ htoun16(&sin->sin_port, port);
+ addrlen = sizeof(struct sockaddr_in);
+ break;
+ }
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
+
+ memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
+ htoun16(&sin6->sin6_port, port);
+ addrlen = sizeof(struct sockaddr_in6);
+ break;
+ }
+ default:
+ return 0;
+ }
+
+ /* open the socket */
+ skt = socket(family, SOCK_DGRAM, IPPROTO_UDP);
+ if (skt < 0)
+ {
+ DBG1(DBG_CFG, "opening RADIUS socket failed: %s", strerror(errno));
+ return 0;
+ }
+ if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
+ {
+ DBG1(DBG_CFG, "unable to set SO_REUSEADDR on socket: %s", strerror(errno));
+ close(skt);
+ return 0;
+ }
+
+ /* bind the socket */
+ if (bind(skt, (struct sockaddr *)&addr, addrlen) < 0)
+ {
+ DBG1(DBG_CFG, "unable to bind RADIUS socket: %s", strerror(errno));
+ close(skt);
+ return 0;
+ }
+
+ return skt;
+}
+
+/**
+ * Send a RADIUS message to client
+ */
+static void send_message(private_tnc_pdp_t *this, radius_message_t *message,
+ host_t *client)
+{
+ int fd;
+ chunk_t data;
+
+ fd = (client->get_family(client) == AF_INET) ? this->ipv4 : this->ipv6;
+ data = message->get_encoding(message);
+
+ DBG2(DBG_CFG, "sending RADIUS packet to %#H", client);
+ DBG3(DBG_CFG, "%B", &data);
+
+ if (sendto(fd, data.ptr, data.len, 0, client->get_sockaddr(client),
+ *client->get_sockaddr_len(client)) != data.len)
+ {
+ DBG1(DBG_CFG, "sending RADIUS message failed: %s", strerror(errno));
+ }
+}
+
+/**
+ * Encrypt a MS-MPPE-Send/Recv-Key
+ */
+static chunk_t encrypt_mppe_key(private_tnc_pdp_t *this, u_int8_t type,
+ chunk_t key, u_int16_t *salt,
+ radius_message_t *request)
+{
+ chunk_t a, r, seed, data;
+ u_char b[HASH_SIZE_MD5], *c;
+ mppe_key_t *mppe_key;
+
+ /**
+ * From RFC2548 (encryption):
+ * b(1) = MD5(S + R + A) c(1) = p(1) xor b(1) C = c(1)
+ * b(2) = MD5(S + c(1)) c(2) = p(2) xor b(2) C = C + c(2)
+ * . . .
+ * b(i) = MD5(S + c(i-1)) c(i) = p(i) xor b(i) C = C + c(i)
+ */
+
+ data = chunk_alloc(sizeof(mppe_key_t) +
+ HASH_SIZE_MD5 * (1 + key.len / HASH_SIZE_MD5));
+ memset(data.ptr, 0x00, data.len);
+
+ mppe_key = (mppe_key_t*)data.ptr;
+ mppe_key->id = htonl(PEN_MICROSOFT);
+ mppe_key->type = type;
+ mppe_key->length = data.len - sizeof(mppe_key->id);
+ mppe_key->key[0] = key.len;
+
+ memcpy(&mppe_key->key[1], key.ptr, key.len);
+
+ /**
+ * generate a 16 bit unique random salt value for the MPPE stream cipher
+ * the MSB of the salt MUST be set to 1
+ */
+ a = chunk_create((u_char*)&(mppe_key->salt), sizeof(mppe_key->salt));
+ do
+ {
+ this->rng->get_bytes(this->rng, a.len, a.ptr);
+ *a.ptr |= 0x80;
+ }
+ while (mppe_key->salt == *salt);
+
+ /* update the salt value */
+ *salt = mppe_key->salt;
+
+ r = chunk_create(request->get_authenticator(request), HASH_SIZE_MD5);
+ seed = chunk_cata("cc", r, a);
+
+ c = mppe_key->key;
+ while (c < data.ptr + data.len)
+ {
+ /* b(i) = MD5(S + c(i-1)) */
+ this->hasher->get_hash(this->hasher, this->secret, NULL);
+ this->hasher->get_hash(this->hasher, seed, b);
+
+ /* c(i) = b(i) xor p(1) */
+ memxor(c, b, HASH_SIZE_MD5);
+
+ /* prepare next round */
+ seed = chunk_create(c, HASH_SIZE_MD5);
+ c += HASH_SIZE_MD5;
+ }
+
+ return data;
+}
+
+/**
+ * Send a RADIUS response for a request
+ */
+static void send_response(private_tnc_pdp_t *this, radius_message_t *request,
+ radius_message_code_t code, eap_payload_t *eap,
+ identification_t *group, chunk_t msk, host_t *client)
+{
+ radius_message_t *response;
+ chunk_t data, recv, send;
+ u_int32_t tunnel_type;
+ u_int16_t salt = 0;
+
+ response = radius_message_create(code);
+ if (eap)
+ {
+ data = eap->get_data(eap);
+ DBG3(DBG_CFG, "%N payload %B", eap_type_names, this->type, &data);
+
+ /* fragment data suitable for RADIUS */
+ while (data.len > MAX_RADIUS_ATTRIBUTE_SIZE)
+ {
+ response->add(response, RAT_EAP_MESSAGE,
+ chunk_create(data.ptr, MAX_RADIUS_ATTRIBUTE_SIZE));
+ data = chunk_skip(data, MAX_RADIUS_ATTRIBUTE_SIZE);
+ }
+ response->add(response, RAT_EAP_MESSAGE, data);
+ }
+ if (group)
+ {
+ tunnel_type = RADIUS_TUNNEL_TYPE_ESP;
+ htoun32(data.ptr, tunnel_type);
+ data.len = sizeof(tunnel_type);
+ response->add(response, RAT_TUNNEL_TYPE, data);
+ response->add(response, RAT_FILTER_ID, group->get_encoding(group));
+ }
+ if (msk.len)
+ {
+ recv = chunk_create(msk.ptr, msk.len / 2);
+ data = encrypt_mppe_key(this, MS_MPPE_RECV_KEY, recv, &salt, request);
+ response->add(response, RAT_VENDOR_SPECIFIC, data);
+ chunk_free(&data);
+
+ send = chunk_create(msk.ptr + recv.len, msk.len - recv.len);
+ data = encrypt_mppe_key(this, MS_MPPE_SEND_KEY, send, &salt, request);
+ response->add(response, RAT_VENDOR_SPECIFIC, data);
+ chunk_free(&data);
+ }
+ response->set_identifier(response, request->get_identifier(request));
+ response->sign(response, request->get_authenticator(request),
+ this->secret, this->hasher, this->signer, NULL, TRUE);
+
+ DBG1(DBG_CFG, "sending RADIUS %N to client '%H'", radius_message_code_names,
+ code, client);
+ send_message(this, response, client);
+ response->destroy(response);
+}
+
+/**
+ * Process EAP message
+ */
+static void process_eap(private_tnc_pdp_t *this, radius_message_t *request,
+ host_t *source)
+{
+ enumerator_t *enumerator;
+ eap_payload_t *in, *out = NULL;
+ eap_method_t *method;
+ eap_type_t eap_type;
+ u_int32_t eap_vendor;
+ chunk_t data, message = chunk_empty, msk = chunk_empty;
+ chunk_t user_name = chunk_empty, nas_id = chunk_empty;
+ identification_t *group = NULL;
+ radius_message_code_t code = RMC_ACCESS_CHALLENGE;
+ int type;
+
+ enumerator = request->create_enumerator(request);
+ while (enumerator->enumerate(enumerator, &type, &data))
+ {
+ switch (type)
+ {
+ case RAT_USER_NAME:
+ user_name = data;
+ break;
+ case RAT_NAS_IDENTIFIER:
+ nas_id = data;
+ break;
+ case RAT_EAP_MESSAGE:
+ if (data.len)
+ {
+ message = chunk_cat("mc", message, data);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (message.len)
+ {
+ in = eap_payload_create_data(message);
+
+ /* apply EAP method selected by RADIUS server */
+ eap_type = in->get_type(in, &eap_vendor);
+
+ DBG3(DBG_CFG, "%N payload %B", eap_type_names, eap_type, &message);
+
+ if (eap_type == EAP_IDENTITY)
+ {
+ identification_t *peer;
+ chunk_t eap_identity;
+
+ if (message.len < 5)
+ {
+ goto end;
+ }
+ eap_identity = chunk_create(message.ptr + 5, message.len - 5);
+ peer = identification_create_from_data(eap_identity);
+ method = charon->eap->create_instance(charon->eap, this->type,
+ 0, EAP_SERVER, this->server, peer);
+ if (!method)
+ {
+ peer->destroy(peer);
+ goto end;
+ }
+ this->connections->add(this->connections, nas_id, user_name, peer,
+ method);
+ method->initiate(method, &out);
+ }
+ else
+ {
+ ike_sa_t *ike_sa;
+ auth_cfg_t *auth;
+ auth_rule_t type;
+ identification_t *data;
+ enumerator_t *e;
+
+ method = this->connections->get_state(this->connections, nas_id,
+ user_name, &ike_sa);
+ if (!method)
+ {
+ goto end;
+ }
+ charon->bus->set_sa(charon->bus, ike_sa);
+
+ switch (method->process(method, in, &out))
+ {
+ case NEED_MORE:
+ code = RMC_ACCESS_CHALLENGE;
+ break;
+ case SUCCESS:
+ code = RMC_ACCESS_ACCEPT;
+ method->get_msk(method, &msk);
+ auth = ike_sa->get_auth_cfg(ike_sa, FALSE);
+ e = auth->create_enumerator(auth);
+ while (e->enumerate(e, &type, &data))
+ {
+ /* look for group memberships */
+ if (type == AUTH_RULE_GROUP)
+ {
+ group = data;
+ }
+ }
+ e->destroy(e);
+
+ DESTROY_IF(out);
+ out = eap_payload_create_code(EAP_SUCCESS,
+ in->get_identifier(in));
+ break;
+ case FAILED:
+ default:
+ code = RMC_ACCESS_REJECT;
+ DESTROY_IF(out);
+ out = eap_payload_create_code(EAP_FAILURE,
+ in->get_identifier(in));
+ }
+ charon->bus->set_sa(charon->bus, NULL);
+ }
+
+ send_response(this, request, code, out, group, msk, source);
+ out->destroy(out);
+
+ if (code == RMC_ACCESS_ACCEPT || code == RMC_ACCESS_REJECT)
+ {
+ this->connections->remove(this->connections, nas_id, user_name);
+ }
+
+end:
+ free(message.ptr);
+ in->destroy(in);
+ }
+}
+
+/**
+ * Process packets received on the RADIUS socket
+ */
+static job_requeue_t receive(private_tnc_pdp_t *this)
+{
+ while (TRUE)
+ {
+ radius_message_t *request;
+ char buffer[MAX_PACKET];
+ int max_fd = 0, selected = 0, bytes_read = 0;
+ fd_set rfds;
+ bool oldstate;
+ host_t *source;
+ struct msghdr msg;
+ struct iovec iov;
+ union {
+ struct sockaddr_in in4;
+ struct sockaddr_in6 in6;
+ } src;
+
+ FD_ZERO(&rfds);
+
+ if (this->ipv4)
+ {
+ FD_SET(this->ipv4, &rfds);
+ }
+ if (this->ipv6)
+ {
+ FD_SET(this->ipv6, &rfds);
+ }
+ max_fd = max(this->ipv4, this->ipv6);
+
+ DBG2(DBG_CFG, "waiting for data on RADIUS sockets");
+ oldstate = thread_cancelability(TRUE);
+ if (select(max_fd + 1, &rfds, NULL, NULL, NULL) <= 0)
+ {
+ thread_cancelability(oldstate);
+ continue;
+ }
+ thread_cancelability(oldstate);
+
+ if (FD_ISSET(this->ipv4, &rfds))
+ {
+ selected = this->ipv4;
+ }
+ else if (FD_ISSET(this->ipv6, &rfds))
+ {
+ selected = this->ipv6;
+ }
+ else
+ {
+ /* oops, shouldn't happen */
+ continue;
+ }
+
+ /* read received packet */
+ msg.msg_name = &src;
+ msg.msg_namelen = sizeof(src);
+ iov.iov_base = buffer;
+ iov.iov_len = MAX_PACKET;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+
+ bytes_read = recvmsg(selected, &msg, 0);
+ if (bytes_read < 0)
+ {
+ DBG1(DBG_CFG, "error reading RADIUS socket: %s", strerror(errno));
+ continue;
+ }
+ if (msg.msg_flags & MSG_TRUNC)
+ {
+ DBG1(DBG_CFG, "receive buffer too small, RADIUS packet discarded");
+ continue;
+ }
+ source = host_create_from_sockaddr((sockaddr_t*)&src);
+ DBG2(DBG_CFG, "received RADIUS packet from %#H", source);
+ DBG3(DBG_CFG, "%b", buffer, bytes_read);
+ request = radius_message_parse(chunk_create(buffer, bytes_read));
+ if (request)
+ {
+ DBG1(DBG_CFG, "received RADIUS %N from client '%H'",
+ radius_message_code_names, request->get_code(request), source);
+
+ if (request->verify(request, NULL, this->secret, this->hasher,
+ this->signer))
+ {
+ process_eap(this, request, source);
+ }
+ request->destroy(request);
+
+ }
+ else
+ {
+ DBG1(DBG_CFG, "received invalid RADIUS message, ignored");
+ }
+ source->destroy(source);
+ }
+ return JOB_REQUEUE_FAIR;
+}
+
+METHOD(tnc_pdp_t, destroy, void,
+ private_tnc_pdp_t *this)
+{
+ if (this->job)
+ {
+ this->job->cancel(this->job);
+ }
+ if (this->ipv4)
+ {
+ close(this->ipv4);
+ }
+ if (this->ipv6)
+ {
+ close(this->ipv6);
+ }
+ DESTROY_IF(this->server);
+ DESTROY_IF(this->signer);
+ DESTROY_IF(this->hasher);
+ DESTROY_IF(this->rng);
+ DESTROY_IF(this->connections);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+tnc_pdp_t *tnc_pdp_create(u_int16_t port)
+{
+ private_tnc_pdp_t *this;
+ char *secret, *server, *eap_type_str;
+
+ INIT(this,
+ .public = {
+ .destroy = _destroy,
+ },
+ .ipv4 = open_socket(AF_INET, port),
+ .ipv6 = open_socket(AF_INET6, port),
+ .hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5),
+ .signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_MD5_128),
+ .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
+ .connections = tnc_pdp_connections_create(),
+ );
+
+ if (!this->hasher || !this->signer || !this->rng)
+ {
+ DBG1(DBG_CFG, "RADIUS initialization failed, HMAC/MD5/RNG required");
+ destroy(this);
+ return NULL;
+ }
+ if (!this->ipv4 && !this->ipv6)
+ {
+ DBG1(DBG_NET, "could not create any RADIUS sockets");
+ destroy(this);
+ return NULL;
+ }
+ if (!this->ipv4)
+ {
+ DBG1(DBG_NET, "could not open IPv4 RADIUS socket, IPv4 disabled");
+ }
+ if (!this->ipv6)
+ {
+ DBG1(DBG_NET, "could not open IPv6 RADIUS socket, IPv6 disabled");
+ }
+
+ server = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-pdp.server", NULL);
+ if (!server)
+ {
+ DBG1(DBG_CFG, "missing PDP server name, PDP disabled");
+ destroy(this);
+ return NULL;
+ }
+ this->server = identification_create_from_string(server);
+
+ secret = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-pdp.secret", NULL);
+ if (!secret)
+ {
+ DBG1(DBG_CFG, "missing RADIUS secret, PDP disabled");
+ destroy(this);
+ return NULL;
+ }
+ this->secret = chunk_create(secret, strlen(secret));
+ this->signer->set_key(this->signer, this->secret);
+
+ eap_type_str = lib->settings->get_str(lib->settings,
+ "charon.plugins.tnc-pdp.method", "ttls");
+ this->type = eap_type_from_string(eap_type_str);
+ if (this->type == 0)
+ {
+ DBG1(DBG_CFG, "unrecognized eap method \"%s\"", eap_type_str);
+ destroy(this);
+ return NULL;
+ }
+ DBG1(DBG_IKE, "eap method %N selected", eap_type_names, this->type);
+
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
+ lib->processor->queue_job(lib->processor, (job_t*)this->job);
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp.h b/src/libcharon/plugins/tnc_pdp/tnc_pdp.h
new file mode 100644
index 000000000..06291220f
--- /dev/null
+++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 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_pdp_t tnc_pdp
+ * @{ @ingroup tnc_pdp
+ */
+
+#ifndef TNC_PDP_H_
+#define TNC_PDP_H_
+
+typedef struct tnc_pdp_t tnc_pdp_t;
+
+#include <library.h>
+
+/**
+ * Public interface of a TNC Policy Decision Point object
+ */
+struct tnc_pdp_t {
+
+ /**
+ * implements plugin interface
+ */
+ void (*destroy)(tnc_pdp_t *this);
+};
+
+/**
+ * Create a TNC PDP instance
+ *
+ * @param port RADIUS port of TNC PDP
+ */
+tnc_pdp_t* tnc_pdp_create(u_int16_t port);
+
+#endif /** TNC_PDP_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c
new file mode 100644
index 000000000..175a57aba
--- /dev/null
+++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2012 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_pdp_connections.h"
+
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_tnc_pdp_connections_t private_tnc_pdp_connections_t;
+typedef struct entry_t entry_t;
+
+/**
+ * Private data of tnc_pdp_connections_t
+ */
+struct private_tnc_pdp_connections_t {
+
+ /**
+ * Implements tnc_pdp_connections_t interface
+ */
+ tnc_pdp_connections_t public;
+
+ /**
+ * List of TNC PEP RADIUS Connections
+ */
+ linked_list_t *list;
+};
+
+/**
+ * Data entry for a TNC PEP RADIUS connection
+ */
+struct entry_t {
+
+ /**
+ * NAS identifier of PEP
+ */
+ chunk_t nas_id;
+
+ /**
+ * User name of TNC Client
+ */
+ chunk_t user_name;
+
+ /**
+ * EAP method state
+ */
+ eap_method_t *method;
+
+ /**
+ * IKE SA used for bus communication
+ */
+ ike_sa_t *ike_sa;
+};
+
+/**
+ * Free the memory allocated to a data entry
+ */
+static void free_entry(entry_t *this)
+{
+ this->method->destroy(this->method);
+ this->ike_sa->destroy(this->ike_sa);
+ free(this->nas_id.ptr);
+ free(this->user_name.ptr);
+ free(this);
+}
+
+/**
+ * Find a matching data entry
+ */
+static bool equals_entry( entry_t *this, chunk_t nas_id, chunk_t user_name)
+{
+ bool no_nas_id = !this->nas_id.ptr && !nas_id.ptr;
+
+ return (chunk_equals(this->nas_id, nas_id) || no_nas_id) &&
+ chunk_equals(this->user_name, user_name);
+}
+
+/**
+ * Find a matching data entry
+ */
+static void dbg_nas_user(chunk_t nas_id, chunk_t user_name, bool not, char *op)
+{
+ if (nas_id.len)
+ {
+ DBG1(DBG_CFG, "%s RADIUS connection for user '%.*s' NAS '%.*s'",
+ not ? "could not find" : op, user_name.len, user_name.ptr,
+ nas_id.len, nas_id.ptr);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "%s RADIUS connection for user '%.*s'",
+ not ? "could not find" : op, user_name.len, user_name.ptr);
+ }
+}
+
+METHOD(tnc_pdp_connections_t, add, void,
+ private_tnc_pdp_connections_t *this, chunk_t nas_id, chunk_t user_name,
+ identification_t *peer, eap_method_t *method)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ ike_sa_id_t *ike_sa_id;
+ ike_sa_t *ike_sa;
+ bool found = FALSE;
+
+ ike_sa_id = ike_sa_id_create(0, 0, FALSE);
+ ike_sa = ike_sa_create(ike_sa_id);
+ ike_sa_id->destroy(ike_sa_id);
+ ike_sa->set_other_id(ike_sa, peer);
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (equals_entry(entry, nas_id, user_name))
+ {
+ found = TRUE;
+ entry->method->destroy(entry->method);
+ entry->ike_sa->destroy(entry->ike_sa);
+ DBG1(DBG_CFG, "removed stale RADIUS connection");
+ entry->method = method;
+ entry->ike_sa = ike_sa;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ entry = malloc_thing(entry_t);
+ entry->nas_id = chunk_clone(nas_id);
+ entry->user_name = chunk_clone(user_name);
+ entry->method = method;
+ entry->ike_sa = ike_sa;
+ this->list->insert_last(this->list, entry);
+ }
+ dbg_nas_user(nas_id, user_name, FALSE, "created");
+}
+
+METHOD(tnc_pdp_connections_t, remove_, void,
+ private_tnc_pdp_connections_t *this, chunk_t nas_id, chunk_t user_name)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (equals_entry(entry, nas_id, user_name))
+ {
+ free_entry(entry);
+ this->list->remove_at(this->list, enumerator);
+ dbg_nas_user(nas_id, user_name, FALSE, "removed");
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(tnc_pdp_connections_t, get_state, eap_method_t*,
+ private_tnc_pdp_connections_t *this, chunk_t nas_id, chunk_t user_name,
+ ike_sa_t **ike_sa)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ eap_method_t *found = NULL;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (equals_entry(entry, nas_id, user_name))
+ {
+ found = entry->method;
+ *ike_sa = entry->ike_sa;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ dbg_nas_user(nas_id, user_name, !found, "found");
+ return found;
+}
+
+METHOD(tnc_pdp_connections_t, destroy, void,
+ private_tnc_pdp_connections_t *this)
+{
+ this->list->destroy_function(this->list, (void*)free_entry);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+tnc_pdp_connections_t *tnc_pdp_connections_create(void)
+{
+ private_tnc_pdp_connections_t *this;
+
+ INIT(this,
+ .public = {
+ .add = _add,
+ .remove = _remove_,
+ .get_state = _get_state,
+ .destroy = _destroy,
+ },
+ .list = linked_list_create(),
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h
new file mode 100644
index 000000000..b9f5d097b
--- /dev/null
+++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp_connections.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2012 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_pdp_connections tnc_pdp_connections
+ * @{ @ingroup tnc_pdp
+ */
+
+#ifndef TNC_PDP_CONNECTIONS_H_
+#define TNC_PDP_CONNECTIONS_H_
+
+typedef struct tnc_pdp_connections_t tnc_pdp_connections_t;
+
+#include <library.h>
+#include <sa/ike_sa.h>
+#include <sa/authenticators/eap/eap_method.h>
+
+/**
+ * Public interface of a tnc_pdp_connections object
+ */
+struct tnc_pdp_connections_t {
+
+ /**
+ * Register a new TNC PEP RADIUS Connection
+ *
+ * @param nas_id NAS identifier of Policy Enforcement Point
+ * @param user_name User name of TNC Client
+ * @param peer Peer identity
+ * @param method EAP method state for this TNC PEP Connection
+ */
+ void (*add)(tnc_pdp_connections_t *this, chunk_t nas_id, chunk_t user_name,
+ identification_t *peer, eap_method_t *method);
+
+ /**
+ * Remove a TNC PEP RADIUS Connection
+ *
+ * @param nas_id NAS identifier of Policy Enforcement Point
+ * @param user_name User name of TNC Client
+ */
+ void (*remove)(tnc_pdp_connections_t *this, chunk_t nas_id,
+ chunk_t user_name);
+
+ /**
+ * Get the EAP method and IKE_SA of a registered TNC PEP RADIUS Connection
+ *
+ * @param nas_id NAS identifier of Policy Enforcement Point
+ * @param user_name User name of TNC Client
+ * @param ike_sa IKE_SA used for bus communication only
+ * @return EAP method for this connection or NULL if not found
+ */
+ eap_method_t* (*get_state)(tnc_pdp_connections_t *this, chunk_t nas_id,
+ chunk_t user_name, ike_sa_t **ike_sa);
+
+ /**
+ * Destroys a tnc_pdp_connections_t object.
+ */
+ void (*destroy)(tnc_pdp_connections_t *this);
+};
+
+/**
+ * Create a tnc_pdp_connections_t instance
+ */
+tnc_pdp_connections_t* tnc_pdp_connections_create(void);
+
+#endif /** TNC_PDP_CONNECTIONS_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.c
new file mode 100644
index 000000000..9abe02aec
--- /dev/null
+++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.c
@@ -0,0 +1,91 @@
+/*
+ * 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_pdp_plugin.h"
+#include "tnc_pdp.h"
+
+typedef struct private_tnc_pdp_plugin_t private_tnc_pdp_plugin_t;
+
+/**
+ * Default RADIUS port, when not configured
+ */
+#define RADIUS_PORT 1812
+
+/**
+ * private data of tnc_pdp plugin
+ */
+struct private_tnc_pdp_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ tnc_pdp_plugin_t public;
+
+ /**
+ * Policy Decision Point object
+ */
+ tnc_pdp_t *pdp;
+
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_tnc_pdp_plugin_t *this)
+{
+ return "tnc-pdp";
+}
+
+METHOD(plugin_t, get_features, int,
+ private_tnc_pdp_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_PROVIDE(CUSTOM, "tnc-pdp"),
+ PLUGIN_DEPENDS(CUSTOM, "imv-manager"),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_tnc_pdp_plugin_t *this)
+{
+ DESTROY_IF(this->pdp);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *tnc_pdp_plugin_create()
+{
+ private_tnc_pdp_plugin_t *this;
+ int port;
+
+ port = lib->settings->get_int(lib->settings,
+ "charon.plugins.tnc_pdp.port", RADIUS_PORT);
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ .pdp = tnc_pdp_create(port),
+ );
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.h b/src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.h
new file mode 100644
index 000000000..9b8b9ff0e
--- /dev/null
+++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 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_pdp tnc_pdp
+ * @ingroup cplugins
+ *
+ * @defgroup tnc_pdp_plugin tnc_pdp_plugin
+ * @{ @ingroup tnc_pdp
+ */
+
+#ifndef TNC_PDP_PLUGIN_H_
+#define TNC_PDP_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct tnc_pdp_plugin_t tnc_pdp_plugin_t;
+
+/**
+ * TNC-PDP plugin
+ */
+struct tnc_pdp_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** TNC_PDP_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_tnccs/Makefile.am b/src/libcharon/plugins/tnc_tnccs/Makefile.am
new file mode 100644
index 000000000..c7fc02f7c
--- /dev/null
+++ b/src/libcharon/plugins/tnc_tnccs/Makefile.am
@@ -0,0 +1,22 @@
+
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-tnc-tnccs.la
+else
+plugin_LTLIBRARIES = libstrongswan-tnc-tnccs.la
+libstrongswan_tnc_tnccs_la_LIBADD = \
+ $(top_builddir)/src/libtncif/libtncif.la \
+ $(top_builddir)/src/libtnccs/libtnccs.la
+endif
+
+libstrongswan_tnc_tnccs_la_SOURCES = \
+ tnc_tnccs_plugin.h tnc_tnccs_plugin.c \
+ tnc_tnccs_manager.h tnc_tnccs_manager.c
+
+libstrongswan_tnc_tnccs_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/tnc_tnccs/Makefile.in b/src/libcharon/plugins/tnc_tnccs/Makefile.in
new file mode 100644
index 000000000..c12a837d1
--- /dev/null
+++ b/src/libcharon/plugins/tnc_tnccs/Makefile.in
@@ -0,0 +1,624 @@
+# 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/tnc_tnccs
+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_tnc_tnccs_la_DEPENDENCIES = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+am_libstrongswan_tnc_tnccs_la_OBJECTS = tnc_tnccs_plugin.lo \
+ tnc_tnccs_manager.lo
+libstrongswan_tnc_tnccs_la_OBJECTS = \
+ $(am_libstrongswan_tnc_tnccs_la_OBJECTS)
+libstrongswan_tnc_tnccs_la_LINK = $(LIBTOOL) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_tnc_tnccs_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_tnc_tnccs_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_tnc_tnccs_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_tnc_tnccs_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_tnc_tnccs_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libtncif \
+ -I$(top_srcdir)/src/libtnccs
+
+AM_CFLAGS = -rdynamic
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnc-tnccs.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnc-tnccs.la
+@MONOLITHIC_FALSE@libstrongswan_tnc_tnccs_la_LIBADD = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+
+libstrongswan_tnc_tnccs_la_SOURCES = \
+ tnc_tnccs_plugin.h tnc_tnccs_plugin.c \
+ tnc_tnccs_manager.h tnc_tnccs_manager.c
+
+libstrongswan_tnc_tnccs_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/tnc_tnccs/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libcharon/plugins/tnc_tnccs/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-tnc-tnccs.la: $(libstrongswan_tnc_tnccs_la_OBJECTS) $(libstrongswan_tnc_tnccs_la_DEPENDENCIES)
+ $(libstrongswan_tnc_tnccs_la_LINK) $(am_libstrongswan_tnc_tnccs_la_rpath) $(libstrongswan_tnc_tnccs_la_OBJECTS) $(libstrongswan_tnc_tnccs_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_tnccs_manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc_tnccs_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/tnc/tnccs/tnccs_manager.c b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.c
index 609742dc8..64ed160d9 100644
--- a/src/libcharon/tnc/tnccs/tnccs_manager.c
+++ b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.c
@@ -13,16 +13,18 @@
* for more details.
*/
-#include "tnccs_manager.h"
+#include "tnc_tnccs_manager.h"
-#include <tnc/imv/imv_recommendations.h>
+#include <tnc/tnc.h>
+#include <tnc/imv/imv_manager.h>
+#include <tnc/imc/imc_manager.h>
+#include <tnc/imv/imv_manager.h>
#include <debug.h>
-#include <daemon.h>
#include <utils/linked_list.h>
#include <threading/rwlock.h>
-typedef struct private_tnccs_manager_t private_tnccs_manager_t;
+typedef struct private_tnc_tnccs_manager_t private_tnc_tnccs_manager_t;
typedef struct tnccs_entry_t tnccs_entry_t;
typedef struct tnccs_connection_entry_t tnccs_connection_entry_t;
@@ -53,6 +55,11 @@ struct tnccs_connection_entry_t {
TNC_ConnectionID id;
/**
+ * TNCCS protocol type
+ */
+ tnccs_type_t type;
+
+ /**
* TNCCS instance
*/
tnccs_t *tnccs;
@@ -74,9 +81,9 @@ struct tnccs_connection_entry_t {
};
/**
- * private data of tnccs_manager
+ * private data of tnc_tnccs_manager
*/
-struct private_tnccs_manager_t {
+struct private_tnc_tnccs_manager_t {
/**
* public functions
@@ -111,7 +118,7 @@ struct private_tnccs_manager_t {
};
METHOD(tnccs_manager_t, add_method, void,
- private_tnccs_manager_t *this, tnccs_type_t type,
+ private_tnc_tnccs_manager_t *this, tnccs_type_t type,
tnccs_constructor_t constructor)
{
tnccs_entry_t *entry;
@@ -126,7 +133,7 @@ METHOD(tnccs_manager_t, add_method, void,
}
METHOD(tnccs_manager_t, remove_method, void,
- private_tnccs_manager_t *this, tnccs_constructor_t constructor)
+ private_tnc_tnccs_manager_t *this, tnccs_constructor_t constructor)
{
enumerator_t *enumerator;
tnccs_entry_t *entry;
@@ -146,7 +153,7 @@ METHOD(tnccs_manager_t, remove_method, void,
}
METHOD(tnccs_manager_t, create_instance, tnccs_t*,
- private_tnccs_manager_t *this, tnccs_type_t type, bool is_server)
+ private_tnc_tnccs_manager_t *this, tnccs_type_t type, bool is_server)
{
enumerator_t *enumerator;
tnccs_entry_t *entry;
@@ -172,32 +179,33 @@ METHOD(tnccs_manager_t, create_instance, tnccs_t*,
}
METHOD(tnccs_manager_t, create_connection, TNC_ConnectionID,
- private_tnccs_manager_t *this, tnccs_t *tnccs,
+ private_tnc_tnccs_manager_t *this, tnccs_type_t type, tnccs_t *tnccs,
tnccs_send_message_t send_message, bool* request_handshake_retry,
recommendations_t **recs)
{
tnccs_connection_entry_t *entry;
entry = malloc_thing(tnccs_connection_entry_t);
+ entry->type = type;
entry->tnccs = tnccs;
entry->send_message = send_message;
entry->request_handshake_retry = request_handshake_retry;
if (recs)
{
/* we assume a TNC Server needing recommendations from IMVs */
- if (!charon->imvs)
+ if (!tnc->imvs)
{
- DBG1(DBG_TNC, "no IMV manager available!");
+ DBG1(DBG_TNC, "no IMV manager available!");
free(entry);
return 0;
}
- entry->recs = charon->imvs->create_recommendations(charon->imvs);
+ entry->recs = tnc->imvs->create_recommendations(tnc->imvs);
*recs = entry->recs;
}
else
{
/* we assume a TNC Client */
- if (!charon->imcs)
+ if (!tnc->imcs)
{
DBG1(DBG_TNC, "no IMC manager available!");
free(entry);
@@ -215,24 +223,24 @@ METHOD(tnccs_manager_t, create_connection, TNC_ConnectionID,
}
METHOD(tnccs_manager_t, remove_connection, void,
- private_tnccs_manager_t *this, TNC_ConnectionID id, bool is_server)
+ private_tnc_tnccs_manager_t *this, TNC_ConnectionID id, bool is_server)
{
enumerator_t *enumerator;
tnccs_connection_entry_t *entry;
if (is_server)
{
- if (charon->imvs)
+ if (tnc->imvs)
{
- charon->imvs->notify_connection_change(charon->imvs, id,
+ tnc->imvs->notify_connection_change(tnc->imvs, id,
TNC_CONNECTION_STATE_DELETE);
}
}
else
{
- if (charon->imcs)
+ if (tnc->imcs)
{
- charon->imcs->notify_connection_change(charon->imcs, id,
+ tnc->imcs->notify_connection_change(tnc->imcs, id,
TNC_CONNECTION_STATE_DELETE);
}
}
@@ -257,9 +265,9 @@ METHOD(tnccs_manager_t, remove_connection, void,
}
METHOD(tnccs_manager_t, request_handshake_retry, TNC_Result,
- private_tnccs_manager_t *this, bool is_imc, TNC_UInt32 imcv_id,
- TNC_ConnectionID id,
- TNC_RetryReason reason)
+ private_tnc_tnccs_manager_t *this, bool is_imc, TNC_UInt32 imcv_id,
+ TNC_ConnectionID id,
+ TNC_RetryReason reason)
{
enumerator_t *enumerator;
tnccs_connection_entry_t *entry;
@@ -291,26 +299,24 @@ METHOD(tnccs_manager_t, request_handshake_retry, TNC_Result,
}
METHOD(tnccs_manager_t, send_message, TNC_Result,
- private_tnccs_manager_t *this, TNC_IMCID imc_id, TNC_IMVID imv_id,
- TNC_ConnectionID id,
- TNC_BufferReference msg,
- TNC_UInt32 msg_len,
- TNC_MessageType msg_type)
+ private_tnc_tnccs_manager_t *this, TNC_IMCID imc_id, TNC_IMVID imv_id,
+ TNC_ConnectionID id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype)
{
enumerator_t *enumerator;
tnccs_connection_entry_t *entry;
tnccs_send_message_t send_message = NULL;
tnccs_t *tnccs = NULL;
- TNC_VendorID msg_vid;
- TNC_MessageSubtype msg_subtype;
-
- msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY;
- msg_subtype = msg_type & TNC_SUBTYPE_ANY;
if (msg_vid == TNC_VENDORID_ANY || msg_subtype == TNC_SUBTYPE_ANY)
{
- DBG1(DBG_TNC, "not sending message of invalid type 0x%08x", msg_type);
+ DBG1(DBG_TNC, "not sending message of invalid type 0x%02x/0x%08x",
+ msg_vid, msg_subtype);
return TNC_RESULT_INVALID_PARAMETER;
}
@@ -330,16 +336,17 @@ METHOD(tnccs_manager_t, send_message, TNC_Result,
if (tnccs && send_message)
{
- return send_message(tnccs, imc_id, imv_id, msg, msg_len, msg_type);
+ return send_message(tnccs, imc_id, imv_id, msg_flags, msg, msg_len,
+ msg_vid, msg_subtype);
}
return TNC_RESULT_FATAL;
}
METHOD(tnccs_manager_t, provide_recommendation, TNC_Result,
- private_tnccs_manager_t *this, TNC_IMVID imv_id,
- TNC_ConnectionID id,
- TNC_IMV_Action_Recommendation rec,
- TNC_IMV_Evaluation_Result eval)
+ private_tnc_tnccs_manager_t *this, TNC_IMVID imv_id,
+ TNC_ConnectionID id,
+ TNC_IMV_Action_Recommendation rec,
+ TNC_IMV_Evaluation_Result eval)
{
enumerator_t *enumerator;
tnccs_connection_entry_t *entry;
@@ -366,20 +373,150 @@ METHOD(tnccs_manager_t, provide_recommendation, TNC_Result,
return TNC_RESULT_FATAL;
}
+/**
+ * Write the value of a boolean attribute into the buffer
+ */
+static TNC_Result bool_attribute(TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer,
+ TNC_UInt32 *value_len,
+ bool value)
+{
+ *value_len = 1;
+
+ if (buffer && buffer_len > 0)
+ {
+ *buffer = value ? 0x01 : 0x00;
+ return TNC_RESULT_SUCCESS;
+ }
+ else
+ {
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+}
+
+/**
+ * Write the value of an u_int32_t attribute into the buffer
+ */
+static TNC_Result uint_attribute(TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer,
+ TNC_UInt32 *value_len,
+ u_int32_t value)
+{
+ *value_len = sizeof(u_int32_t);
+
+ if (buffer && buffer_len >= *value_len)
+ {
+ htoun32(buffer, value);
+ return TNC_RESULT_SUCCESS;
+ }
+ else
+ {
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+}
+
+/**
+ * Write the value of string attribute into the buffer
+ */
+static TNC_Result str_attribute(TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer,
+ TNC_UInt32 *value_len,
+ char *value)
+{
+ *value_len = 1 + strlen(value);
+
+ if (buffer && buffer_len >= *value_len)
+ {
+ snprintf(buffer, buffer_len, "%s", value);
+ return TNC_RESULT_SUCCESS;
+ }
+ else
+ {
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+}
+
METHOD(tnccs_manager_t, get_attribute, TNC_Result,
- private_tnccs_manager_t *this, TNC_IMVID imv_id,
- TNC_ConnectionID id,
- TNC_AttributeID attribute_id,
- TNC_UInt32 buffer_len,
- TNC_BufferReference buffer,
- TNC_UInt32 *out_value_len)
+ private_tnc_tnccs_manager_t *this, bool is_imc,
+ TNC_UInt32 imcv_id,
+ TNC_ConnectionID id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer,
+ TNC_UInt32 *value_len)
{
enumerator_t *enumerator;
tnccs_connection_entry_t *entry;
- recommendations_t *recs = NULL;
+ bool attribute_match = FALSE, entry_found = FALSE;
+
+ if (is_imc)
+ {
+ switch (attribute_id)
+ {
+ /* these attributes are unsupported */
+ case TNC_ATTRIBUTEID_SOHR:
+ case TNC_ATTRIBUTEID_SSOHR:
+ return TNC_RESULT_INVALID_PARAMETER;
+
+ /* these attributes are supported */
+ case TNC_ATTRIBUTEID_PRIMARY_IMC_ID:
+ attribute_match = TRUE;
+ break;
+
+ /* these attributes are yet to be matched */
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch (attribute_id)
+ {
+ /* these attributes are unsupported or invalid */
+ case TNC_ATTRIBUTEID_REASON_STRING:
+ case TNC_ATTRIBUTEID_REASON_LANGUAGE:
+ case TNC_ATTRIBUTEID_SOH:
+ case TNC_ATTRIBUTEID_SSOH:
+ return TNC_RESULT_INVALID_PARAMETER;
+
+ /* these attributes are supported */
+ case TNC_ATTRIBUTEID_PRIMARY_IMV_ID:
+ attribute_match = TRUE;
+ break;
+
+ /* these attributes are yet to be matched */
+ default:
+ break;
+ }
+ }
+
+ if (!attribute_match)
+ {
+ switch (attribute_id)
+ {
+ /* these attributes are supported */
+ case TNC_ATTRIBUTEID_PREFERRED_LANGUAGE:
+ case TNC_ATTRIBUTEID_MAX_ROUND_TRIPS:
+ case TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE:
+ case TNC_ATTRIBUTEID_HAS_LONG_TYPES:
+ case TNC_ATTRIBUTEID_HAS_EXCLUSIVE:
+ case TNC_ATTRIBUTEID_HAS_SOH:
+ case TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL:
+ case TNC_ATTRIBUTEID_IFTNCCS_VERSION:
+ case TNC_ATTRIBUTEID_IFT_PROTOCOL:
+ case TNC_ATTRIBUTEID_IFT_VERSION:
+ break;
- if (id == TNC_CONNECTIONID_ANY ||
- attribute_id != TNC_ATTRIBUTEID_PREFERRED_LANGUAGE)
+ /* these attributes are unsupported or unknown */
+ case TNC_ATTRIBUTEID_DHPN:
+ case TNC_ATTRIBUTEID_TLS_UNIQUE:
+ default:
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ }
+
+ /* attributes specific to the TNCC or TNCS are unsupported */
+ if (id == TNC_CONNECTIONID_ANY)
{
return TNC_RESULT_INVALID_PARAMETER;
}
@@ -390,44 +527,114 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result,
{
if (id == entry->id)
{
- recs = entry->recs;
+ entry_found = TRUE;
break;
}
}
enumerator->destroy(enumerator);
this->connection_lock->unlock(this->connection_lock);
- if (recs)
+ if (!entry_found)
{
- chunk_t pref_lang;
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
- pref_lang = recs->get_preferred_language(recs);
- if (pref_lang.len == 0)
+ switch (attribute_id)
+ {
+ case TNC_ATTRIBUTEID_PREFERRED_LANGUAGE:
{
- return TNC_RESULT_INVALID_PARAMETER;
+ recommendations_t *recs;
+ chunk_t pref_lang;
+
+ recs = entry->recs;
+ if (!recs)
+ {
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ pref_lang = recs->get_preferred_language(recs);
+ if (pref_lang.len == 0)
+ {
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ *value_len = pref_lang.len;
+ if (buffer && buffer_len >= pref_lang.len)
+ {
+ memcpy(buffer, pref_lang.ptr, pref_lang.len);
+ }
+ return TNC_RESULT_SUCCESS;
}
- *out_value_len = pref_lang.len;
- if (buffer && buffer_len <= pref_lang.len)
+ case TNC_ATTRIBUTEID_MAX_ROUND_TRIPS:
+ return uint_attribute(buffer_len, buffer, value_len, 0xffffffff);
+ case TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE:
+ return uint_attribute(buffer_len, buffer, value_len, 0x00000000);
+ case TNC_ATTRIBUTEID_HAS_LONG_TYPES:
+ case TNC_ATTRIBUTEID_HAS_EXCLUSIVE:
+ return bool_attribute(buffer_len, buffer, value_len,
+ entry->type == TNCCS_2_0);
+ case TNC_ATTRIBUTEID_HAS_SOH:
+ return bool_attribute(buffer_len, buffer, value_len,
+ entry->type == TNCCS_SOH);
+ case TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL:
{
- memcpy(buffer, pref_lang.ptr, pref_lang.len);
+ char *protocol;
+
+ switch (entry->type)
+ {
+ case TNCCS_1_1:
+ case TNCCS_2_0:
+ protocol = "IF-TNCCS";
+ break;
+ case TNCCS_SOH:
+ protocol = "IF-TNCCS-SOH";
+ break;
+ default:
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return str_attribute(buffer_len, buffer, value_len, protocol);
}
- return TNC_RESULT_SUCCESS;
+ case TNC_ATTRIBUTEID_IFTNCCS_VERSION:
+ {
+ char *version;
+
+ switch (entry->type)
+ {
+ case TNCCS_1_1:
+ version = "1.1";
+ break;
+ case TNCCS_2_0:
+ version = "2.0";
+ break;
+ case TNCCS_SOH:
+ version = "1.0";
+ break;
+ default:
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return str_attribute(buffer_len, buffer, value_len, version);
+ }
+ case TNC_ATTRIBUTEID_IFT_PROTOCOL:
+ return str_attribute(buffer_len, buffer, value_len,
+ "IF-T for Tunneled EAP");
+ case TNC_ATTRIBUTEID_IFT_VERSION:
+ return str_attribute(buffer_len, buffer, value_len, "1.1");
+ default:
+ return TNC_RESULT_INVALID_PARAMETER;
}
- return TNC_RESULT_INVALID_PARAMETER;
}
METHOD(tnccs_manager_t, set_attribute, TNC_Result,
- private_tnccs_manager_t *this, TNC_IMVID imv_id,
- TNC_ConnectionID id,
- TNC_AttributeID attribute_id,
- TNC_UInt32 buffer_len,
- TNC_BufferReference buffer)
+ private_tnc_tnccs_manager_t *this, bool is_imc,
+ TNC_UInt32 imcv_id,
+ TNC_ConnectionID id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer)
{
enumerator_t *enumerator;
tnccs_connection_entry_t *entry;
recommendations_t *recs = NULL;
- if (id == TNC_CONNECTIONID_ANY ||
+ if (is_imc || id == TNC_CONNECTIONID_ANY ||
(attribute_id != TNC_ATTRIBUTEID_REASON_STRING &&
attribute_id != TNC_ATTRIBUTEID_REASON_LANGUAGE))
{
@@ -453,18 +660,18 @@ METHOD(tnccs_manager_t, set_attribute, TNC_Result,
if (attribute_id == TNC_ATTRIBUTEID_REASON_STRING)
{
- return recs->set_reason_string(recs, imv_id, attribute);
+ return recs->set_reason_string(recs, imcv_id, attribute);
}
else
{
- return recs->set_reason_language(recs, imv_id, attribute);
+ return recs->set_reason_language(recs, imcv_id, attribute);
}
}
return TNC_RESULT_INVALID_PARAMETER;
}
METHOD(tnccs_manager_t, destroy, void,
- private_tnccs_manager_t *this)
+ private_tnc_tnccs_manager_t *this)
{
this->protocols->destroy_function(this->protocols, free);
this->protocol_lock->destroy(this->protocol_lock);
@@ -476,9 +683,9 @@ METHOD(tnccs_manager_t, destroy, void,
/*
* See header
*/
-tnccs_manager_t *tnccs_manager_create()
+tnccs_manager_t *tnc_tnccs_manager_create()
{
- private_tnccs_manager_t *this;
+ private_tnc_tnccs_manager_t *this;
INIT(this,
.public = {
diff --git a/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.h b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.h
new file mode 100644
index 000000000..dd5149846
--- /dev/null
+++ b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.h
@@ -0,0 +1,31 @@
+/*
+ * 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_tnccs_manager tnc_tnccs_manager
+ * @{ @ingroup tnc_tnccs
+ */
+
+#ifndef TNC_TNCCS_MANAGER_H_
+#define TNC_TNCCS_MANAGER_H_
+
+#include <tnc/tnccs/tnccs_manager.h>
+
+/**
+ * Create a TNCCS manager instance.
+ */
+tnccs_manager_t *tnc_tnccs_manager_create();
+
+#endif /** TNC_TNCCS_MANAGER_H_ @}*/
diff --git a/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.c b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.c
new file mode 100644
index 000000000..a44319ed1
--- /dev/null
+++ b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.c
@@ -0,0 +1,98 @@
+/*
+ * 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_tnccs_plugin.h"
+#include "tnc_tnccs_manager.h"
+
+#include <tnc/tnc.h>
+
+#include <debug.h>
+
+typedef struct private_tnc_tnccs_plugin_t private_tnc_tnccs_plugin_t;
+
+/**
+ * Private data of a tnc_tnccs_plugin_t object.
+ */
+struct private_tnc_tnccs_plugin_t {
+
+ /**
+ * Public interface.
+ */
+ tnc_tnccs_plugin_t public;
+
+};
+
+
+METHOD(plugin_t, get_name, char*,
+ private_tnc_tnccs_plugin_t *this)
+{
+ return "tnc-tnccs";
+}
+
+METHOD(plugin_t, get_features, int,
+ private_tnc_tnccs_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(tnc_manager_register, tnc_tnccs_manager_create),
+ PLUGIN_PROVIDE(CUSTOM, "tnccs-manager"),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_tnc_tnccs_plugin_t *this)
+{
+ libtnccs_deinit();
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *tnc_tnccs_plugin_create(void)
+{
+ private_tnc_tnccs_plugin_t *this;
+
+ if (lib->integrity)
+ {
+ if (lib->integrity->check(lib->integrity, "libtnccs", libtnccs_init))
+ {
+ DBG1(DBG_LIB,
+ "lib 'libtnccs': passed file and segment integrity tests");
+ }
+ else
+ {
+ DBG1(DBG_LIB,
+ "lib 'libtnccs': failed integrity tests");
+ return NULL;
+ }
+ }
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ );
+
+ libtnccs_init();
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.h b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_plugin.h
new file mode 100644
index 000000000..f935fa462
--- /dev/null
+++ b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_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_tnccs tnc_tnccs
+ * @ingroup cplugins
+ *
+ * @defgroup tnc_tnccs_plugin tnc_tnccs_plugin
+ * @{ @ingroup tnc_tnccs
+ */
+
+#ifndef TNC_TNCCS_PLUGIN_H_
+#define TNC_TNCCS_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct tnc_tnccs_plugin_t tnc_tnccs_plugin_t;
+
+/**
+ * TNCCS manager plugin
+ */
+struct tnc_tnccs_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** TNC_TNCCS_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/tnccs_11/Makefile.am b/src/libcharon/plugins/tnccs_11/Makefile.am
index 1042c3514..c205692d4 100644
--- a/src/libcharon/plugins/tnccs_11/Makefile.am
+++ b/src/libcharon/plugins/tnccs_11/Makefile.am
@@ -1,6 +1,10 @@
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls ${xml_CFLAGS}
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs \
+ ${xml_CFLAGS}
AM_CFLAGS = -rdynamic
@@ -10,6 +14,9 @@ if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-tnccs-11.la
else
plugin_LTLIBRARIES = libstrongswan-tnccs-11.la
+libstrongswan_tnccs_11_la_LIBADD += \
+ $(top_builddir)/src/libtncif/libtncif.la \
+ $(top_builddir)/src/libtnccs/libtnccs.la
endif
libstrongswan_tnccs_11_la_SOURCES = \
diff --git a/src/libcharon/plugins/tnccs_11/Makefile.in b/src/libcharon/plugins/tnccs_11/Makefile.in
index 308dd57ca..1902d1f93 100644
--- a/src/libcharon/plugins/tnccs_11/Makefile.in
+++ b/src/libcharon/plugins/tnccs_11/Makefile.in
@@ -34,6 +34,10 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@MONOLITHIC_FALSE@am__append_1 = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+
subdir = src/libcharon/plugins/tnccs_11
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -75,7 +79,8 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
am__DEPENDENCIES_1 =
-libstrongswan_tnccs_11_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+libstrongswan_tnccs_11_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__append_1)
am_libstrongswan_tnccs_11_la_OBJECTS = tnccs_11_plugin.lo tnccs_11.lo \
tnccs_batch.lo tnccs_msg.lo imc_imv_msg.lo tnccs_error_msg.lo \
tnccs_preferred_language_msg.lo tnccs_reason_strings_msg.lo \
@@ -198,6 +203,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -206,6 +214,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -222,11 +231,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -270,6 +281,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -280,11 +292,15 @@ 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 ${xml_CFLAGS}
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs \
+ ${xml_CFLAGS}
AM_CFLAGS = -rdynamic
-libstrongswan_tnccs_11_la_LIBADD = ${xml_LIBS}
+libstrongswan_tnccs_11_la_LIBADD = ${xml_LIBS} $(am__append_1)
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-11.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-11.la
libstrongswan_tnccs_11_la_SOURCES = \
diff --git a/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c
index 0f6f3a675..c9397722b 100644
--- a/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c
+++ b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c
@@ -16,10 +16,11 @@
#include "tnccs_batch.h"
#include "messages/tnccs_error_msg.h"
-#include <debug.h>
-#include <utils/linked_list.h>
#include <tnc/tnccs/tnccs.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
#include <libxml/parser.h>
typedef struct private_tnccs_batch_t private_tnccs_batch_t;
diff --git a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c
index f24c0dac9..fa570aae9 100644
--- a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c
+++ b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c
@@ -16,8 +16,9 @@
#include "imc_imv_msg.h"
#include <tnc/tnccs/tnccs.h>
-#include <debug.h>
+
#include <utils/lexparser.h>
+#include <debug.h>
typedef struct private_imc_imv_msg_t private_imc_imv_msg_t;
diff --git a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h
index 02f07199f..3477fa74e 100644
--- a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h
+++ b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h
@@ -25,7 +25,7 @@ typedef struct imc_imv_msg_t imc_imv_msg_t;
#include "tnccs_msg.h"
-#include <tnc/tncif.h>
+#include <tncif.h>
/**
* Classs representing the PB-PA message type.
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h
index d301ab2bb..c2de7fe4d 100644
--- a/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h
@@ -25,7 +25,7 @@ typedef struct tnccs_preferred_language_msg_t tnccs_preferred_language_msg_t;
#include "tnccs_msg.h"
-#include <tnc/tncif.h>
+#include <tncif.h>
/**
* Class representing the TNCCS-PreferredLanguage message type
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c
index d4b5d9bf9..af60a4b3a 100644
--- a/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c
@@ -14,6 +14,7 @@
*/
#include "tnccs_reason_strings_msg.h"
+#include "tnccs_error_msg.h"
#include <debug.h>
@@ -85,6 +86,10 @@ tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node,
linked_list_t *errors)
{
private_tnccs_reason_strings_msg_t *this;
+ char *error_msg, *lang_string, *reason_string;
+ tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH;
+ tnccs_msg_t *msg;
+ xmlNodePtr child;
INIT(this,
.public = {
@@ -99,7 +104,45 @@ tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node,
.node = node,
);
+ if (xmlStrcmp(node->name, (const xmlChar*)"TNCCS-ReasonStrings"))
+ {
+ error_msg = "TNCCS-ReasonStrings tag expected";
+ goto fatal;
+ }
+
+ child = node->xmlChildrenNode;
+ while (child)
+ {
+ if (xmlIsBlankNode(child))
+ {
+ child = child->next;
+ continue;
+ }
+ if (xmlStrcmp(child->name, (const xmlChar*)"ReasonString"))
+ {
+ error_msg = "ReasonString tag expected";
+ goto fatal;
+ }
+ break;
+ }
+
+ lang_string = (char*)xmlGetProp(child, (const xmlChar*)"lang");
+ if (!lang_string)
+ {
+ lang_string = "";
+ }
+ this->language = chunk_create(strdup(lang_string), strlen(lang_string));
+
+ reason_string = (char*)xmlNodeGetContent(child);
+ this->reason = chunk_create(strdup(reason_string), strlen(reason_string));
+
return &this->public.tnccs_msg_interface;
+
+fatal:
+ msg = tnccs_error_msg_create(error_type, error_msg);
+ errors->insert_last(errors, msg);
+ destroy(this);
+ return NULL;
}
/**
@@ -140,10 +183,12 @@ tnccs_msg_t *tnccs_reason_strings_msg_create(chunk_t reason, chunk_t language)
n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type));
/* could add multiple reasons here, if we had them */
+
n3 = xmlNewNode(NULL, BAD_CAST "ReasonString");
xmlNewProp(n3, BAD_CAST "xml:lang", BAD_CAST this->language.ptr);
xmlNodeSetContent(n3, BAD_CAST this->reason.ptr);
xmlAddChild(n2, n3);
+ xmlAddChild(n, n2);
return &this->public.tnccs_msg_interface;
}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c
index adc7b54b9..610224242 100644
--- a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c
@@ -128,7 +128,7 @@ tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node,
fatal:
msg = tnccs_error_msg_create(error_type, error_msg);
errors->insert_last(errors, msg);
- _destroy(this);
+ destroy(this);
return NULL;
}
diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h
index 685049e95..3a67a3b32 100644
--- a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h
+++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h
@@ -25,7 +25,7 @@ typedef struct tnccs_recommendation_msg_t tnccs_recommendation_msg_t;
#include "tnccs_msg.h"
-#include <tnc/tncifimv.h>
+#include <tncifimv.h>
/**
* Class representing the TNCCS-Recommendation message type
diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11.c b/src/libcharon/plugins/tnccs_11/tnccs_11.c
index 86f1c269f..3673221e5 100644
--- a/src/libcharon/plugins/tnccs_11/tnccs_11.c
+++ b/src/libcharon/plugins/tnccs_11/tnccs_11.c
@@ -22,12 +22,17 @@
#include "messages/tnccs_reason_strings_msg.h"
#include "messages/tnccs_recommendation_msg.h"
-#include <daemon.h>
+#include <tncif_names.h>
+#include <tncif_pa_subtypes.h>
+
+#include <tnc/tnc.h>
+#include <tnc/imc/imc_manager.h>
+#include <tnc/imv/imv_manager.h>
+#include <tnc/tnccs/tnccs.h>
+#include <tnc/tnccs/tnccs_manager.h>
+
#include <debug.h>
#include <threading/mutex.h>
-#include <tnc/tncif.h>
-#include <tnc/tncifimv.h>
-#include <tnc/tnccs/tnccs.h>
typedef struct private_tnccs_11_t private_tnccs_11_t;
@@ -90,15 +95,20 @@ struct private_tnccs_11_t {
* Set of IMV recommendations (TNC Server only)
*/
recommendations_t *recs;
+
};
METHOD(tnccs_t, send_msg, TNC_Result,
private_tnccs_11_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
+ TNC_UInt32 msg_flags,
TNC_BufferReference msg,
TNC_UInt32 msg_len,
- TNC_MessageType msg_type)
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype)
{
tnccs_msg_t *tnccs_msg;
+ TNC_MessageType msg_type;
+ enum_name_t *pa_subtype_names;
if (!this->send_msg)
{
@@ -107,6 +117,24 @@ METHOD(tnccs_t, send_msg, TNC_Result,
this->is_server ? imv_id : imc_id);
return TNC_RESULT_ILLEGAL_OPERATION;
}
+ if (msg_vid > TNC_VENDORID_ANY || msg_subtype > TNC_SUBTYPE_ANY)
+ {
+ return TNC_RESULT_NO_LONG_MESSAGE_TYPES;
+ }
+ msg_type = (msg_vid << 8) | msg_subtype;
+
+ pa_subtype_names = get_pa_subtype_names(msg_vid);
+ if (pa_subtype_names)
+ {
+ DBG2(DBG_TNC, "creating IMC-IMV message type '%N/%N' 0x%06x/0x%02x",
+ pen_names, msg_vid, pa_subtype_names, msg_subtype,
+ msg_vid, msg_subtype);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "creating IMC-IMV message type '%N' 0x%06x/0x%02x",
+ pen_names, msg_vid, msg_vid, msg_subtype);
+ }
tnccs_msg = imc_imv_msg_create(msg_type, chunk_create(msg, msg_len));
/* adding an IMC-IMV Message to TNCCS batch */
@@ -132,23 +160,40 @@ static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg)
imc_imv_msg_t *imc_imv_msg;
TNC_MessageType msg_type;
chunk_t msg_body;
+ u_int32_t msg_vid, msg_subtype;
+ enum_name_t *pa_subtype_names;
imc_imv_msg = (imc_imv_msg_t*)msg;
msg_type = imc_imv_msg->get_msg_type(imc_imv_msg);
msg_body = imc_imv_msg->get_msg_body(imc_imv_msg);
+ msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY;
+ msg_subtype = msg_type & TNC_SUBTYPE_ANY;
- DBG2(DBG_TNC, "handling IMC_IMV message type 0x%08x", msg_type);
+ pa_subtype_names = get_pa_subtype_names(msg_vid);
+ if (pa_subtype_names)
+ {
+ DBG2(DBG_TNC, "handling IMC-IMV message type '%N/%N' 0x%06x/0x%02x",
+ pen_names, msg_vid, pa_subtype_names, msg_subtype,
+ msg_vid, msg_subtype);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "handling IMC-IMV message type '%N' 0x%06x/0x%02x",
+ pen_names, msg_vid, msg_vid, msg_subtype);
+ }
this->send_msg = TRUE;
if (this->is_server)
{
- charon->imvs->receive_message(charon->imvs,
- this->connection_id, msg_body.ptr, msg_body.len, msg_type);
+ tnc->imvs->receive_message(tnc->imvs, this->connection_id,
+ FALSE, msg_body.ptr, msg_body.len,
+ msg_vid, msg_subtype, 0, TNC_IMVID_ANY);
}
else
{
- charon->imcs->receive_message(charon->imcs,
- this->connection_id, msg_body.ptr, msg_body.len,msg_type);
+ tnc->imcs->receive_message(tnc->imcs, this->connection_id,
+ FALSE, msg_body.ptr, msg_body.len,
+ msg_vid, msg_subtype, 0, TNC_IMCID_ANY);
}
this->send_msg = FALSE;
break;
@@ -181,8 +226,8 @@ static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg)
default:
state = TNC_CONNECTION_STATE_ACCESS_NONE;
}
- charon->imcs->notify_connection_change(charon->imcs,
- this->connection_id, state);
+ tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+ state);
this->delete_state = TRUE;
break;
}
@@ -221,9 +266,9 @@ static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg)
reason_msg = (tnccs_reason_strings_msg_t*)msg;
reason_string = reason_msg->get_reason(reason_msg, &reason_lang);
- DBG2(DBG_TNC, "reason string is '%.*s", reason_string.len,
+ DBG2(DBG_TNC, "reason string is '%.*s'", reason_string.len,
reason_string.ptr);
- DBG2(DBG_TNC, "reason language is '%.*s", reason_lang.len,
+ DBG2(DBG_TNC, "reason language is '%.*s'", reason_lang.len,
reason_lang.ptr);
break;
}
@@ -243,17 +288,17 @@ METHOD(tls_t, process, status_t,
if (this->is_server && !this->connection_id)
{
- this->connection_id = charon->tnccs->create_connection(charon->tnccs,
- (tnccs_t*)this, _send_msg,
+ this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
+ TNCCS_1_1, (tnccs_t*)this, _send_msg,
&this->request_handshake_retry, &this->recs);
if (!this->connection_id)
{
return FAILED;
}
- charon->imvs->notify_connection_change(charon->imvs,
- this->connection_id, TNC_CONNECTION_STATE_CREATE);
- charon->imvs->notify_connection_change(charon->imvs,
- this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+ tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+ TNC_CONNECTION_STATE_CREATE);
+ tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+ TNC_CONNECTION_STATE_HANDSHAKE);
}
data = chunk_create(buf, buflen);
@@ -304,11 +349,11 @@ METHOD(tls_t, process, status_t,
this->send_msg = TRUE;
if (this->is_server)
{
- charon->imvs->batch_ending(charon->imvs, this->connection_id);
+ tnc->imvs->batch_ending(tnc->imvs, this->connection_id);
}
else
{
- charon->imcs->batch_ending(charon->imcs, this->connection_id);
+ tnc->imcs->batch_ending(tnc->imcs, this->connection_id);
}
this->send_msg = FALSE;
}
@@ -331,7 +376,7 @@ static void check_and_build_recommendation(private_tnccs_11_t *this)
if (!this->recs->have_recommendation(this->recs, &rec, &eval))
{
- charon->imvs->solicit_recommendation(charon->imvs, this->connection_id);
+ tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id);
}
if (this->recs->have_recommendation(this->recs, &rec, &eval))
{
@@ -351,6 +396,7 @@ static void check_and_build_recommendation(private_tnccs_11_t *this)
this->batch->add_msg(this->batch, msg);
}
enumerator->destroy(enumerator);
+ this->recs->clear_reasons(this->recs);
/* we have reache the final state */
this->delete_state = TRUE;
@@ -368,8 +414,8 @@ METHOD(tls_t, build, status_t,
tnccs_msg_t *msg;
char *pref_lang;
- this->connection_id = charon->tnccs->create_connection(charon->tnccs,
- (tnccs_t*)this, _send_msg,
+ this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
+ TNCCS_1_1, (tnccs_t*)this, _send_msg,
&this->request_handshake_retry, NULL);
if (!this->connection_id)
{
@@ -377,19 +423,19 @@ METHOD(tls_t, build, status_t,
}
/* Create TNCCS-PreferredLanguage message */
- pref_lang = charon->imcs->get_preferred_language(charon->imcs);
+ pref_lang = tnc->imcs->get_preferred_language(tnc->imcs);
msg = tnccs_preferred_language_msg_create(pref_lang);
this->mutex->lock(this->mutex);
this->batch = tnccs_batch_create(this->is_server, ++this->batch_id);
this->batch->add_msg(this->batch, msg);
this->mutex->unlock(this->mutex);
- charon->imcs->notify_connection_change(charon->imcs,
- this->connection_id, TNC_CONNECTION_STATE_CREATE);
- charon->imcs->notify_connection_change(charon->imcs,
- this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+ tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+ TNC_CONNECTION_STATE_CREATE);
+ tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+ TNC_CONNECTION_STATE_HANDSHAKE);
this->send_msg = TRUE;
- charon->imcs->begin_handshake(charon->imcs, this->connection_id);
+ tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
this->send_msg = FALSE;
}
@@ -456,7 +502,7 @@ METHOD(tls_t, is_complete, bool,
if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
{
- return charon->imvs->enforce_recommendation(charon->imvs, rec, eval);
+ return tnc->imvs->enforce_recommendation(tnc->imvs, rec, eval);
}
else
{
@@ -473,8 +519,8 @@ METHOD(tls_t, get_eap_msk, chunk_t,
METHOD(tls_t, destroy, void,
private_tnccs_11_t *this)
{
- charon->tnccs->remove_connection(charon->tnccs, this->connection_id,
- this->is_server);
+ tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
+ this->is_server);
this->mutex->destroy(this->mutex);
DESTROY_IF(this->batch);
free(this);
diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c
index 9ec91f006..cd95afb1e 100644
--- a/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c
+++ b/src/libcharon/plugins/tnccs_11/tnccs_11_plugin.c
@@ -16,7 +16,7 @@
#include "tnccs_11_plugin.h"
#include "tnccs_11.h"
-#include <daemon.h>
+#include <tnc/tnccs/tnccs_manager.h>
METHOD(plugin_t, get_name, char*,
tnccs_11_plugin_t *this)
@@ -24,11 +24,23 @@ METHOD(plugin_t, get_name, char*,
return "tnccs-11";
}
+METHOD(plugin_t, get_features, int,
+ tnccs_11_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(tnccs_method_register, tnccs_11_create),
+ PLUGIN_PROVIDE(CUSTOM, "tnccs-1.1"),
+ PLUGIN_DEPENDS(EAP_SERVER, EAP_TNC),
+ PLUGIN_DEPENDS(EAP_PEER, EAP_TNC),
+ PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
tnccs_11_plugin_t *this)
{
- charon->tnccs->remove_method(charon->tnccs,
- (tnccs_constructor_t)tnccs_11_create);
free(this);
}
@@ -42,14 +54,11 @@ plugin_t *tnccs_11_plugin_create()
INIT(this,
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.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_20/Makefile.am b/src/libcharon/plugins/tnccs_20/Makefile.am
index d72fd3e34..ec17e6412 100644
--- a/src/libcharon/plugins/tnccs_20/Makefile.am
+++ b/src/libcharon/plugins/tnccs_20/Makefile.am
@@ -1,6 +1,9 @@
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@@ -8,7 +11,9 @@ 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
+libstrongswan_tnccs_20_la_LIBADD = \
+ $(top_builddir)/src/libtncif/libtncif.la \
+ $(top_builddir)/src/libtnccs/libtnccs.la
endif
libstrongswan_tnccs_20_la_SOURCES = \
diff --git a/src/libcharon/plugins/tnccs_20/Makefile.in b/src/libcharon/plugins/tnccs_20/Makefile.in
index bbfcc2760..b0078f338 100644
--- a/src/libcharon/plugins/tnccs_20/Makefile.in
+++ b/src/libcharon/plugins/tnccs_20/Makefile.in
@@ -75,7 +75,8 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
@MONOLITHIC_FALSE@libstrongswan_tnccs_20_la_DEPENDENCIES = \
-@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo \
pb_tnc_batch.lo pb_tnc_msg.lo pb_experimental_msg.lo \
pb_pa_msg.lo pb_assessment_result_msg.lo \
@@ -200,6 +201,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -208,6 +212,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -224,11 +229,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -272,6 +279,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -282,13 +290,19 @@ 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
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-20.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-20.la
-@MONOLITHIC_FALSE@libstrongswan_tnccs_20_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+@MONOLITHIC_FALSE@libstrongswan_tnccs_20_la_LIBADD = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+
libstrongswan_tnccs_20_la_SOURCES = \
tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \
batch/pb_tnc_batch.h batch/pb_tnc_batch.c \
diff --git a/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c
index 3f38543ed..c6a4bb599 100644
--- a/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c
+++ b/src/libcharon/plugins/tnccs_20/batch/pb_tnc_batch.c
@@ -18,12 +18,14 @@
#include "messages/pb_error_msg.h"
#include "state_machine/pb_tnc_state_machine.h"
-#include <debug.h>
-#include <utils/linked_list.h>
-#include <tls_writer.h>
-#include <tls_reader.h>
#include <tnc/tnccs/tnccs.h>
+#include <utils/linked_list.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <pen/pen.h>
+#include <debug.h>
+
ENUM(pb_tnc_batch_type_names, PB_BATCH_CDATA, PB_BATCH_CLOSE,
"CDATA",
"SDATA",
@@ -142,7 +144,7 @@ METHOD(pb_tnc_batch_t, build, void,
enumerator_t *enumerator;
pb_tnc_msg_type_t msg_type;
pb_tnc_msg_t *msg;
- tls_writer_t *writer;
+ bio_writer_t *writer;
/* compute total PB-TNC batch size by summing over all messages */
batch_len = PB_TNC_BATCH_HEADER_SIZE;
@@ -156,7 +158,7 @@ METHOD(pb_tnc_batch_t, build, void,
enumerator->destroy(enumerator);
/* build PB-TNC batch header */
- writer = tls_writer_create(batch_len);
+ writer = bio_writer_create(batch_len);
writer->write_uint8 (writer, PB_TNC_VERSION);
writer->write_uint8 (writer, this->is_server ?
PB_TNC_BATCH_FLAG_D : PB_TNC_BATCH_FLAG_NONE);
@@ -178,7 +180,7 @@ METHOD(pb_tnc_batch_t, build, void,
flags |= PB_TNC_FLAG_NOSKIP;
}
writer->write_uint8 (writer, flags);
- writer->write_uint24(writer, IETF_VENDOR_ID);
+ writer->write_uint24(writer, PEN_IETF);
writer->write_uint32(writer, msg_type);
writer->write_uint32(writer, msg_len);
writer->write_data (writer, msg_value);
@@ -192,7 +194,7 @@ METHOD(pb_tnc_batch_t, build, void,
static status_t process_batch_header(private_pb_tnc_batch_t *this,
pb_tnc_state_machine_t *state_machine)
{
- tls_reader_t *reader;
+ bio_reader_t *reader;
pb_tnc_msg_t *msg;
pb_error_msg_t *err_msg;
u_int8_t version, flags, reserved, type;
@@ -203,12 +205,12 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
{
DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC batch header",
this->encoding.len);
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, 0);
goto fatal;
}
- reader = tls_reader_create(this->encoding);
+ reader = bio_reader_create(this->encoding);
reader->read_uint8 (reader, &version);
reader->read_uint8 (reader, &flags);
reader->read_uint8 (reader, &reserved);
@@ -220,7 +222,7 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
if (version != PB_TNC_VERSION)
{
DBG1(DBG_TNC, "unsupported TNCCS batch version 0x%01x", version);
- msg = pb_error_msg_create(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create(TRUE, PEN_IETF,
PB_ERROR_VERSION_NOT_SUPPORTED);
err_msg = (pb_error_msg_t*)msg;
err_msg->set_bad_version(err_msg, version);
@@ -233,7 +235,7 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
{
DBG1(DBG_TNC, "wrong Directionality: batch is from a PB %s",
directionality ? "server" : "client");
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, 1);
goto fatal;
}
@@ -243,7 +245,7 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
if (this->type > PB_BATCH_ROOF)
{
DBG1(DBG_TNC, "unknown PB-TNC batch type: %d", this->type);
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, 3);
goto fatal;
}
@@ -252,7 +254,7 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
{
DBG1(DBG_TNC, "unexpected PB-TNC batch type: %N",
pb_tnc_batch_type_names, this->type);
- msg = pb_error_msg_create(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create(TRUE, PEN_IETF,
PB_ERROR_UNEXPECTED_BATCH_TYPE);
goto fatal;
}
@@ -262,7 +264,7 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this,
{
DBG1(DBG_TNC, "%u bytes of data is not equal to batch length of %u bytes",
this->encoding.len, batch_len);
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, 4);
goto fatal;
}
@@ -277,7 +279,7 @@ fatal:
static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
{
- tls_reader_t *reader;
+ bio_reader_t *reader;
pb_tnc_msg_t *pb_tnc_msg, *msg;
u_int8_t flags;
u_int32_t vendor_id, msg_type, msg_len, offset;
@@ -291,12 +293,12 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
{
DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC message header",
data.len);
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, this->offset);
goto fatal;
}
- reader = tls_reader_create(data);
+ reader = bio_reader_create(data);
reader->read_uint8 (reader, &flags);
reader->read_uint24(reader, &vendor_id);
reader->read_uint32(reader, &msg_type);
@@ -308,15 +310,15 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
if (msg_len > data.len)
{
DBG1(DBG_TNC, "%u bytes insufficient to parse PB-TNC message", data.len);
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, this->offset + 8);
goto fatal;
}
- if (vendor_id == RESERVED_VENDOR_ID)
+ if (vendor_id == PEN_RESERVED)
{
- DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", RESERVED_VENDOR_ID);
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", PEN_RESERVED);
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, this->offset + 1);
goto fatal;
@@ -326,19 +328,19 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
{
DBG1(DBG_TNC, "PB-TNC message Type 0x%08x is reserved",
PB_TNC_RESERVED_MSG_TYPE);
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, this->offset + 4);
goto fatal;
}
- if (vendor_id != IETF_VENDOR_ID || msg_type > PB_MSG_ROOF)
+ if (vendor_id != PEN_IETF || msg_type > PB_MSG_ROOF)
{
if (msg_len < PB_TNC_HEADER_SIZE)
{
DBG1(DBG_TNC, "%u bytes too small for PB-TNC message length",
msg_len);
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, this->offset + 8);
goto fatal;
}
@@ -347,7 +349,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
{
DBG1(DBG_TNC, "reject PB-TNC message (Vendor ID 0x%06x / "
"Type 0x%08x)", vendor_id, msg_type);
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset);
goto fatal;
}
@@ -367,7 +369,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
DBG1(DBG_TNC, "%N message must%s have NOSKIP flag set",
pb_tnc_msg_type_names, msg_type,
pb_tnc_msg_infos[msg_type].has_noskip_flag ? "" : " not");
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, this->offset);
goto fatal;
}
@@ -380,7 +382,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
pb_tnc_msg_type_names, msg_type,
pb_tnc_msg_infos[msg_type].exact_size ? "exactly" : "at least",
pb_tnc_msg_infos[msg_type].min_size, msg_len);
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, this->offset);
goto fatal;
}
@@ -393,7 +395,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
{
DBG1(DBG_TNC,"reject %N message received from a PB-TNC client",
pb_tnc_msg_type_names, msg_type);
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
PB_ERROR_INVALID_PARAMETER, this->offset);
goto fatal;
}
@@ -415,8 +417,8 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this)
status = pb_tnc_msg->process(pb_tnc_msg, &offset);
if (status == FAILED || status == VERIFY_ERROR)
{
- msg = pb_error_msg_create_with_offset(TRUE, IETF_VENDOR_ID,
- PB_ERROR_INVALID_PARAMETER, this->offset);
+ msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF,
+ PB_ERROR_INVALID_PARAMETER, this->offset + offset);
this->errors->insert_last(this->errors, msg);
}
if (status == FAILED)
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c
index 41b9e31f6..fa3deddf6 100644
--- a/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_access_recommendation_msg.c
@@ -15,8 +15,8 @@
#include "pb_access_recommendation_msg.h"
-#include <tls_writer.h>
-#include <tls_reader.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
#include <debug.h>
ENUM(pb_access_recommendation_code_names, PB_REC_ACCESS_ALLOWED, PB_REC_QUARANTINED,
@@ -80,10 +80,10 @@ METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
METHOD(pb_tnc_msg_t, build, void,
private_pb_access_recommendation_msg_t *this)
{
- tls_writer_t *writer;
+ bio_writer_t *writer;
/* build message */
- writer = tls_writer_create(ACCESS_RECOMMENDATION_MSG_SIZE);
+ writer = bio_writer_create(ACCESS_RECOMMENDATION_MSG_SIZE);
writer->write_uint16(writer, ACCESS_RECOMMENDATION_RESERVED);
writer->write_uint16(writer, this->recommendation);
free(this->encoding.ptr);
@@ -95,11 +95,11 @@ METHOD(pb_tnc_msg_t, build, void,
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_access_recommendation_msg_t *this, u_int32_t *offset)
{
- tls_reader_t *reader;
+ bio_reader_t *reader;
u_int16_t reserved;
/* process message */
- reader = tls_reader_create(this->encoding);
+ reader = bio_reader_create(this->encoding);
reader->read_uint16(reader, &reserved);
reader->read_uint16(reader, &this->recommendation);
reader->destroy(reader);
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c
index c91e54176..0d558c0d4 100644
--- a/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_assessment_result_msg.c
@@ -15,9 +15,10 @@
#include "pb_assessment_result_msg.h"
-#include <tls_writer.h>
-#include <tls_reader.h>
-#include <tnc/tncifimv.h>
+#include <tncifimv.h>
+
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
#include <debug.h>
typedef struct private_pb_assessment_result_msg_t private_pb_assessment_result_msg_t;
@@ -75,10 +76,10 @@ METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
METHOD(pb_tnc_msg_t, build, void,
private_pb_assessment_result_msg_t *this)
{
- tls_writer_t *writer;
+ bio_writer_t *writer;
/* build message */
- writer = tls_writer_create(ASSESSMENT_RESULT_MSG_SIZE);
+ writer = bio_writer_create(ASSESSMENT_RESULT_MSG_SIZE);
writer->write_uint32(writer, this->assessment_result);
free(this->encoding.ptr);
this->encoding = writer->get_buf(writer);
@@ -89,10 +90,10 @@ METHOD(pb_tnc_msg_t, build, void,
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_assessment_result_msg_t *this, u_int32_t *offset)
{
- tls_reader_t *reader;
+ bio_reader_t *reader;
/* process message */
- reader = tls_reader_create(this->encoding);
+ reader = bio_reader_create(this->encoding);
reader->read_uint32(reader, &this->assessment_result);
reader->destroy(reader);
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c
index e1755c512..03e3cec92 100644
--- a/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_error_msg.c
@@ -15,11 +15,13 @@
#include "pb_error_msg.h"
-#include <debug.h>
-#include <tls_writer.h>
-#include <tls_reader.h>
#include <tnc/tnccs/tnccs.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <pen/pen.h>
+#include <debug.h>
+
ENUM(pb_tnc_error_code_names, PB_ERROR_UNEXPECTED_BATCH_TYPE,
PB_ERROR_VERSION_NOT_SUPPORTED,
"Unexpected Batch Type",
@@ -116,10 +118,10 @@ METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
METHOD(pb_tnc_msg_t, build, void,
private_pb_error_msg_t *this)
{
- tls_writer_t *writer;
+ bio_writer_t *writer;
/* build message header */
- writer = tls_writer_create(ERROR_HEADER_SIZE);
+ writer = bio_writer_create(ERROR_HEADER_SIZE);
writer->write_uint8 (writer, this->fatal ?
ERROR_FLAG_FATAL : ERROR_FLAG_NONE);
writer->write_uint24(writer, this->vendor_id);
@@ -152,24 +154,25 @@ METHOD(pb_tnc_msg_t, process, status_t,
{
u_int8_t flags, max_version, min_version;
u_int16_t reserved;
- tls_reader_t *reader;
+ bio_reader_t *reader;
if (this->encoding.len < ERROR_HEADER_SIZE)
{
DBG1(DBG_TNC,"%N message is shorter than header size of %u bytes",
pb_tnc_msg_type_names, PB_MSG_ERROR, ERROR_HEADER_SIZE);
+ *offset = 0;
return FAILED;
}
/* process message header */
- reader = tls_reader_create(this->encoding);
+ reader = bio_reader_create(this->encoding);
reader->read_uint8 (reader, &flags);
reader->read_uint24(reader, &this->vendor_id);
reader->read_uint16(reader, &this->error_code);
reader->read_uint16(reader, &reserved);
this->fatal = (flags & ERROR_FLAG_FATAL) != ERROR_FLAG_NONE;
- if (this->vendor_id == IETF_VENDOR_ID && reader->remaining(reader) == 4)
+ if (this->vendor_id == PEN_IETF && reader->remaining(reader) == 4)
{
if (this->error_code == PB_ERROR_VERSION_NOT_SUPPORTED)
{
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c
index 9a94edf30..297cc8df7 100644
--- a/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_language_preference_msg.c
@@ -15,8 +15,8 @@
#include "pb_language_preference_msg.h"
-#include <tls_writer.h>
-#include <tls_reader.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
#include <debug.h>
typedef struct private_pb_language_preference_msg_t private_pb_language_preference_msg_t;
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c
index 8315bfb76..1c4913e5e 100644
--- a/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c
@@ -17,22 +17,12 @@
#include "pb_pa_msg.h"
-#include <tls_writer.h>
-#include <tls_reader.h>
#include <tnc/tnccs/tnccs.h>
-#include <debug.h>
-ENUM(pa_tnc_subtype_names, PA_SUBTYPE_TESTING, PA_SUBTYPE_NEA_CLIENT,
- "Testing",
- "Operating System",
- "Anti-Virus",
- "Anti-Spyware",
- "Anti-Malware",
- "Firewall",
- "IDPS",
- "VPN",
- "NEA Client"
-);
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <pen/pen.h>
+#include <debug.h>
typedef struct private_pb_pa_msg_t private_pb_pa_msg_t;
@@ -124,10 +114,10 @@ METHOD(pb_tnc_msg_t, build, void,
private_pb_pa_msg_t *this)
{
chunk_t msg_header;
- tls_writer_t *writer;
+ bio_writer_t *writer;
/* build message header */
- writer = tls_writer_create(64);
+ writer = bio_writer_create(64);
writer->write_uint8 (writer, this->excl ? PA_FLAG_EXCL : PA_FLAG_NONE);
writer->write_uint24(writer, this->vendor_id);
writer->write_uint32(writer, this->subtype);
@@ -146,10 +136,10 @@ METHOD(pb_tnc_msg_t, process, status_t,
{
u_int8_t flags;
size_t msg_body_len;
- tls_reader_t *reader;
+ bio_reader_t *reader;
/* process message header */
- reader = tls_reader_create(this->encoding);
+ reader = bio_reader_create(this->encoding);
reader->read_uint8 (reader, &flags);
reader->read_uint24(reader, &this->vendor_id);
reader->read_uint32(reader, &this->subtype);
@@ -166,9 +156,9 @@ METHOD(pb_tnc_msg_t, process, status_t,
}
reader->destroy(reader);
- if (this->vendor_id == RESERVED_VENDOR_ID)
+ if (this->vendor_id == PEN_RESERVED)
{
- DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", RESERVED_VENDOR_ID);
+ DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", PEN_RESERVED);
*offset = 1;
return FAILED;
}
@@ -221,12 +211,6 @@ METHOD(pb_pa_msg_t, get_exclusive_flag, bool,
return this->excl;
}
-METHOD(pb_pa_msg_t, set_exclusive_flag, void,
- private_pb_pa_msg_t *this, bool excl)
-{
- this->excl = excl;
-}
-
/**
* See header
*/
@@ -247,7 +231,6 @@ pb_tnc_msg_t *pb_pa_msg_create_from_data(chunk_t data)
.get_validator_id = _get_validator_id,
.get_body = _get_body,
.get_exclusive_flag = _get_exclusive_flag,
- .set_exclusive_flag = _set_exclusive_flag,
},
.type = PB_MSG_PA,
.encoding = chunk_clone(data),
@@ -261,7 +244,7 @@ pb_tnc_msg_t *pb_pa_msg_create_from_data(chunk_t data)
*/
pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype,
u_int16_t collector_id, u_int16_t validator_id,
- chunk_t msg_body)
+ bool excl, chunk_t msg_body)
{
private_pb_pa_msg_t *this;
@@ -279,13 +262,13 @@ pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype,
.get_validator_id = _get_validator_id,
.get_body = _get_body,
.get_exclusive_flag = _get_exclusive_flag,
- .set_exclusive_flag = _set_exclusive_flag,
},
.type = PB_MSG_PA,
.vendor_id = vendor_id,
.subtype = subtype,
.collector_id = collector_id,
.validator_id = validator_id,
+ .excl = excl,
.msg_body = chunk_clone(msg_body),
);
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h
index 366d790f6..d9db9a1ce 100644
--- a/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h
@@ -21,32 +21,11 @@
#ifndef PB_PA_MSG_H_
#define PB_PA_MSG_H_
-typedef enum pa_tnc_subtype_t pa_tnc_subtype_t;
typedef struct pb_pa_msg_t pb_pa_msg_t;
#include "pb_tnc_msg.h"
/**
- * PA-TNC Subtypes as defined in section 3.5 of RFC 5792
- */
- enum pa_tnc_subtype_t {
- PA_SUBTYPE_TESTING = 0,
- PA_SUBTYPE_OPERATING_SYSTEM = 1,
- PA_SUBTYPE_ANTI_VIRUS = 2,
- PA_SUBTYPE_ANTI_SPYWARE = 3,
- PA_SUBTYPE_ANTI_MALWARE = 4,
- PA_SUBTYPE_FIREWALL = 5,
- PA_SUBTYPE_IDPS = 6,
- PA_SUBTYPE_VPN = 7,
- PA_SUBTYPE_NEA_CLIENT = 8
-};
-
-/**
- * enum name for pa_tnc_subtype_t.
- */
-extern enum_name_t *pa_tnc_subtype_names;
-
-/**
* Class representing the PB-PA message type.
*/
struct pb_pa_msg_t {
@@ -92,12 +71,6 @@ struct pb_pa_msg_t {
*/
bool (*get_exclusive_flag)(pb_pa_msg_t *this);
- /**
- * Set the exclusive flag
- *
- * @param excl vexclusive flag
- */
- void (*set_exclusive_flag)(pb_pa_msg_t *this, bool excl);
};
/**
@@ -107,11 +80,12 @@ struct pb_pa_msg_t {
* @param subtype PA Subtype
* @param collector_id Posture Collector ID
* @param validator_id Posture Validator ID
+ * @param excl Exclusive Flag
* @param msg_body PA Message Body
*/
pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype,
u_int16_t collector_id, u_int16_t validator_id,
- chunk_t msg_body);
+ bool excl, chunk_t msg_body);
/**
* Create an unprocessed PB-PA message from raw data
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c
index e361cf2b2..181ecf61b 100644
--- a/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_reason_string_msg.c
@@ -15,8 +15,8 @@
#include "pb_reason_string_msg.h"
-#include <tls_writer.h>
-#include <tls_reader.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
#include <debug.h>
typedef struct private_pb_reason_string_msg_t private_pb_reason_string_msg_t;
@@ -81,10 +81,10 @@ METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
METHOD(pb_tnc_msg_t, build, void,
private_pb_reason_string_msg_t *this)
{
- tls_writer_t *writer;
+ bio_writer_t *writer;
/* build message */
- writer = tls_writer_create(64);
+ writer = bio_writer_create(64);
writer->write_data32(writer, this->reason_string);
writer->write_data8 (writer, this->language_code);
@@ -97,10 +97,10 @@ METHOD(pb_tnc_msg_t, build, void,
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_reason_string_msg_t *this, u_int32_t *offset)
{
- tls_reader_t *reader;
+ bio_reader_t *reader;
/* process message */
- reader = tls_reader_create(this->encoding);
+ reader = bio_reader_create(this->encoding);
if (!reader->read_data32(reader, &this->reason_string))
{
DBG1(DBG_TNC, "could not parse reason string");
diff --git a/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c
index 79381a7b1..d213db313 100644
--- a/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c
+++ b/src/libcharon/plugins/tnccs_20/messages/pb_remediation_parameters_msg.c
@@ -15,8 +15,8 @@
#include "pb_remediation_parameters_msg.h"
-#include <tls_writer.h>
-#include <tls_reader.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
#include <debug.h>
ENUM(pb_tnc_remed_param_type_names, PB_REMEDIATION_URI, PB_REMEDIATION_STRING,
@@ -106,10 +106,10 @@ METHOD(pb_tnc_msg_t, get_encoding, chunk_t,
METHOD(pb_tnc_msg_t, build, void,
private_pb_remediation_parameters_msg_t *this)
{
- tls_writer_t *writer;
+ bio_writer_t *writer;
/* build message */
- writer = tls_writer_create(64);
+ writer = bio_writer_create(64);
writer->write_uint32(writer, this->vendor_id);
writer->write_uint32(writer, this->parameters_type);
writer->write_data32(writer, this->remediation_string);
@@ -124,10 +124,10 @@ METHOD(pb_tnc_msg_t, build, void,
METHOD(pb_tnc_msg_t, process, status_t,
private_pb_remediation_parameters_msg_t *this, u_int32_t *offset)
{
- tls_reader_t *reader;
+ bio_reader_t *reader;
/* process message */
- reader = tls_reader_create(this->encoding);
+ reader = bio_reader_create(this->encoding);
reader->read_uint32(reader, &this->vendor_id);
reader->read_uint32(reader, &this->parameters_type);
diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20.c b/src/libcharon/plugins/tnccs_20/tnccs_20.c
index 9e2081d46..606fc529b 100644
--- a/src/libcharon/plugins/tnccs_20/tnccs_20.c
+++ b/src/libcharon/plugins/tnccs_20/tnccs_20.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Sansar Choinyanbuu
- * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010-2011 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -26,12 +26,17 @@
#include "messages/pb_language_preference_msg.h"
#include "state_machine/pb_tnc_state_machine.h"
+#include <tncif_names.h>
+#include <tncif_pa_subtypes.h>
+
+#include <tnc/tnc.h>
+#include <tnc/tnccs/tnccs_manager.h>
+#include <tnc/imc/imc_manager.h>
+#include <tnc/imv/imv_manager.h>
+
#include <debug.h>
-#include <daemon.h>
#include <threading/mutex.h>
-#include <tnc/tncif.h>
-#include <tnc/tncifimv.h>
-#include <tnc/tnccs/tnccs.h>
+#include <pen/pen.h>
typedef struct private_tnccs_20_t private_tnccs_20_t;
@@ -89,18 +94,21 @@ struct private_tnccs_20_t {
* Set of IMV recommendations (TNC Server only)
*/
recommendations_t *recs;
+
};
METHOD(tnccs_t, send_msg, TNC_Result,
private_tnccs_20_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id,
+ TNC_UInt32 msg_flags,
TNC_BufferReference msg,
TNC_UInt32 msg_len,
- TNC_MessageType msg_type)
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype)
{
- TNC_MessageSubtype msg_sub_type;
- TNC_VendorID msg_vendor_id;
pb_tnc_msg_t *pb_tnc_msg;
pb_tnc_batch_type_t batch_type;
+ enum_name_t *pa_subtype_names;
+ bool excl;
if (!this->send_msg)
{
@@ -109,12 +117,23 @@ METHOD(tnccs_t, send_msg, TNC_Result,
this->is_server ? imv_id : imc_id);
return TNC_RESULT_ILLEGAL_OPERATION;
}
+ excl = (msg_flags & TNC_MESSAGE_FLAGS_EXCLUSIVE) != 0;
- msg_sub_type = msg_type & TNC_SUBTYPE_ANY;
- msg_vendor_id = (msg_type >> 8) & TNC_VENDORID_ANY;
+ pb_tnc_msg = pb_pa_msg_create(msg_vid, msg_subtype, imc_id, imv_id,
+ excl, chunk_create(msg, msg_len));
- pb_tnc_msg = pb_pa_msg_create(msg_vendor_id, msg_sub_type, imc_id, imv_id,
- chunk_create(msg, msg_len));
+ pa_subtype_names = get_pa_subtype_names(msg_vid);
+ if (pa_subtype_names)
+ {
+ DBG2(DBG_TNC, "creating PB-PA message type '%N/%N' 0x%06x/0x%08x",
+ pen_names, msg_vid, pa_subtype_names, msg_subtype,
+ msg_vid, msg_subtype);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "creating PB-PA message type '%N' 0x%06x/0x%08x",
+ pen_names, msg_vid, msg_vid, msg_subtype);
+ }
/* adding PA message to SDATA or CDATA batch only */
batch_type = this->is_server ? PB_BATCH_SDATA : PB_BATCH_CDATA;
@@ -148,27 +167,44 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
case PB_MSG_PA:
{
pb_pa_msg_t *pa_msg;
- TNC_MessageType msg_type;
- u_int32_t vendor_id, subtype;
+ u_int32_t msg_vid, msg_subtype;
+ u_int16_t imc_id, imv_id;
chunk_t msg_body;
+ bool excl;
+ enum_name_t *pa_subtype_names;
pa_msg = (pb_pa_msg_t*)msg;
- vendor_id = pa_msg->get_vendor_id(pa_msg, &subtype);
- msg_type = (vendor_id << 8) | (subtype & 0xff);
+ msg_vid = pa_msg->get_vendor_id(pa_msg, &msg_subtype);
msg_body = pa_msg->get_body(pa_msg);
+ imc_id = pa_msg->get_collector_id(pa_msg);
+ imv_id = pa_msg->get_validator_id(pa_msg);
+ excl = pa_msg->get_exclusive_flag(pa_msg);
- DBG2(DBG_TNC, "handling PB-PA message type 0x%08x", msg_type);
+ pa_subtype_names = get_pa_subtype_names(msg_vid);
+ if (pa_subtype_names)
+ {
+ DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x",
+ pen_names, msg_vid, pa_subtype_names, msg_subtype,
+ msg_vid, msg_subtype);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x",
+ pen_names, msg_vid, msg_vid, msg_subtype);
+ }
this->send_msg = TRUE;
if (this->is_server)
{
- charon->imvs->receive_message(charon->imvs,
- this->connection_id, msg_body.ptr, msg_body.len, msg_type);
+ tnc->imvs->receive_message(tnc->imvs, this->connection_id,
+ excl, msg_body.ptr, msg_body.len,
+ msg_vid, msg_subtype, imc_id, imv_id);
}
else
{
- charon->imcs->receive_message(charon->imcs,
- this->connection_id, msg_body.ptr, msg_body.len,msg_type);
+ tnc->imcs->receive_message(tnc->imcs, this->connection_id,
+ excl, msg_body.ptr, msg_body.len,
+ msg_vid, msg_subtype, imv_id, imc_id);
}
this->send_msg = FALSE;
break;
@@ -205,8 +241,8 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
case PB_REC_QUARANTINED:
state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
}
- charon->imcs->notify_connection_change(charon->imcs,
- this->connection_id, state);
+ tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+ state);
break;
}
case PB_MSG_REMEDIATION_PARAMETERS:
@@ -231,7 +267,7 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
this->fatal_error = TRUE;
}
- if (vendor_id == IETF_VENDOR_ID)
+ if (vendor_id == PEN_IETF)
{
switch (error_code)
{
@@ -289,10 +325,10 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
reason_msg = (pb_reason_string_msg_t*)msg;
reason_string = reason_msg->get_reason_string(reason_msg);
language_code = reason_msg->get_language_code(reason_msg);
- DBG2(DBG_TNC, "reason string is '%.*s", reason_string.len,
- reason_string.ptr);
- DBG2(DBG_TNC, "language code is '%.*s", language_code.len,
- language_code.ptr);
+ DBG2(DBG_TNC, "reason string is '%.*s'", reason_string.len,
+ reason_string.ptr);
+ DBG2(DBG_TNC, "language code is '%.*s'", language_code.len,
+ language_code.ptr);
break;
}
default:
@@ -319,6 +355,11 @@ static void build_retry_batch(private_tnccs_20_t *this)
pb_tnc_batch_type_names, this->batch->get_type(this->batch));
this->batch->destroy(this->batch);
}
+ if (this->is_server)
+ {
+ tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+ TNC_CONNECTION_STATE_HANDSHAKE);
+ }
this->batch = pb_tnc_batch_create(this->is_server, batch_retry_type);
}
@@ -333,17 +374,17 @@ METHOD(tls_t, process, status_t,
if (this->is_server && !this->connection_id)
{
- this->connection_id = charon->tnccs->create_connection(charon->tnccs,
- (tnccs_t*)this, _send_msg,
+ this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
+ TNCCS_2_0, (tnccs_t*)this, _send_msg,
&this->request_handshake_retry, &this->recs);
if (!this->connection_id)
{
return FAILED;
}
- charon->imvs->notify_connection_change(charon->imvs,
- this->connection_id, TNC_CONNECTION_STATE_CREATE);
- charon->imvs->notify_connection_change(charon->imvs,
- this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+ tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+ TNC_CONNECTION_STATE_CREATE);
+ tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id,
+ TNC_CONNECTION_STATE_HANDSHAKE);
}
data = chunk_create(buf, buflen);
@@ -372,10 +413,10 @@ METHOD(tls_t, process, status_t,
else if (batch_type == PB_BATCH_SRETRY)
{
/* Restart the measurements */
- charon->imcs->notify_connection_change(charon->imcs,
+ tnc->imcs->notify_connection_change(tnc->imcs,
this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
this->send_msg = TRUE;
- charon->imcs->begin_handshake(charon->imcs, this->connection_id);
+ tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
this->send_msg = FALSE;
}
@@ -406,11 +447,11 @@ METHOD(tls_t, process, status_t,
this->send_msg = TRUE;
if (this->is_server)
{
- charon->imvs->batch_ending(charon->imvs, this->connection_id);
+ tnc->imvs->batch_ending(tnc->imvs, this->connection_id);
}
else
{
- charon->imcs->batch_ending(charon->imcs, this->connection_id);
+ tnc->imcs->batch_ending(tnc->imcs, this->connection_id);
}
this->send_msg = FALSE;
}
@@ -459,10 +500,11 @@ static void check_and_build_recommendation(private_tnccs_20_t *this)
chunk_t reason, language;
enumerator_t *enumerator;
pb_tnc_msg_t *msg;
+ pb_access_recommendation_code_t pb_rec;
if (!this->recs->have_recommendation(this->recs, &rec, &eval))
{
- charon->imvs->solicit_recommendation(charon->imvs, this->connection_id);
+ tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id);
}
if (this->recs->have_recommendation(this->recs, &rec, &eval))
{
@@ -472,10 +514,22 @@ static void check_and_build_recommendation(private_tnccs_20_t *this)
this->batch->add_msg(this->batch, msg);
/**
- * IMV Action Recommendation and PB Access Recommendation codes
- * are shifted by one.
+ * Map IMV Action Recommendation codes to PB Access Recommendation codes
*/
- msg = pb_access_recommendation_msg_create(rec + 1);
+ switch (rec)
+ {
+ case TNC_IMV_ACTION_RECOMMENDATION_ALLOW:
+ pb_rec = PB_REC_ACCESS_ALLOWED;
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE:
+ pb_rec = PB_REC_QUARANTINED;
+ break;
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS:
+ case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION:
+ default:
+ pb_rec = PB_REC_ACCESS_DENIED;
+ }
+ msg = pb_access_recommendation_msg_create(pb_rec);
this->batch->add_msg(this->batch, msg);
enumerator = this->recs->create_reason_enumerator(this->recs);
@@ -485,6 +539,7 @@ static void check_and_build_recommendation(private_tnccs_20_t *this)
this->batch->add_msg(this->batch, msg);
}
enumerator->destroy(enumerator);
+ this->recs->clear_reasons(this->recs);
}
}
@@ -500,8 +555,8 @@ METHOD(tls_t, build, status_t,
pb_tnc_msg_t *msg;
char *pref_lang;
- this->connection_id = charon->tnccs->create_connection(charon->tnccs,
- (tnccs_t*)this, _send_msg,
+ this->connection_id = tnc->tnccs->create_connection(tnc->tnccs,
+ TNCCS_2_0, (tnccs_t*)this, _send_msg,
&this->request_handshake_retry, NULL);
if (!this->connection_id)
{
@@ -509,7 +564,7 @@ METHOD(tls_t, build, status_t,
}
/* Create PB-TNC Language Preference message */
- pref_lang = charon->imcs->get_preferred_language(charon->imcs);
+ pref_lang = tnc->imcs->get_preferred_language(tnc->imcs);
msg = pb_language_preference_msg_create(chunk_create(pref_lang,
strlen(pref_lang)));
this->mutex->lock(this->mutex);
@@ -517,12 +572,12 @@ METHOD(tls_t, build, status_t,
this->batch->add_msg(this->batch, msg);
this->mutex->unlock(this->mutex);
- charon->imcs->notify_connection_change(charon->imcs,
- this->connection_id, TNC_CONNECTION_STATE_CREATE);
- charon->imcs->notify_connection_change(charon->imcs,
- this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE);
+ tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+ TNC_CONNECTION_STATE_CREATE);
+ tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id,
+ TNC_CONNECTION_STATE_HANDSHAKE);
this->send_msg = TRUE;
- charon->imcs->begin_handshake(charon->imcs, this->connection_id);
+ tnc->imcs->begin_handshake(tnc->imcs, this->connection_id);
this->send_msg = FALSE;
}
@@ -639,7 +694,7 @@ METHOD(tls_t, is_complete, bool,
if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval))
{
- return charon->imvs->enforce_recommendation(charon->imvs, rec, eval);
+ return tnc->imvs->enforce_recommendation(tnc->imvs, rec, eval);
}
else
{
@@ -656,8 +711,8 @@ METHOD(tls_t, get_eap_msk, chunk_t,
METHOD(tls_t, destroy, void,
private_tnccs_20_t *this)
{
- charon->tnccs->remove_connection(charon->tnccs, this->connection_id,
- this->is_server);
+ tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id,
+ this->is_server);
this->state_machine->destroy(this->state_machine);
this->mutex->destroy(this->mutex);
DESTROY_IF(this->batch);
diff --git a/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c
index e6dc699e6..4f419ecf0 100644
--- a/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c
+++ b/src/libcharon/plugins/tnccs_20/tnccs_20_plugin.c
@@ -16,7 +16,7 @@
#include "tnccs_20_plugin.h"
#include "tnccs_20.h"
-#include <daemon.h>
+#include <tnc/tnccs/tnccs_manager.h>
METHOD(plugin_t, get_name, char*,
tnccs_20_plugin_t *this)
@@ -24,11 +24,23 @@ METHOD(plugin_t, get_name, char*,
return "tnccs-20";
}
+METHOD(plugin_t, get_features, int,
+ tnccs_20_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(tnccs_method_register, tnccs_20_create),
+ PLUGIN_PROVIDE(CUSTOM, "tnccs-2.0"),
+ PLUGIN_DEPENDS(EAP_SERVER, EAP_TNC),
+ PLUGIN_DEPENDS(EAP_PEER, EAP_TNC),
+ PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
tnccs_20_plugin_t *this)
{
- charon->tnccs->remove_method(charon->tnccs,
- (tnccs_constructor_t)tnccs_20_create);
free(this);
}
@@ -42,14 +54,11 @@ plugin_t *tnccs_20_plugin_create()
INIT(this,
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.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_dynamic/Makefile.am b/src/libcharon/plugins/tnccs_dynamic/Makefile.am
index 9a81d065f..57c2baaf0 100644
--- a/src/libcharon/plugins/tnccs_dynamic/Makefile.am
+++ b/src/libcharon/plugins/tnccs_dynamic/Makefile.am
@@ -1,6 +1,9 @@
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@@ -8,7 +11,9 @@ if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-tnccs-dynamic.la
else
plugin_LTLIBRARIES = libstrongswan-tnccs-dynamic.la
-libstrongswan_tnccs_dynamic_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+libstrongswan_tnccs_dynamic_la_LIBADD = \
+ $(top_builddir)/src/libtncif/libtncif.la \
+ $(top_builddir)/src/libtnccs/libtnccs.la
endif
libstrongswan_tnccs_dynamic_la_SOURCES = \
diff --git a/src/libcharon/plugins/tnccs_dynamic/Makefile.in b/src/libcharon/plugins/tnccs_dynamic/Makefile.in
index dda1472db..ab24d32d3 100644
--- a/src/libcharon/plugins/tnccs_dynamic/Makefile.in
+++ b/src/libcharon/plugins/tnccs_dynamic/Makefile.in
@@ -75,7 +75,8 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
@MONOLITHIC_FALSE@libstrongswan_tnccs_dynamic_la_DEPENDENCIES = \
-@MONOLITHIC_FALSE@ $(top_builddir)/src/libtls/libtls.la
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
am_libstrongswan_tnccs_dynamic_la_OBJECTS = tnccs_dynamic_plugin.lo \
tnccs_dynamic.lo
libstrongswan_tnccs_dynamic_la_OBJECTS = \
@@ -196,6 +197,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -204,6 +208,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -220,11 +225,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -268,6 +275,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -278,13 +286,19 @@ 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
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libtls \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libtnccs
AM_CFLAGS = -rdynamic
@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-dynamic.la
@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-dynamic.la
-@MONOLITHIC_FALSE@libstrongswan_tnccs_dynamic_la_LIBADD = $(top_builddir)/src/libtls/libtls.la
+@MONOLITHIC_FALSE@libstrongswan_tnccs_dynamic_la_LIBADD = \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtncif/libtncif.la \
+@MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la
+
libstrongswan_tnccs_dynamic_la_SOURCES = \
tnccs_dynamic_plugin.h tnccs_dynamic_plugin.c tnccs_dynamic.h tnccs_dynamic.c
diff --git a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c
index b7985fa51..b68d2dd6b 100644
--- a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c
+++ b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic.c
@@ -15,8 +15,9 @@
#include "tnccs_dynamic.h"
-#include <tnc/tnccs/tnccs.h>
-#include <daemon.h>
+#include <tnc/tnc.h>
+
+#include <debug.h>
typedef struct private_tnccs_dynamic_t private_tnccs_dynamic_t;
@@ -75,8 +76,7 @@ METHOD(tls_t, process, status_t,
type = determine_tnccs_protocol(*(char*)buf);
DBG1(DBG_TNC, "%N protocol detected dynamically",
tnccs_type_names, type);
- this->tls = (tls_t*)charon->tnccs->create_instance(charon->tnccs,
- type, TRUE);
+ this->tls = (tls_t*)tnc->tnccs->create_instance(tnc->tnccs, type, TRUE);
if (!this->tls)
{
DBG1(DBG_TNC, "N% protocol not supported", tnccs_type_names, type);
diff --git a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c
index 089a3ed57..6f581c543 100644
--- a/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c
+++ b/src/libcharon/plugins/tnccs_dynamic/tnccs_dynamic_plugin.c
@@ -16,7 +16,7 @@
#include "tnccs_dynamic_plugin.h"
#include "tnccs_dynamic.h"
-#include <daemon.h>
+#include <tnc/tnccs/tnccs_manager.h>
METHOD(plugin_t, get_name, char*,
tnccs_dynamic_plugin_t *this)
@@ -24,11 +24,24 @@ METHOD(plugin_t, get_name, char*,
return "tnccs-dynamic";
}
+METHOD(plugin_t, get_features, int,
+ tnccs_dynamic_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(tnccs_method_register, tnccs_dynamic_create),
+ PLUGIN_PROVIDE(CUSTOM, "tnccs-dynamic"),
+ PLUGIN_DEPENDS(CUSTOM, "tnccs-1.1"),
+ PLUGIN_DEPENDS(CUSTOM, "tnccs-2.0"),
+ PLUGIN_DEPENDS(EAP_SERVER, EAP_TNC),
+ PLUGIN_DEPENDS(EAP_PEER, EAP_TNC),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
tnccs_dynamic_plugin_t *this)
{
- charon->tnccs->remove_method(charon->tnccs,
- (tnccs_constructor_t)tnccs_dynamic_create);
free(this);
}
@@ -42,14 +55,11 @@ plugin_t *tnccs_dynamic_plugin_create()
INIT(this,
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
);
- charon->tnccs->add_method(charon->tnccs, TNCCS_DYNAMIC,
- (tnccs_constructor_t)tnccs_dynamic_create);
-
return &this->plugin;
}
diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in
index 013ceb7da..dd001e0bd 100644
--- a/src/libcharon/plugins/uci/Makefile.in
+++ b/src/libcharon/plugins/uci/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/uci/uci_config.c b/src/libcharon/plugins/uci/uci_config.c
index 4e43388ec..2f5e59b89 100644
--- a/src/libcharon/plugins/uci/uci_config.c
+++ b/src/libcharon/plugins/uci/uci_config.c
@@ -133,10 +133,8 @@ static u_int create_rekey(char *string)
return 12 * 3600;
}
-/**
- * Implementation of peer_enumerator_t.public.enumerate
- */
-static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
+METHOD(enumerator_t, peer_enumerator_enumerate, bool,
+ peer_enumerator_t *this, peer_cfg_t **cfg)
{
char *name, *ike_proposal, *esp_proposal, *ike_rekey, *esp_rekey;
char *local_id, *local_addr, *local_net;
@@ -177,9 +175,9 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
name, 2, ike_cfg, CERT_SEND_IF_ASKED, UNIQUE_NO,
1, create_rekey(ike_rekey), 0, /* keytries, rekey, reauth */
1800, 900, /* jitter, overtime */
- TRUE, 60, /* mobike, dpddelay */
- NULL, NULL, /* vip, pool */
- FALSE, NULL, NULL); /* mediation, med by, peer id */
+ TRUE, 60, /* 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_PSK);
auth->add(auth, AUTH_RULE_IDENTITY,
@@ -208,32 +206,30 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
return FALSE;
}
-/**
- * Implementation of peer_enumerator_t.public.destroy
- */
-static void peer_enumerator_destroy(peer_enumerator_t *this)
+
+METHOD(enumerator_t, peer_enumerator_destroy, void,
+ peer_enumerator_t *this)
{
DESTROY_IF(this->peer_cfg);
this->inner->destroy(this->inner);
free(this);
}
-/**
- * Implementation of backend_t.create_peer_cfg_enumerator.
- */
-static enumerator_t* create_peer_cfg_enumerator(private_uci_config_t *this,
- identification_t *me,
- identification_t *other)
+METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
+ private_uci_config_t *this, identification_t *me, identification_t *other)
{
- peer_enumerator_t *e = malloc_thing(peer_enumerator_t);
-
- e->public.enumerate = (void*)peer_enumerator_enumerate;
- e->public.destroy = (void*)peer_enumerator_destroy;
- e->peer_cfg = NULL;
- e->inner = this->parser->create_section_enumerator(this->parser,
+ peer_enumerator_t *e;
+
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_peer_enumerator_enumerate,
+ .destroy = _peer_enumerator_destroy,
+ },
+ .inner = this->parser->create_section_enumerator(this->parser,
"local_id", "remote_id", "local_addr", "remote_addr",
"local_net", "remote_net", "ike_proposal", "esp_proposal",
- "ike_rekey", "esp_rekey", NULL);
+ "ike_rekey", "esp_rekey", NULL),
+ );
if (!e->inner)
{
free(e);
@@ -254,10 +250,8 @@ typedef struct {
enumerator_t *inner;
} ike_enumerator_t;
-/**
- * Implementation of peer_enumerator_t.public.enumerate
- */
-static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg)
+METHOD(enumerator_t, ike_enumerator_enumerate, bool,
+ ike_enumerator_t *this, ike_cfg_t **cfg)
{
char *local_addr, *remote_addr, *ike_proposal;
@@ -281,29 +275,27 @@ static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg)
return FALSE;
}
-/**
- * Implementation of ike_enumerator_t.public.destroy
- */
-static void ike_enumerator_destroy(ike_enumerator_t *this)
+METHOD(enumerator_t, ike_enumerator_destroy, void,
+ ike_enumerator_t *this)
{
DESTROY_IF(this->ike_cfg);
this->inner->destroy(this->inner);
free(this);
}
-/**
- * Implementation of backend_t.create_ike_cfg_enumerator.
- */
-static enumerator_t* create_ike_cfg_enumerator(private_uci_config_t *this,
- host_t *me, host_t *other)
+METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*,
+ private_uci_config_t *this, host_t *me, host_t *other)
{
- ike_enumerator_t *e = malloc_thing(ike_enumerator_t);
-
- e->public.enumerate = (void*)ike_enumerator_enumerate;
- e->public.destroy = (void*)ike_enumerator_destroy;
- e->ike_cfg = NULL;
- e->inner = this->parser->create_section_enumerator(this->parser,
- "local_addr", "remote_addr", "ike_proposal", NULL);
+ ike_enumerator_t *e;
+
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_ike_enumerator_enumerate,
+ .destroy = _ike_enumerator_destroy,
+ },
+ .inner = this->parser->create_section_enumerator(this->parser,
+ "local_addr", "remote_addr", "ike_proposal", NULL),
+ );
if (!e->inner)
{
free(e);
@@ -312,10 +304,8 @@ static enumerator_t* create_ike_cfg_enumerator(private_uci_config_t *this,
return &e->public;
}
-/**
- * implements backend_t.get_peer_cfg_by_name.
- */
-static peer_cfg_t *get_peer_cfg_by_name(private_uci_config_t *this, char *name)
+METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
+ private_uci_config_t *this, char *name)
{
enumerator_t *enumerator;
peer_cfg_t *current, *found = NULL;
@@ -336,10 +326,8 @@ static peer_cfg_t *get_peer_cfg_by_name(private_uci_config_t *this, char *name)
return found;
}
-/**
- * Implementation of uci_config_t.destroy.
- */
-static void destroy(private_uci_config_t *this)
+METHOD(uci_config_t, destroy, void,
+ private_uci_config_t *this)
{
free(this);
}
@@ -349,13 +337,19 @@ static void destroy(private_uci_config_t *this)
*/
uci_config_t *uci_config_create(uci_parser_t *parser)
{
- private_uci_config_t *this = malloc_thing(private_uci_config_t);
-
- this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator;
- this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator;
- this->public.backend.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_t*,char*))get_peer_cfg_by_name;
- this->public.destroy = (void(*)(uci_config_t*))destroy;
- this->parser = parser;
+ private_uci_config_t *this;
+
+ INIT(this,
+ .public = {
+ .backend = {
+ .create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
+ .create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
+ .get_peer_cfg_by_name = _get_peer_cfg_by_name,
+ },
+ .destroy = _destroy,
+ },
+ .parser = parser,
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/uci/uci_control.c b/src/libcharon/plugins/uci/uci_control.c
index aee2505e3..af4a6a711 100644
--- a/src/libcharon/plugins/uci/uci_control.c
+++ b/src/libcharon/plugins/uci/uci_control.c
@@ -76,8 +76,7 @@ static void write_fifo(private_uci_control_t *this, char *format, ...)
*/
static void status(private_uci_control_t *this, char *name)
{
- enumerator_t *configs, *sas;
- iterator_t *children;
+ enumerator_t *configs, *sas, *children;
ike_sa_t *ike_sa;
child_sa_t *child_sa;
peer_cfg_t *peer_cfg;
@@ -92,7 +91,8 @@ static void status(private_uci_control_t *this, char *name)
{
continue;
}
- sas = charon->controller->create_ike_sa_enumerator(charon->controller);
+ sas = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (sas->enumerate(sas, &ike_sa))
{
if (!streq(ike_sa->get_name(ike_sa), peer_cfg->get_name(peer_cfg)))
@@ -110,8 +110,8 @@ static void status(private_uci_control_t *this, char *name)
fprintf(out, "%-8s %-20D %-16H ", ike_sa->get_name(ike_sa),
ike_sa->get_other_id(ike_sa), ike_sa->get_other_host(ike_sa));
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
+ children = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (children->enumerate(children, (void**)&child_sa))
{
fprintf(out, "%#R",
child_sa->get_traffic_selectors(child_sa, FALSE));
@@ -148,8 +148,8 @@ static void initiate(private_uci_control_t *this, char *name)
enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
if (enumerator->enumerate(enumerator, &child_cfg) &&
charon->controller->initiate(charon->controller, peer_cfg,
- child_cfg->get_ref(child_cfg),
- controller_cb_empty, NULL) == SUCCESS)
+ child_cfg->get_ref(child_cfg),
+ controller_cb_empty, NULL, 0) == SUCCESS)
{
write_fifo(this, "connection '%s' established\n", name);
}
@@ -174,7 +174,8 @@ static void terminate(private_uci_control_t *this, char *name)
ike_sa_t *ike_sa;
u_int id;
- enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+ enumerator = charon->controller->create_ike_sa_enumerator(
+ charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (streq(name, ike_sa->get_name(ike_sa)))
@@ -182,7 +183,7 @@ static void terminate(private_uci_control_t *this, char *name)
id = ike_sa->get_unique_id(ike_sa);
enumerator->destroy(enumerator);
charon->controller->terminate_ike(charon->controller, id,
- controller_cb_empty, NULL);
+ controller_cb_empty, NULL, 0);
write_fifo(this, "connection '%s' terminated\n", name);
return;
}
@@ -265,10 +266,8 @@ static job_requeue_t receive(private_uci_control_t *this)
return JOB_REQUEUE_FAIR;
}
-/**
- * Implementation of uci_control_t.destroy
- */
-static void destroy(private_uci_control_t *this)
+METHOD(uci_control_t, destroy, void,
+ private_uci_control_t *this)
{
this->job->cancel(this->job);
unlink(FIFO_FILE);
@@ -280,9 +279,13 @@ static void destroy(private_uci_control_t *this)
*/
uci_control_t *uci_control_create()
{
- private_uci_control_t *this = malloc_thing(private_uci_control_t);
+ private_uci_control_t *this;
- this->public.destroy = (void(*)(uci_control_t*))destroy;
+ INIT(this,
+ .public = {
+ .destroy = _destroy,
+ },
+ );
unlink(FIFO_FILE);
if (mkfifo(FIFO_FILE, S_IRUSR|S_IWUSR) != 0)
@@ -292,8 +295,8 @@ uci_control_t *uci_control_create()
}
else
{
- this->job = callback_job_create((callback_job_cb_t)receive,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
}
return &this->public;
diff --git a/src/libcharon/plugins/uci/uci_creds.c b/src/libcharon/plugins/uci/uci_creds.c
index 4d664feb2..f5d5ace70 100644
--- a/src/libcharon/plugins/uci/uci_creds.c
+++ b/src/libcharon/plugins/uci/uci_creds.c
@@ -51,11 +51,9 @@ typedef struct {
identification_t *other;
} shared_enumerator_t;
-/**
- * Implementation of shared_enumerator_t.public.enumerate
- */
-static bool shared_enumerator_enumerate(shared_enumerator_t *this,
- shared_key_t **key, id_match_t *me, id_match_t *other)
+METHOD(enumerator_t, shared_enumerator_enumerate, bool,
+ shared_enumerator_t *this, shared_key_t **key, id_match_t *me,
+ id_match_t *other)
{
char *local_id, *remote_id, *psk;
identification_t *local, *remote;
@@ -107,23 +105,17 @@ static bool shared_enumerator_enumerate(shared_enumerator_t *this,
return TRUE;
}
-/**
- * Implementation of shared_enumerator_t.public.destroy
- */
-static void shared_enumerator_destroy(shared_enumerator_t *this)
+METHOD(enumerator_t, shared_enumerator_destroy, void,
+ shared_enumerator_t *this)
{
this->inner->destroy(this->inner);
DESTROY_IF(this->current);
free(this);
}
-/**
- * Implementation of backend_t.create_shared_cfg_enumerator.
- */
-static enumerator_t* create_shared_enumerator(private_uci_creds_t *this,
- shared_key_type_t type,
- identification_t *me,
- identification_t *other)
+METHOD(credential_set_t, create_shared_enumerator, enumerator_t*,
+ private_uci_creds_t *this, shared_key_type_t type,
+ identification_t *me, identification_t *other)
{
shared_enumerator_t *e;
@@ -132,14 +124,16 @@ static enumerator_t* create_shared_enumerator(private_uci_creds_t *this,
return NULL;
}
- e = malloc_thing(shared_enumerator_t);
- e->current = NULL;
- e->public.enumerate = (void*)shared_enumerator_enumerate;
- e->public.destroy = (void*)shared_enumerator_destroy;
- e->me = me;
- e->other = other;
- e->inner = this->parser->create_section_enumerator(this->parser,
- "local_id", "remote_id", "psk", NULL);
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_shared_enumerator_enumerate,
+ .destroy = _shared_enumerator_destroy,
+ },
+ .me = me,
+ .other = other,
+ .inner = this->parser->create_section_enumerator(this->parser,
+ "local_id", "remote_id", "psk", NULL),
+ );
if (!e->inner)
{
free(e);
@@ -148,24 +142,28 @@ static enumerator_t* create_shared_enumerator(private_uci_creds_t *this,
return &e->public;
}
-/**
- * Implementation of uci_creds_t.destroy
- */
-static void destroy(private_uci_creds_t *this)
+METHOD(uci_creds_t, destroy, void,
+ private_uci_creds_t *this)
{
free(this);
}
uci_creds_t *uci_creds_create(uci_parser_t *parser)
{
- private_uci_creds_t *this = malloc_thing(private_uci_creds_t);
-
- this->public.credential_set.create_shared_enumerator = (enumerator_t*(*)(credential_set_t*, shared_key_type_t, identification_t*, identification_t*))create_shared_enumerator;
- this->public.credential_set.create_private_enumerator = (enumerator_t*(*) (credential_set_t*, key_type_t, identification_t*))return_null;
- this->public.credential_set.create_cert_enumerator = (enumerator_t*(*) (credential_set_t*, certificate_type_t, key_type_t,identification_t *, bool))return_null;
- this->public.credential_set.create_cdp_enumerator = (enumerator_t*(*) (credential_set_t *,certificate_type_t, identification_t *))return_null;
- this->public.credential_set.cache_cert = (void (*)(credential_set_t *, certificate_t *))nop;
- this->public.destroy = (void(*) (uci_creds_t*))destroy;
+ private_uci_creds_t *this;
+
+ INIT(this,
+ .public = {
+ .credential_set = {
+ .create_shared_enumerator = _create_shared_enumerator,
+ .create_private_enumerator = (void*)return_null,
+ .create_cert_enumerator = (void*)return_null,
+ .create_cdp_enumerator = (void*)return_null,
+ .cache_cert = (void*)nop,
+ },
+ .destroy = _destroy,
+ },
+ );
this->parser = parser;
diff --git a/src/libcharon/plugins/uci/uci_parser.c b/src/libcharon/plugins/uci/uci_parser.c
index 6de55d218..2429e9e44 100644
--- a/src/libcharon/plugins/uci/uci_parser.c
+++ b/src/libcharon/plugins/uci/uci_parser.c
@@ -57,10 +57,8 @@ typedef struct {
char *keywords[];
} section_enumerator_t;
-/**
- * Implementation of section_enumerator_t.enumerate
- */
-static bool section_enumerator_enumerate(section_enumerator_t *this, ...)
+METHOD(enumerator_t, section_enumerator_enumerate, bool,
+ section_enumerator_t *this, ...)
{
struct uci_element *element;
char **value;
@@ -104,19 +102,15 @@ static bool section_enumerator_enumerate(section_enumerator_t *this, ...)
return TRUE;
}
-/**
- * Implementation of section_enumerator_t.public.destroy
- */
-static void section_enumerator_destroy(section_enumerator_t *this)
+METHOD(enumerator_t, section_enumerator_destroy, void,
+ section_enumerator_t *this)
{
uci_free_context(this->ctx);
free(this);
}
-/**
- * Implementation of backend_t.create_section_enumerator.
- */
-static enumerator_t* create_section_enumerator(private_uci_parser_t *this, ...)
+METHOD(uci_parser_t, create_section_enumerator, enumerator_t*,
+ private_uci_parser_t *this, ...)
{
section_enumerator_t *e;
va_list args;
@@ -140,8 +134,8 @@ static enumerator_t* create_section_enumerator(private_uci_parser_t *this, ...)
while (e->keywords[i++]);
va_end(args);
- e->public.enumerate = (void*)section_enumerator_enumerate;
- e->public.destroy = (void*)section_enumerator_destroy;
+ e->public.enumerate = (void*)_section_enumerator_enumerate;
+ e->public.destroy = _section_enumerator_destroy;
/* load uci context */
e->ctx = uci_alloc_context();
@@ -160,10 +154,8 @@ static enumerator_t* create_section_enumerator(private_uci_parser_t *this, ...)
return &e->public;
}
-/**
- * Implementation of uci_parser_t.destroy.
- */
-static void destroy(private_uci_parser_t *this)
+METHOD(uci_parser_t, destroy, void,
+ private_uci_parser_t *this)
{
free(this->package);
free(this);
@@ -174,12 +166,15 @@ static void destroy(private_uci_parser_t *this)
*/
uci_parser_t *uci_parser_create(char *package)
{
- private_uci_parser_t *this = malloc_thing(private_uci_parser_t);
-
- this->public.create_section_enumerator = (enumerator_t*(*)(uci_parser_t*, ...))create_section_enumerator;
- this->public.destroy = (void(*)(uci_parser_t*))destroy;
-
- this->package = strdup(package);
+ private_uci_parser_t *this;
+
+ INIT(this,
+ .public = {
+ .create_section_enumerator = _create_section_enumerator,
+ .destroy = _destroy,
+ },
+ .package = strdup(package),
+ );
return &this->public;
}
diff --git a/src/libcharon/plugins/uci/uci_plugin.c b/src/libcharon/plugins/uci/uci_plugin.c
index a6d24c32b..497c473a4 100644
--- a/src/libcharon/plugins/uci/uci_plugin.c
+++ b/src/libcharon/plugins/uci/uci_plugin.c
@@ -92,10 +92,10 @@ plugin_t *uci_plugin_create()
},
},
.parser = uci_parser_create(UCI_PACKAGE),
- .config = uci_config_create(this->parser),
- .creds = uci_creds_create(this->parser),
.control = uci_control_create(),
);
+ this->config = uci_config_create(this->parser);
+ this->creds = uci_creds_create(this->parser);
charon->backends->add_backend(charon->backends, &this->config->backend);
lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
diff --git a/src/libcharon/plugins/unit_tester/Makefile.in b/src/libcharon/plugins/unit_tester/Makefile.in
index 2fee3da82..106c9b1fe 100644
--- a/src/libcharon/plugins/unit_tester/Makefile.in
+++ b/src/libcharon/plugins/unit_tester/Makefile.in
@@ -198,6 +198,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -206,6 +209,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -222,11 +226,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -270,6 +276,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in
index 49cffe218..fb7b38f65 100644
--- a/src/libcharon/plugins/updown/Makefile.in
+++ b/src/libcharon/plugins/updown/Makefile.in
@@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +205,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +222,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c
index 8e58b1a9b..2bd757ec7 100644
--- a/src/libcharon/plugins/updown/updown_listener.c
+++ b/src/libcharon/plugins/updown/updown_listener.c
@@ -115,37 +115,15 @@ METHOD(listener_t, child_updown, bool,
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
{
char command[1024];
- char *my_client, *other_client, *my_client_mask, *other_client_mask;
- char *pos, *virtual_ip, *iface, *mark_in, *mark_out, *udp_enc;
+ host_t *my_client, *other_client;
+ u_int8_t my_client_mask, other_client_mask;
+ char *virtual_ip, *iface, *mark_in, *mark_out, *udp_enc;
mark_t mark;
bool is_host, is_ipv6;
FILE *shell;
- /* get subnet/bits from string */
- if (asprintf(&my_client, "%R", my_ts) < 0)
- {
- my_client = NULL;
- }
- pos = strchr(my_client, '/');
- *pos = '\0';
- my_client_mask = pos + 1;
- pos = strchr(my_client_mask, '[');
- if (pos)
- {
- *pos = '\0';
- }
- if (asprintf(&other_client, "%R", other_ts) < 0)
- {
- other_client = NULL;
- }
- pos = strchr(other_client, '/');
- *pos = '\0';
- other_client_mask = pos + 1;
- pos = strchr(other_client_mask, '[');
- if (pos)
- {
- *pos = '\0';
- }
+ my_ts->to_subnet(my_ts, &my_client, &my_client_mask);
+ other_ts->to_subnet(other_ts, &other_client, &other_client_mask);
if (vip)
{
@@ -248,16 +226,12 @@ METHOD(listener_t, child_updown, bool,
"PLUTO_REQID='%u' "
"PLUTO_ME='%H' "
"PLUTO_MY_ID='%Y' "
- "PLUTO_MY_CLIENT='%s/%s' "
- "PLUTO_MY_CLIENT_NET='%s' "
- "PLUTO_MY_CLIENT_MASK='%s' "
+ "PLUTO_MY_CLIENT='%H/%u' "
"PLUTO_MY_PORT='%u' "
"PLUTO_MY_PROTOCOL='%u' "
"PLUTO_PEER='%H' "
"PLUTO_PEER_ID='%Y' "
- "PLUTO_PEER_CLIENT='%s/%s' "
- "PLUTO_PEER_CLIENT_NET='%s' "
- "PLUTO_PEER_CLIENT_MASK='%s' "
+ "PLUTO_PEER_CLIENT='%H/%u' "
"PLUTO_PEER_PORT='%u' "
"PLUTO_PEER_PROTOCOL='%u' "
"%s"
@@ -274,12 +248,10 @@ METHOD(listener_t, child_updown, bool,
child_sa->get_reqid(child_sa),
me, ike_sa->get_my_id(ike_sa),
my_client, my_client_mask,
- my_client, my_client_mask,
my_ts->get_from_port(my_ts),
my_ts->get_protocol(my_ts),
other, ike_sa->get_other_id(ike_sa),
other_client, other_client_mask,
- other_client, other_client_mask,
other_ts->get_from_port(other_ts),
other_ts->get_protocol(other_ts),
virtual_ip,
@@ -288,8 +260,8 @@ METHOD(listener_t, child_updown, bool,
udp_enc,
config->get_hostaccess(config) ? "PLUTO_HOST_ACCESS='1' " : "",
script);
- free(my_client);
- free(other_client);
+ my_client->destroy(my_client);
+ other_client->destroy(other_client);
free(virtual_ip);
free(mark_in);
free(mark_out);
diff --git a/src/libcharon/plugins/whitelist/Makefile.in b/src/libcharon/plugins/whitelist/Makefile.in
index 37ae5f9c3..2534f4bec 100644
--- a/src/libcharon/plugins/whitelist/Makefile.in
+++ b/src/libcharon/plugins/whitelist/Makefile.in
@@ -202,6 +202,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -210,6 +213,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -226,11 +230,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -274,6 +280,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libcharon/plugins/whitelist/whitelist_control.c b/src/libcharon/plugins/whitelist/whitelist_control.c
index 4a1fc5d87..202c9a418 100644
--- a/src/libcharon/plugins/whitelist/whitelist_control.c
+++ b/src/libcharon/plugins/whitelist/whitelist_control.c
@@ -225,8 +225,8 @@ whitelist_control_t *whitelist_control_create(whitelist_listener_t *listener)
return NULL;
}
- this->job = callback_job_create((callback_job_cb_t)receive,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
diff --git a/src/libcharon/processing/jobs/acquire_job.c b/src/libcharon/processing/jobs/acquire_job.c
index 3544dd332..2d836b002 100644
--- a/src/libcharon/processing/jobs/acquire_job.c
+++ b/src/libcharon/processing/jobs/acquire_job.c
@@ -61,6 +61,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_acquire_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/*
* Described in header
*/
@@ -74,6 +80,7 @@ acquire_job_t *acquire_job_create(u_int32_t reqid,
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.c b/src/libcharon/processing/jobs/delete_child_sa_job.c
index 29122cd03..bd8bb9562 100644
--- a/src/libcharon/processing/jobs/delete_child_sa_job.c
+++ b/src/libcharon/processing/jobs/delete_child_sa_job.c
@@ -73,6 +73,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_delete_child_sa_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/*
* Described in header
*/
@@ -86,6 +92,7 @@ delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid,
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/delete_ike_sa_job.c b/src/libcharon/processing/jobs/delete_ike_sa_job.c
index 468c9ef94..c29b72230 100644
--- a/src/libcharon/processing/jobs/delete_ike_sa_job.c
+++ b/src/libcharon/processing/jobs/delete_ike_sa_job.c
@@ -92,6 +92,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_delete_ike_sa_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/*
* Described in header
*/
@@ -104,6 +110,7 @@ delete_ike_sa_job_t *delete_ike_sa_job_create(ike_sa_id_t *ike_sa_id,
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/inactivity_job.c b/src/libcharon/processing/jobs/inactivity_job.c
index 1371000eb..251b9ab03 100644
--- a/src/libcharon/processing/jobs/inactivity_job.c
+++ b/src/libcharon/processing/jobs/inactivity_job.c
@@ -61,15 +61,15 @@ METHOD(job_t, execute, void,
this->reqid, TRUE);
if (ike_sa)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
child_sa_t *child_sa;
u_int32_t delete = 0;
protocol_id_t proto = 0;
int children = 0;
status_t status = SUCCESS;
- iterator = ike_sa->create_child_sa_iterator(ike_sa);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
if (child_sa->get_reqid(child_sa) == this->reqid)
{
@@ -94,7 +94,7 @@ METHOD(job_t, execute, void,
}
children++;
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
if (delete)
{
@@ -127,6 +127,12 @@ METHOD(job_t, execute, void,
}
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_inactivity_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/**
* See header
*/
@@ -137,8 +143,9 @@ inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout,
INIT(this,
.public = {
- .job_interface = {
+ .job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/initiate_mediation_job.c b/src/libcharon/processing/jobs/initiate_mediation_job.c
index ffe8755e2..e52f3c6df 100644
--- a/src/libcharon/processing/jobs/initiate_mediation_job.c
+++ b/src/libcharon/processing/jobs/initiate_mediation_job.c
@@ -41,10 +41,8 @@ struct private_initiate_mediation_job_t {
ike_sa_id_t *mediation_sa_id;
};
-/**
- * Implements job_t.destroy.
- */
-static void destroy(private_initiate_mediation_job_t *this)
+METHOD(job_t, destroy, void,
+ private_initiate_mediation_job_t *this)
{
DESTROY_IF(this->mediation_sa_id);
DESTROY_IF(this->mediated_sa_id);
@@ -66,10 +64,8 @@ static bool initiate_callback(private_initiate_mediation_job_t *this,
return TRUE;
}
-/**
- * Implementation of job_t.execute.
- */
-static void initiate(private_initiate_mediation_job_t *this)
+METHOD(job_t, initiate, void,
+ private_initiate_mediation_job_t *this)
{
ike_sa_t *mediated_sa, *mediation_sa;
peer_cfg_t *mediated_cfg, *mediation_cfg;
@@ -126,7 +122,7 @@ static void initiate(private_initiate_mediation_job_t *this)
mediation_cfg->get_ref(mediation_cfg);
if (charon->controller->initiate(charon->controller, mediation_cfg,
- NULL, (controller_cb_t)initiate_callback, this) != SUCCESS)
+ NULL, (controller_cb_t)initiate_callback, this, 0) != SUCCESS)
{
mediation_cfg->destroy(mediation_cfg);
mediated_cfg->destroy(mediated_cfg);
@@ -172,10 +168,8 @@ static void initiate(private_initiate_mediation_job_t *this)
destroy(this);
}
-/**
- * Implementation of job_t.execute.
- */
-static void reinitiate(private_initiate_mediation_job_t *this)
+METHOD(job_t, reinitiate, void,
+ private_initiate_mediation_job_t *this)
{
ike_sa_t *mediated_sa, *mediation_sa;
peer_cfg_t *mediated_cfg;
@@ -223,20 +217,26 @@ static void reinitiate(private_initiate_mediation_job_t *this)
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_initiate_mediation_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/**
* Creates an empty job
*/
static private_initiate_mediation_job_t *initiate_mediation_job_create_empty()
{
- private_initiate_mediation_job_t *this = malloc_thing(private_initiate_mediation_job_t);
-
- /* interface functions */
- this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
-
- /* private variables */
- this->mediation_sa_id = NULL;
- this->mediated_sa_id = NULL;
-
+ private_initiate_mediation_job_t *this;
+ INIT(this,
+ .public = {
+ .job_interface = {
+ .get_priority = _get_priority,
+ .destroy = _destroy,
+ },
+ },
+ );
return this;
}
@@ -247,8 +247,7 @@ initiate_mediation_job_t *initiate_mediation_job_create(ike_sa_id_t *ike_sa_id)
{
private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty();
- this->public.job_interface.execute = (void (*) (job_t *)) initiate;
-
+ this->public.job_interface.execute = _initiate;
this->mediated_sa_id = ike_sa_id->clone(ike_sa_id);
return &this->public;
@@ -262,8 +261,7 @@ initiate_mediation_job_t *reinitiate_mediation_job_create(ike_sa_id_t *mediation
{
private_initiate_mediation_job_t *this = initiate_mediation_job_create_empty();
- this->public.job_interface.execute = (void (*) (job_t *)) reinitiate;
-
+ this->public.job_interface.execute = _reinitiate;
this->mediation_sa_id = mediation_sa_id->clone(mediation_sa_id);
this->mediated_sa_id = mediated_sa_id->clone(mediated_sa_id);
diff --git a/src/libcharon/processing/jobs/mediation_job.c b/src/libcharon/processing/jobs/mediation_job.c
index b5b8af3b3..6f02f2a0a 100644
--- a/src/libcharon/processing/jobs/mediation_job.c
+++ b/src/libcharon/processing/jobs/mediation_job.c
@@ -66,10 +66,8 @@ struct private_mediation_job_t {
bool response;
};
-/**
- * Implements job_t.destroy.
- */
-static void destroy(private_mediation_job_t *this)
+METHOD(job_t, destroy, void,
+ private_mediation_job_t *this)
{
DESTROY_IF(this->target);
DESTROY_IF(this->source);
@@ -79,10 +77,8 @@ static void destroy(private_mediation_job_t *this)
free(this);
}
-/**
- * Implementation of job_t.execute.
- */
-static void execute(private_mediation_job_t *this)
+METHOD(job_t, execute, void,
+ private_mediation_job_t *this)
{
ike_sa_id_t *target_sa_id;
@@ -137,26 +133,27 @@ static void execute(private_mediation_job_t *this)
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_mediation_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/**
* Creates an empty mediation job
*/
static private_mediation_job_t *mediation_job_create_empty()
{
- private_mediation_job_t *this = malloc_thing(private_mediation_job_t);
-
- /* interface functions */
- this->public.job_interface.execute = (void (*) (job_t *)) execute;
- this->public.job_interface.destroy = (void (*) (job_t *)) destroy;
-
- /* private variables */
- this->target = NULL;
- this->source = NULL;
- this->callback = FALSE;
- this->connect_id = chunk_empty;
- this->connect_key = chunk_empty;
- this->endpoints = NULL;
- this->response = FALSE;
-
+ private_mediation_job_t *this;
+ INIT(this,
+ .public = {
+ .job_interface = {
+ .execute = _execute,
+ .get_priority = _get_priority,
+ .destroy = _destroy,
+ },
+ },
+ );
return this;
}
diff --git a/src/libcharon/processing/jobs/migrate_job.c b/src/libcharon/processing/jobs/migrate_job.c
index 5e7c7ae88..eb10e2e46 100644
--- a/src/libcharon/processing/jobs/migrate_job.c
+++ b/src/libcharon/processing/jobs/migrate_job.c
@@ -79,12 +79,12 @@ METHOD(job_t, execute, void,
}
if (ike_sa)
{
- iterator_t *children;
+ enumerator_t *children;
child_sa_t *child_sa;
host_t *host;
- children = ike_sa->create_child_sa_iterator(ike_sa);
- while (children->iterate(children, (void**)&child_sa))
+ children = ike_sa->create_child_sa_enumerator(ike_sa);
+ while (children->enumerate(children, (void**)&child_sa))
{
if (child_sa->get_reqid(child_sa) == this->reqid)
{
@@ -120,6 +120,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_migrate_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/*
* Described in header
*/
@@ -135,6 +141,7 @@ migrate_job_t *migrate_job_create(u_int32_t reqid,
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/process_message_job.c b/src/libcharon/processing/jobs/process_message_job.c
index b6de4fc0f..a4924d001 100644
--- a/src/libcharon/processing/jobs/process_message_job.c
+++ b/src/libcharon/processing/jobs/process_message_job.c
@@ -84,6 +84,27 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_process_message_job_t *this)
+{
+ switch (this->message->get_exchange_type(this->message))
+ {
+ case IKE_AUTH:
+ /* IKE auth is rather expensive and often blocking, low priority */
+ return JOB_PRIO_LOW;
+ case INFORMATIONAL:
+ /* INFORMATIONALs are inexpensive, for DPD we should have low
+ * reaction times */
+ return JOB_PRIO_HIGH;
+ case IKE_SA_INIT:
+ case CREATE_CHILD_SA:
+ default:
+ /* IKE_SA_INIT is expensive, but we will drop them in the receiver
+ * if we are overloaded */
+ return JOB_PRIO_MEDIUM;
+ }
+}
+
/*
* Described in header
*/
@@ -95,6 +116,7 @@ process_message_job_t *process_message_job_create(message_t *message)
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.c b/src/libcharon/processing/jobs/rekey_child_sa_job.c
index 2bcee2ddf..5855f1bc9 100644
--- a/src/libcharon/processing/jobs/rekey_child_sa_job.c
+++ b/src/libcharon/processing/jobs/rekey_child_sa_job.c
@@ -71,6 +71,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_rekey_child_sa_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/*
* Described in header
*/
@@ -84,6 +90,7 @@ rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid,
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/rekey_ike_sa_job.c b/src/libcharon/processing/jobs/rekey_ike_sa_job.c
index dc86ba9b3..5366195fd 100644
--- a/src/libcharon/processing/jobs/rekey_ike_sa_job.c
+++ b/src/libcharon/processing/jobs/rekey_ike_sa_job.c
@@ -81,6 +81,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_rekey_ike_sa_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/*
* Described in header
*/
@@ -92,6 +98,7 @@ rekey_ike_sa_job_t *rekey_ike_sa_job_create(ike_sa_id_t *ike_sa_id, bool reauth)
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/retransmit_job.c b/src/libcharon/processing/jobs/retransmit_job.c
index 1c78abd27..050f7005a 100644
--- a/src/libcharon/processing/jobs/retransmit_job.c
+++ b/src/libcharon/processing/jobs/retransmit_job.c
@@ -70,6 +70,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_retransmit_job_t *this)
+{
+ return JOB_PRIO_HIGH;
+}
+
/*
* Described in header.
*/
@@ -81,6 +87,7 @@ retransmit_job_t *retransmit_job_create(u_int32_t message_id,ike_sa_id_t *ike_sa
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/roam_job.c b/src/libcharon/processing/jobs/roam_job.c
index 74ef8bd6d..951ac5ad3 100644
--- a/src/libcharon/processing/jobs/roam_job.c
+++ b/src/libcharon/processing/jobs/roam_job.c
@@ -55,7 +55,8 @@ METHOD(job_t, execute, void,
/* enumerator over all IKE_SAs gives us no way to checkin_and_destroy
* after a DESTROY_ME, so we check out each available IKE_SA by hand. */
list = linked_list_create();
- enumerator = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager);
+ enumerator = charon->ike_sa_manager->create_enumerator(
+ charon->ike_sa_manager, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
id = ike_sa->get_id(ike_sa);
@@ -85,6 +86,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_roam_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/*
* Described in header
*/
@@ -96,6 +103,7 @@ roam_job_t *roam_job_create(bool address)
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/send_dpd_job.c b/src/libcharon/processing/jobs/send_dpd_job.c
index 47b525363..ab00d013d 100644
--- a/src/libcharon/processing/jobs/send_dpd_job.c
+++ b/src/libcharon/processing/jobs/send_dpd_job.c
@@ -66,6 +66,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_send_dpd_job_t *this)
+{
+ return JOB_PRIO_HIGH;
+}
+
/*
* Described in header
*/
@@ -77,6 +83,7 @@ send_dpd_job_t *send_dpd_job_create(ike_sa_id_t *ike_sa_id)
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/send_keepalive_job.c b/src/libcharon/processing/jobs/send_keepalive_job.c
index 8d98aad7e..5e128d478 100644
--- a/src/libcharon/processing/jobs/send_keepalive_job.c
+++ b/src/libcharon/processing/jobs/send_keepalive_job.c
@@ -60,6 +60,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_send_keepalive_job_t *this)
+{
+ return JOB_PRIO_HIGH;
+}
+
/*
* Described in header
*/
@@ -71,6 +77,7 @@ send_keepalive_job_t *send_keepalive_job_create(ike_sa_id_t *ike_sa_id)
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/processing/jobs/start_action_job.c b/src/libcharon/processing/jobs/start_action_job.c
index 5dda18be2..b65181ef8 100644
--- a/src/libcharon/processing/jobs/start_action_job.c
+++ b/src/libcharon/processing/jobs/start_action_job.c
@@ -42,6 +42,7 @@ METHOD(job_t, execute, void,
enumerator_t *enumerator, *children;
peer_cfg_t *peer_cfg;
child_cfg_t *child_cfg;
+ ipsec_mode_t mode;
char *name;
enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
@@ -65,11 +66,20 @@ METHOD(job_t, execute, void,
charon->controller->initiate(charon->controller,
peer_cfg->get_ref(peer_cfg),
child_cfg->get_ref(child_cfg),
- NULL, NULL);
+ NULL, NULL, 0);
break;
case ACTION_ROUTE:
DBG1(DBG_JOB, "start action: route '%s'", name);
- charon->traps->install(charon->traps, peer_cfg, child_cfg);
+ mode = child_cfg->get_mode(child_cfg);
+ if (mode == MODE_PASS || mode == MODE_DROP)
+ {
+ charon->shunts->install(charon->shunts, child_cfg);
+ }
+ else
+ {
+ charon->traps->install(charon->traps, peer_cfg,
+ child_cfg);
+ }
break;
case ACTION_NONE:
break;
@@ -81,6 +91,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_start_action_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/*
* Described in header
*/
@@ -92,10 +108,11 @@ start_action_job_t *start_action_job_create(void)
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
- )
+ );
return &this->public;
}
diff --git a/src/libcharon/processing/jobs/update_sa_job.c b/src/libcharon/processing/jobs/update_sa_job.c
index 3b4e9949f..c4f6e4782 100644
--- a/src/libcharon/processing/jobs/update_sa_job.c
+++ b/src/libcharon/processing/jobs/update_sa_job.c
@@ -74,6 +74,12 @@ METHOD(job_t, execute, void,
destroy(this);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_update_sa_job_t *this)
+{
+ return JOB_PRIO_MEDIUM;
+}
+
/*
* Described in header
*/
@@ -85,6 +91,7 @@ update_sa_job_t *update_sa_job_create(u_int32_t reqid, host_t *new)
.public = {
.job_interface = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
},
diff --git a/src/libcharon/sa/authenticators/authenticator.c b/src/libcharon/sa/authenticators/authenticator.c
index 83f5fbaad..9ffe661cc 100644
--- a/src/libcharon/sa/authenticators/authenticator.c
+++ b/src/libcharon/sa/authenticators/authenticator.c
@@ -28,11 +28,12 @@ ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS,
"RSA signature",
"pre-shared key",
"DSS signature");
-ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_ECDSA_521, AUTH_DSS,
+ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_GSPM, AUTH_DSS,
"ECDSA-256 signature",
"ECDSA-384 signature",
- "ECDSA-521 signature");
-ENUM_END(auth_method_names, AUTH_ECDSA_521);
+ "ECDSA-521 signature",
+ "secure password method");
+ENUM_END(auth_method_names, AUTH_GSPM);
/**
* Described in header.
diff --git a/src/libcharon/sa/authenticators/authenticator.h b/src/libcharon/sa/authenticators/authenticator.h
index d27e006a3..5042e4a73 100644
--- a/src/libcharon/sa/authenticators/authenticator.h
+++ b/src/libcharon/sa/authenticators/authenticator.h
@@ -67,6 +67,12 @@ enum auth_method_t {
* ECDSA with SHA-512 on the P-521 curve as specified in RFC 4754
*/
AUTH_ECDSA_521 = 11,
+
+ /**
+ * Generic Secure Password Authentication Method as specified in RFC 6467
+ */
+ AUTH_GSPM = 12,
+
};
/**
diff --git a/src/libcharon/sa/authenticators/eap/eap_method.c b/src/libcharon/sa/authenticators/eap/eap_method.c
index 0fa4a00c5..a05e8c59a 100644
--- a/src/libcharon/sa/authenticators/eap/eap_method.c
+++ b/src/libcharon/sa/authenticators/eap/eap_method.c
@@ -15,8 +15,28 @@
#include "eap_method.h"
+#include <daemon.h>
+
ENUM(eap_role_names, EAP_SERVER, EAP_PEER,
"EAP_SERVER",
"EAP_PEER",
);
+/**
+ * See header
+ */
+bool eap_method_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data)
+{
+ if (reg)
+ {
+ charon->eap->add_method(charon->eap, feature->arg.eap, 0,
+ feature->type == FEATURE_EAP_SERVER ? EAP_SERVER : EAP_PEER,
+ (eap_constructor_t)data);
+ }
+ else
+ {
+ charon->eap->remove_method(charon->eap, (eap_constructor_t)data);
+ }
+ return TRUE;
+}
diff --git a/src/libcharon/sa/authenticators/eap/eap_method.h b/src/libcharon/sa/authenticators/eap/eap_method.h
index 0eab2b5ff..6242a5a6e 100644
--- a/src/libcharon/sa/authenticators/eap/eap_method.h
+++ b/src/libcharon/sa/authenticators/eap/eap_method.h
@@ -25,6 +25,7 @@ typedef struct eap_method_t eap_method_t;
typedef enum eap_role_t eap_role_t;
#include <library.h>
+#include <plugins/plugin.h>
#include <utils/identification.h>
#include <eap/eap.h>
#include <encoding/payloads/eap_payload.h>
@@ -159,4 +160,18 @@ struct eap_method_t {
typedef eap_method_t *(*eap_constructor_t)(identification_t *server,
identification_t *peer);
+/**
+ * Helper function to (un-)register EAP methods from plugin features.
+ *
+ * This function is a plugin_feature_callback_t and can be used with the
+ * PLUGIN_CALLBACK macro to register a EAP method constructor.
+ *
+ * @param plugin plugin registering the EAP method constructor
+ * @param feature associated plugin feature
+ * @param reg TRUE to register, FALSE to unregister.
+ * @param data data passed to callback, an eap_constructor_t
+ */
+bool eap_method_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data);
+
#endif /** EAP_METHOD_H_ @}*/
diff --git a/src/libcharon/sa/authenticators/eap_authenticator.c b/src/libcharon/sa/authenticators/eap_authenticator.c
index d442acb00..5c8f0b6ce 100644
--- a/src/libcharon/sa/authenticators/eap_authenticator.c
+++ b/src/libcharon/sa/authenticators/eap_authenticator.c
@@ -160,7 +160,9 @@ static eap_payload_t* server_initiate_eap(private_eap_authenticator_t *this,
{
if (this->method->initiate(this->method, &out) == NEED_MORE)
{
- DBG1(DBG_IKE, "initiating EAP-Identity request");
+ DBG1(DBG_IKE, "initiating %N method (id 0x%02X)",
+ eap_type_names, EAP_IDENTITY,
+ this->method->get_identifier(this->method));
return out;
}
this->method->destroy(this->method);
@@ -216,23 +218,12 @@ static eap_payload_t* server_initiate_eap(private_eap_authenticator_t *this,
*/
static void replace_eap_identity(private_eap_authenticator_t *this)
{
- enumerator_t *enumerator;
- auth_rule_t rule;
+ identification_t *eap_identity;
auth_cfg_t *cfg;
- void *ptr;
+ eap_identity = this->eap_identity->clone(this->eap_identity);
cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
- enumerator = cfg->create_enumerator(cfg);
- while (enumerator->enumerate(enumerator, &rule, &ptr))
- {
- if (rule == AUTH_RULE_EAP_IDENTITY)
- {
- cfg->replace(cfg, enumerator, AUTH_RULE_EAP_IDENTITY,
- this->eap_identity->clone(this->eap_identity));
- break;
- }
- }
- enumerator->destroy(enumerator);
+ cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, eap_identity);
}
/**
@@ -349,8 +340,8 @@ static eap_payload_t* client_process_eap(private_eap_authenticator_t *this,
{
id = this->ike_sa->get_my_id(this->ike_sa);
}
- DBG1(DBG_IKE, "server requested %N, sending '%Y'",
- eap_type_names, type, id);
+ DBG1(DBG_IKE, "server requested %N (id 0x%02X), sending '%Y'",
+ eap_type_names, type, in->get_identifier(in), id);
this->eap_identity = id->clone(id);
this->method = load_method(this, type, vendor, EAP_PEER);
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c
index dc42ba787..2130a5998 100644
--- a/src/libcharon/sa/child_sa.c
+++ b/src/libcharon/sa/child_sa.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2010 Tobias Brunner
+ * Copyright (C) 2006-2011 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
@@ -657,6 +657,55 @@ METHOD(child_sa_t, install, status_t,
return status;
}
+/**
+ * Install 3 policies: out, in and forward
+ */
+static status_t install_policies_internal(private_child_sa_t *this,
+ host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
+ traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
+ ipsec_sa_cfg_t *other_sa, policy_type_t type, policy_priority_t priority)
+{
+ status_t status = SUCCESS;
+ status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
+ my_addr, other_addr, my_ts, other_ts,
+ POLICY_OUT, type, other_sa,
+ this->mark_out, priority);
+
+ status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
+ other_addr, my_addr, other_ts, my_ts,
+ POLICY_IN, type, my_sa,
+ this->mark_in, priority);
+ if (this->mode != MODE_TRANSPORT)
+ {
+ status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
+ other_addr, my_addr, other_ts, my_ts,
+ POLICY_FWD, type, my_sa,
+ this->mark_in, priority);
+ }
+ return status;
+}
+
+/**
+ * Delete 3 policies: out, in and forward
+ */
+static void del_policies_internal(private_child_sa_t *this,
+ traffic_selector_t *my_ts, traffic_selector_t *other_ts,
+ policy_priority_t priority)
+{
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
+ my_ts, other_ts, POLICY_OUT, this->reqid,
+ this->mark_out, priority);
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
+ other_ts, my_ts, POLICY_IN, this->reqid,
+ this->mark_in, priority);
+ if (this->mode != MODE_TRANSPORT)
+ {
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
+ other_ts, my_ts, POLICY_FWD, this->reqid,
+ this->mark_in, priority);
+ }
+}
+
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)
@@ -664,7 +713,6 @@ METHOD(child_sa_t, add_policies, status_t,
enumerator_t *enumerator;
traffic_selector_t *my_ts, *other_ts;
status_t status = SUCCESS;
- bool routed = (this->state == CHILD_CREATED);
/* apply traffic selectors */
enumerator = my_ts_list->create_enumerator(my_ts_list);
@@ -682,6 +730,7 @@ METHOD(child_sa_t, add_policies, status_t,
if (this->config->install_policy(this->config))
{
+ policy_priority_t priority;
ipsec_sa_cfg_t my_sa = {
.mode = this->mode,
.reqid = this->reqid,
@@ -708,31 +757,28 @@ METHOD(child_sa_t, add_policies, status_t,
other_sa.ah.spi = this->other_spi;
}
+ priority = this->state == CHILD_CREATED ? POLICY_PRIORITY_ROUTED
+ : POLICY_PRIORITY_DEFAULT;
+
/* 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 |= 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)
+ /* install outbound drop policy to avoid packets leaving unencrypted
+ * when updating policies */
+ if (priority == POLICY_PRIORITY_DEFAULT)
{
- 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);
+ status |= install_policies_internal(this, this->my_addr,
+ this->other_addr, my_ts, other_ts,
+ &my_sa, &other_sa, POLICY_DROP,
+ POLICY_PRIORITY_FALLBACK);
}
+ /* install policies */
+ status |= install_policies_internal(this, this->my_addr,
+ this->other_addr, my_ts, other_ts,
+ &my_sa, &other_sa, POLICY_IPSEC, priority);
+
if (status != SUCCESS)
{
break;
@@ -769,7 +815,7 @@ METHOD(child_sa_t, update, status_t,
if (!transport_proxy_mode)
{
- /* update our (initator) SA */
+ /* update our (initiator) SA */
if (this->my_spi)
{
if (hydra->kernel_interface->update_sa(hydra->kernel_interface,
@@ -835,26 +881,22 @@ METHOD(child_sa_t, update, status_t,
enumerator = create_policy_enumerator(this);
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
{
+ traffic_selector_t *old_my_ts = NULL, *old_other_ts = NULL;
/* remove old policies first */
- hydra->kernel_interface->del_policy(hydra->kernel_interface,
- my_ts, other_ts, POLICY_OUT, this->mark_out, FALSE);
- hydra->kernel_interface->del_policy(hydra->kernel_interface,
- other_ts, my_ts, POLICY_IN, this->mark_in, FALSE);
- if (this->mode != MODE_TRANSPORT)
- {
- hydra->kernel_interface->del_policy(hydra->kernel_interface,
- other_ts, my_ts, POLICY_FWD, this->mark_in, FALSE);
- }
+ del_policies_internal(this, my_ts, other_ts,
+ POLICY_PRIORITY_DEFAULT);
- /* check whether we have to update a "dynamic" traffic selector */
+ /* check if we have to update a "dynamic" traffic selector */
if (!me->ip_equals(me, this->my_addr) &&
my_ts->is_host(my_ts, this->my_addr))
{
+ old_my_ts = my_ts->clone(my_ts);
my_ts->set_address(my_ts, me);
}
if (!other->ip_equals(other, this->other_addr) &&
other_ts->is_host(other_ts, this->other_addr))
{
+ old_other_ts = other_ts->clone(other_ts);
other_ts->set_address(other_ts, other);
}
@@ -862,22 +904,28 @@ METHOD(child_sa_t, update, status_t,
* correctly */
if (vip)
{
- hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
- hydra->kernel_interface->add_ip(hydra->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 */
- 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)
+ install_policies_internal(this, me, other, my_ts, other_ts,
+ &my_sa, &other_sa, POLICY_IPSEC,
+ POLICY_PRIORITY_DEFAULT);
+
+ /* update fallback policies after the new policy is in place */
+ if (old_my_ts || old_other_ts)
{
- hydra->kernel_interface->add_policy(hydra->kernel_interface,
- other, me, other_ts, my_ts, POLICY_FWD, POLICY_IPSEC,
- &my_sa, this->mark_in, FALSE);
+ del_policies_internal(this, old_my_ts ?: my_ts,
+ old_other_ts ?: other_ts,
+ POLICY_PRIORITY_FALLBACK);
+ install_policies_internal(this, me, other, my_ts, other_ts,
+ &my_sa, &other_sa, POLICY_DROP,
+ POLICY_PRIORITY_FALLBACK);
+ DESTROY_IF(old_my_ts);
+ DESTROY_IF(old_other_ts);
}
}
enumerator->destroy(enumerator);
@@ -910,7 +958,10 @@ METHOD(child_sa_t, destroy, void,
{
enumerator_t *enumerator;
traffic_selector_t *my_ts, *other_ts;
- bool unrouted = (this->state == CHILD_ROUTED);
+ policy_priority_t priority;
+
+ priority = this->state == CHILD_ROUTED ? POLICY_PRIORITY_ROUTED
+ : POLICY_PRIORITY_DEFAULT;
set_state(this, CHILD_DESTROYING);
@@ -942,14 +993,11 @@ METHOD(child_sa_t, destroy, void,
enumerator = create_policy_enumerator(this);
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
{
- 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)
+ del_policies_internal(this, my_ts, other_ts, priority);
+ if (priority == POLICY_PRIORITY_DEFAULT)
{
- hydra->kernel_interface->del_policy(hydra->kernel_interface,
- other_ts, my_ts, POLICY_FWD, this->mark_in, unrouted);
+ del_policies_internal(this, my_ts, other_ts,
+ POLICY_PRIORITY_FALLBACK);
}
}
enumerator->destroy(enumerator);
diff --git a/src/libcharon/sa/connect_manager.c b/src/libcharon/sa/connect_manager.c
index 972cc98ad..7b6ca430f 100644
--- a/src/libcharon/sa/connect_manager.c
+++ b/src/libcharon/sa/connect_manager.c
@@ -130,25 +130,24 @@ static void endpoint_pair_destroy(endpoint_pair_t *this)
static endpoint_pair_t *endpoint_pair_create(endpoint_notify_t *initiator,
endpoint_notify_t *responder, bool initiator_is_local)
{
- endpoint_pair_t *this = malloc_thing(endpoint_pair_t);
-
- this->id = 0;
+ endpoint_pair_t *this;
u_int32_t pi = initiator->get_priority(initiator);
u_int32_t pr = responder->get_priority(responder);
- this->priority = pow(2, 32) * min(pi, pr) + 2 * max(pi, pr) + (pi > pr ? 1 : 0);
- this->local = initiator_is_local ? initiator->get_base(initiator)
- : responder->get_base(responder);
+ INIT(this,
+ .priority = pow(2, 32) * min(pi, pr) + 2 * max(pi, pr)
+ + (pi > pr ? 1 : 0),
+ .local = initiator_is_local ? initiator->get_base(initiator)
+ : responder->get_base(responder),
+ .remote = initiator_is_local ? responder->get_host(responder)
+ : initiator->get_host(initiator),
+ .state = CHECK_WAITING,
+ );
+
this->local = this->local->clone(this->local);
- this->remote = initiator_is_local ? responder->get_host(responder)
- : initiator->get_host(initiator);
this->remote = this->remote->clone(this->remote);
- this->state = CHECK_WAITING;
- this->retransmitted = 0;
- this->packet = NULL;
-
return this;
}
@@ -239,23 +238,24 @@ static check_list_t *check_list_create(identification_t *initiator,
linked_list_t *initiator_endpoints,
bool is_initiator)
{
- check_list_t *this = malloc_thing(check_list_t);
-
- this->connect_id = chunk_clone(connect_id);
-
- this->initiator.id = initiator->clone(initiator);
- this->initiator.key = chunk_clone(initiator_key);
- this->initiator.endpoints = initiator_endpoints->clone_offset(initiator_endpoints, offsetof(endpoint_notify_t, clone));
-
- this->responder.id = responder->clone(responder);
- this->responder.key = chunk_empty;
- this->responder.endpoints = NULL;
-
- this->pairs = linked_list_create();
- this->triggered = linked_list_create();
- this->state = CHECK_NONE;
- this->is_initiator = is_initiator;
- this->is_finishing = FALSE;
+ check_list_t *this;
+
+ INIT(this,
+ .connect_id = chunk_clone(connect_id),
+ .initiator = {
+ .id = initiator->clone(initiator),
+ .key = chunk_clone(initiator_key),
+ .endpoints = initiator_endpoints->clone_offset(initiator_endpoints,
+ offsetof(endpoint_notify_t, clone)),
+ },
+ .responder = {
+ .id = responder->clone(responder),
+ },
+ .pairs = linked_list_create(),
+ .triggered = linked_list_create(),
+ .state = CHECK_NONE,
+ .is_initiator = is_initiator,
+ );
return this;
}
@@ -294,11 +294,13 @@ static void initiated_destroy(initiated_t *this)
static initiated_t *initiated_create(identification_t *id,
identification_t *peer_id)
{
- initiated_t *this = malloc_thing(initiated_t);
+ initiated_t *this;
- this->id = id->clone(id);
- this->peer_id = peer_id->clone(peer_id);
- this->mediated = linked_list_create();
+ INIT(this,
+ .id = id->clone(id),
+ .peer_id = peer_id->clone(peer_id),
+ .mediated = linked_list_create(),
+ );
return this;
}
@@ -351,16 +353,11 @@ static void check_destroy(check_t *this)
*/
static check_t *check_create()
{
- check_t *this = malloc_thing(check_t);
-
- this->connect_id = chunk_empty;
- this->auth = chunk_empty;
- this->endpoint_raw = chunk_empty;
- this->src = NULL;
- this->dst = NULL;
- this->endpoint = NULL;
+ check_t *this;
- this->mid = 0;
+ INIT(this,
+ .mid = 0,
+ );
return this;
}
@@ -396,10 +393,12 @@ static void callback_data_destroy(callback_data_t *this)
static callback_data_t *callback_data_create(private_connect_manager_t *connect_manager,
chunk_t connect_id)
{
- callback_data_t *this = malloc_thing(callback_data_t);
- this->connect_manager = connect_manager;
- this->connect_id = chunk_clone(connect_id);
- this->mid = 0;
+ callback_data_t *this;
+ INIT(this,
+ .connect_manager = connect_manager,
+ .connect_id = chunk_clone(connect_id),
+ .mid = 0,
+ );
return this;
}
@@ -443,11 +442,11 @@ static void initiate_data_destroy(initiate_data_t *this)
static initiate_data_t *initiate_data_create(check_list_t *checklist,
initiated_t *initiated)
{
- initiate_data_t *this = malloc_thing(initiate_data_t);
-
- this->checklist = checklist;
- this->initiated = initiated;
-
+ initiate_data_t *this;
+ INIT(this,
+ .checklist = checklist,
+ .initiated = initiated,
+ );
return this;
}
@@ -476,19 +475,19 @@ static status_t get_initiated_by_ids(private_connect_manager_t *this,
static void remove_initiated(private_connect_manager_t *this,
initiated_t *initiated)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
initiated_t *current;
- iterator = this->initiated->create_iterator(this->initiated, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = this->initiated->create_enumerator(this->initiated);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
if (current == initiated)
{
- iterator->remove(iterator);
+ this->initiated->remove_at(this->initiated, enumerator);
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -514,19 +513,19 @@ static status_t get_checklist_by_id(private_connect_manager_t *this,
static void remove_checklist(private_connect_manager_t *this,
check_list_t *checklist)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
check_list_t *current;
- iterator = this->checklists->create_iterator(this->checklists, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = this->checklists->create_enumerator(this->checklists);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
if (current == checklist)
{
- iterator->remove(iterator);
+ this->checklists->remove_at(this->checklists, enumerator);
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -550,26 +549,15 @@ static status_t endpoints_contain(linked_list_t *endpoints, host_t *host,
*/
static void insert_pair_by_priority(linked_list_t *pairs, endpoint_pair_t *pair)
{
- iterator_t *iterator;
+ enumerator_t *enumerator = pairs->create_enumerator(pairs);
endpoint_pair_t *current;
- bool inserted = FALSE;
-
- iterator = pairs->create_iterator(pairs, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
- {
- if (current->priority < pair->priority)
- {
- iterator->insert_before(iterator, pair);
- inserted = TRUE;
- break;
- }
- }
- iterator->destroy(iterator);
-
- if (!inserted)
+ while (enumerator->enumerate(enumerator, (void**)&current) &&
+ current->priority >= pair->priority)
{
- pairs->insert_last(pairs, pair);
+ continue;
}
+ pairs->insert_before(pairs, enumerator, pair);
+ enumerator->destroy(enumerator);
}
/**
@@ -631,14 +619,14 @@ static bool match_waiting_pair(endpoint_pair_t *current)
static status_t get_triggered_pair(check_list_t *checklist,
endpoint_pair_t **pair)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
endpoint_pair_t *current;
status_t status = NOT_FOUND;
- iterator = checklist->triggered->create_iterator(checklist->triggered, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = checklist->triggered->create_enumerator(checklist->triggered);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
- iterator->remove(iterator);
+ checklist->triggered->remove_at(checklist->triggered, enumerator);
if (current->state == CHECK_WAITING)
{
@@ -650,7 +638,7 @@ static status_t get_triggered_pair(check_list_t *checklist,
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return status;
}
@@ -660,17 +648,17 @@ static status_t get_triggered_pair(check_list_t *checklist,
*/
static void print_checklist(check_list_t *checklist)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
endpoint_pair_t *current;
DBG1(DBG_IKE, "pairs on checklist %#B:", &checklist->connect_id);
- iterator = checklist->pairs->create_iterator(checklist->pairs, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = checklist->pairs->create_enumerator(checklist->pairs);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
DBG1(DBG_IKE, " * %#H - %#H (%d)", current->local, current->remote,
current->priority);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -679,17 +667,17 @@ static void print_checklist(check_list_t *checklist)
*/
static void prune_pairs(linked_list_t *pairs)
{
- iterator_t *iterator, *search;
+ enumerator_t *enumerator, *search;
endpoint_pair_t *current, *other;
u_int32_t id = 0;
- iterator = pairs->create_iterator(pairs, TRUE);
- search = pairs->create_iterator(pairs, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = pairs->create_enumerator(pairs);
+ search = pairs->create_enumerator(pairs);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
current->id = ++id;
- while (search->iterate(search, (void**)&other))
+ while (search->enumerate(search, (void**)&other))
{
if (current == other)
{
@@ -705,14 +693,14 @@ static void prune_pairs(linked_list_t *pairs)
* 'current', remove it */
DBG1(DBG_IKE, "pruning endpoint pair %#H - %#H with priority %d",
other->local, other->remote, other->priority);
- search->remove(search);
+ pairs->remove_at(pairs, search);
endpoint_pair_destroy(other);
}
}
- search->reset(search);
+ pairs->reset_enumerator(pairs, search);
}
search->destroy(search);
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -721,16 +709,16 @@ static void prune_pairs(linked_list_t *pairs)
static void build_pairs(check_list_t *checklist)
{
/* FIXME: limit endpoints and pairs */
- iterator_t *iterator_i, *iterator_r;
+ enumerator_t *enumerator_i, *enumerator_r;
endpoint_notify_t *initiator, *responder;
- iterator_i = checklist->initiator.endpoints->create_iterator(
- checklist->initiator.endpoints, TRUE);
- while (iterator_i->iterate(iterator_i, (void**)&initiator))
+ enumerator_i = checklist->initiator.endpoints->create_enumerator(
+ checklist->initiator.endpoints);
+ while (enumerator_i->enumerate(enumerator_i, (void**)&initiator))
{
- iterator_r = checklist->responder.endpoints->create_iterator(
- checklist->responder.endpoints, TRUE);
- while (iterator_r->iterate(iterator_r, (void**)&responder))
+ enumerator_r = checklist->responder.endpoints->create_enumerator(
+ checklist->responder.endpoints);
+ while (enumerator_r->enumerate(enumerator_r, (void**)&responder))
{
if (initiator->get_family(initiator) != responder->get_family(responder))
{
@@ -740,9 +728,9 @@ static void build_pairs(check_list_t *checklist)
insert_pair_by_priority(checklist->pairs, endpoint_pair_create(
initiator, responder, checklist->is_initiator));
}
- iterator_r->destroy(iterator_r);
+ enumerator_r->destroy(enumerator_r);
}
- iterator_i->destroy(iterator_i);
+ enumerator_i->destroy(enumerator_i);
print_checklist(checklist);
@@ -895,19 +883,19 @@ static job_requeue_t initiator_finish(callback_data_t *data)
static void update_checklist_state(private_connect_manager_t *this,
check_list_t *checklist)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
endpoint_pair_t *current;
bool in_progress = FALSE, succeeded = FALSE;
- iterator = checklist->pairs->create_iterator(checklist->pairs, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = checklist->pairs->create_enumerator(checklist->pairs);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
switch(current->state)
{
case CHECK_WAITING:
/* at least one is still waiting -> checklist remains
* in waiting state */
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return;
case CHECK_IN_PROGRESS:
in_progress = TRUE;
@@ -919,7 +907,7 @@ static void update_checklist_state(private_connect_manager_t *this,
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
if (checklist->is_initiator && succeeded && !checklist->is_finishing)
{
@@ -1185,8 +1173,9 @@ static job_requeue_t initiate_mediated(initiate_data_t *data)
if (get_best_valid_pair(checklist, &pair) == SUCCESS)
{
ike_sa_id_t *waiting_sa;
- iterator_t *iterator = initiated->mediated->create_iterator(initiated->mediated, TRUE);
- while (iterator->iterate(iterator, (void**)&waiting_sa))
+ enumerator_t *enumerator = initiated->mediated->create_enumerator(
+ initiated->mediated);
+ while (enumerator->enumerate(enumerator, (void**)&waiting_sa))
{
ike_sa_t *sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, waiting_sa);
if (sa->initiate_mediated(sa, pair->local, pair->remote, checklist->connect_id) != SUCCESS)
@@ -1199,7 +1188,7 @@ static job_requeue_t initiate_mediated(initiate_data_t *data)
charon->ike_sa_manager->checkin(charon->ike_sa_manager, sa);
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
else
{
@@ -1355,10 +1344,8 @@ static void process_request(private_connect_manager_t *this, check_t *check,
check_destroy(response);
}
-/**
- * Implementation of connect_manager_t.process_check.
- */
-static void process_check(private_connect_manager_t *this, message_t *message)
+METHOD(connect_manager_t, process_check, void,
+ private_connect_manager_t *this, message_t *message)
{
if (message->parse_body(message, NULL) != SUCCESS)
{
@@ -1421,12 +1408,9 @@ static void process_check(private_connect_manager_t *this, message_t *message)
check_destroy(check);
}
-/**
- * Implementation of connect_manager_t.check_and_register.
- */
-static bool check_and_register(private_connect_manager_t *this,
- identification_t *id, identification_t *peer_id,
- ike_sa_id_t *mediated_sa)
+METHOD(connect_manager_t, check_and_register, bool,
+ private_connect_manager_t *this, identification_t *id,
+ identification_t *peer_id, ike_sa_id_t *mediated_sa)
{
initiated_t *initiated;
bool already_there = TRUE;
@@ -1455,12 +1439,9 @@ static bool check_and_register(private_connect_manager_t *this,
return already_there;
}
-/**
- * Implementation of connect_manager_t.check_and_initiate.
- */
-static void check_and_initiate(private_connect_manager_t *this,
- ike_sa_id_t *mediation_sa, identification_t *id,
- identification_t *peer_id)
+METHOD(connect_manager_t, check_and_initiate, void,
+ private_connect_manager_t *this, ike_sa_id_t *mediation_sa,
+ identification_t *id, identification_t *peer_id)
{
initiated_t *initiated;
@@ -1474,27 +1455,23 @@ static void check_and_initiate(private_connect_manager_t *this,
}
ike_sa_id_t *waiting_sa;
- iterator_t *iterator = initiated->mediated->create_iterator(
- initiated->mediated, TRUE);
- while (iterator->iterate(iterator, (void**)&waiting_sa))
+ enumerator_t *enumerator = initiated->mediated->create_enumerator(
+ initiated->mediated);
+ while (enumerator->enumerate(enumerator, (void**)&waiting_sa))
{
job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa,
waiting_sa);
lib->processor->queue_job(lib->processor, job);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);
}
-/**
- * Implementation of connect_manager_t.set_initiator_data.
- */
-static status_t set_initiator_data(private_connect_manager_t *this,
- identification_t *initiator,
- identification_t *responder,
- chunk_t connect_id, chunk_t key,
- linked_list_t *endpoints, bool is_initiator)
+METHOD(connect_manager_t, set_initiator_data, status_t,
+ private_connect_manager_t *this, identification_t *initiator,
+ identification_t *responder, chunk_t connect_id, chunk_t key,
+ linked_list_t *endpoints, bool is_initiator)
{
check_list_t *checklist;
@@ -1517,12 +1494,9 @@ static status_t set_initiator_data(private_connect_manager_t *this,
return SUCCESS;
}
-/**
- * Implementation of connect_manager_t.set_responder_data.
- */
-static status_t set_responder_data(private_connect_manager_t *this,
- chunk_t connect_id, chunk_t key,
- linked_list_t *endpoints)
+METHOD(connect_manager_t, set_responder_data, status_t,
+ private_connect_manager_t *this, chunk_t connect_id, chunk_t key,
+ linked_list_t *endpoints)
{
check_list_t *checklist;
@@ -1551,10 +1525,8 @@ static status_t set_responder_data(private_connect_manager_t *this,
return SUCCESS;
}
-/**
- * Implementation of connect_manager_t.stop_checks.
- */
-static status_t stop_checks(private_connect_manager_t *this, chunk_t connect_id)
+METHOD(connect_manager_t, stop_checks, status_t,
+ private_connect_manager_t *this, chunk_t connect_id)
{
check_list_t *checklist;
@@ -1578,16 +1550,16 @@ static status_t stop_checks(private_connect_manager_t *this, chunk_t connect_id)
return SUCCESS;
}
-/**
- * Implementation of connect_manager_t.destroy.
- */
-static void destroy(private_connect_manager_t *this)
+METHOD(connect_manager_t, destroy, void,
+ private_connect_manager_t *this)
{
this->mutex->lock(this->mutex);
- this->hasher->destroy(this->hasher);
- this->checklists->destroy_function(this->checklists, (void*)check_list_destroy);
- this->initiated->destroy_function(this->initiated, (void*)initiated_destroy);
+ this->checklists->destroy_function(this->checklists,
+ (void*)check_list_destroy);
+ this->initiated->destroy_function(this->initiated,
+ (void*)initiated_destroy);
+ DESTROY_IF(this->hasher);
this->mutex->unlock(this->mutex);
this->mutex->destroy(this->mutex);
@@ -1599,28 +1571,30 @@ static void destroy(private_connect_manager_t *this)
*/
connect_manager_t *connect_manager_create()
{
- private_connect_manager_t *this = malloc_thing(private_connect_manager_t);
-
- this->public.destroy = (void(*)(connect_manager_t*))destroy;
- this->public.check_and_register = (bool(*)(connect_manager_t*,identification_t*,identification_t*,ike_sa_id_t*))check_and_register;
- this->public.check_and_initiate = (void(*)(connect_manager_t*,ike_sa_id_t*,identification_t*,identification_t*))check_and_initiate;
- this->public.set_initiator_data = (status_t(*)(connect_manager_t*,identification_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool))set_initiator_data;
- this->public.set_responder_data = (status_t(*)(connect_manager_t*,chunk_t,chunk_t,linked_list_t*))set_responder_data;
- this->public.process_check = (void(*)(connect_manager_t*,message_t*))process_check;
- this->public.stop_checks = (status_t(*)(connect_manager_t*,chunk_t))stop_checks;
+ private_connect_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .destroy = _destroy,
+ .check_and_register = _check_and_register,
+ .check_and_initiate = _check_and_initiate,
+ .set_initiator_data = _set_initiator_data,
+ .set_responder_data = _set_responder_data,
+ .process_check = _process_check,
+ .stop_checks = _stop_checks,
+ },
+ .hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .checklists = linked_list_create(),
+ .initiated = linked_list_create(),
+ );
- this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
if (this->hasher == NULL)
{
DBG1(DBG_IKE, "unable to create connect manager, SHA1 not supported");
- free(this);
+ destroy(this);
return NULL;
}
- this->checklists = linked_list_create();
- this->initiated = linked_list_create();
-
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
-
- return (connect_manager_t*)this;
+ return &this->public;
}
diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c
index 2fc186fe8..07d19381d 100644
--- a/src/libcharon/sa/ike_sa.c
+++ b/src/libcharon/sa/ike_sa.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2008 Tobias Brunner
+ * Copyright (C) 2006-2012 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -208,9 +208,9 @@ struct private_ike_sa_t {
linked_list_t *attributes;
/**
- * list of peers additional addresses, transmitted via MOBIKE
+ * list of peer's addresses, additional ones transmitted via MOBIKE
*/
- linked_list_t *additional_addresses;
+ linked_list_t *peer_addresses;
/**
* previously value of received DESTINATION_IP hash
@@ -246,6 +246,11 @@ struct private_ike_sa_t {
* remote host address to be used for IKE, set via MIGRATE kernel message
*/
host_t *remote_host;
+
+ /**
+ * TRUE if we are currently reauthenticating this IKE_SA
+ */
+ bool is_reauthenticating;
};
/**
@@ -349,8 +354,8 @@ METHOD(ike_sa_t, get_peer_cfg, peer_cfg_t*,
METHOD(ike_sa_t, set_peer_cfg, void,
private_ike_sa_t *this, peer_cfg_t *peer_cfg)
{
- DESTROY_IF(this->peer_cfg);
peer_cfg->get_ref(peer_cfg);
+ DESTROY_IF(this->peer_cfg);
this->peer_cfg = peer_cfg;
if (this->ike_cfg == NULL)
@@ -559,6 +564,10 @@ METHOD(ike_sa_t, send_dpd, status_t,
job_t *job;
time_t diff, delay;
+ if (this->state == IKE_PASSIVE)
+ {
+ return INVALID_STATE;
+ }
delay = this->peer_cfg->get_dpd(this->peer_cfg);
if (this->task_manager->busy(this->task_manager))
{
@@ -615,6 +624,8 @@ METHOD(ike_sa_t, get_state, ike_sa_state_t,
METHOD(ike_sa_t, set_state, void,
private_ike_sa_t *this, ike_sa_state_t state)
{
+ bool trigger_dpd = FALSE;
+
DBG2(DBG_IKE, "IKE_SA %s[%d] state change: %N => %N",
get_name(this), this->unique_id,
ike_sa_state_names, this->state,
@@ -675,28 +686,20 @@ METHOD(ike_sa_t, set_state, void,
lib->scheduler->schedule_job(lib->scheduler, job, t);
DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t);
}
-
- /* start DPD checks */
- if (this->peer_cfg->get_dpd(this->peer_cfg))
- {
- send_dpd(this);
- }
+ trigger_dpd = this->peer_cfg->get_dpd(this->peer_cfg);
}
break;
}
- case IKE_DELETING:
- {
- /* 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);
- lib->scheduler->schedule_job(lib->scheduler, job,
- HALF_OPEN_IKE_SA_TIMEOUT);
- break;
- }
default:
break;
}
charon->bus->ike_state_change(charon->bus, &this->public, state);
this->state = state;
+
+ if (trigger_dpd)
+ {
+ send_dpd(this);
+ }
}
METHOD(ike_sa_t, reset, void,
@@ -768,17 +771,37 @@ METHOD(ike_sa_t, get_virtual_ip, host_t*,
}
}
-METHOD(ike_sa_t, add_additional_address, void,
+METHOD(ike_sa_t, add_peer_address, void,
private_ike_sa_t *this, host_t *host)
{
- this->additional_addresses->insert_last(this->additional_addresses, host);
+ this->peer_addresses->insert_last(this->peer_addresses, host);
}
-METHOD(ike_sa_t, create_additional_address_iterator, iterator_t*,
+METHOD(ike_sa_t, create_peer_address_enumerator, enumerator_t*,
private_ike_sa_t *this)
{
- return this->additional_addresses->create_iterator(
- this->additional_addresses, TRUE);
+ if (this->peer_addresses->get_count(this->peer_addresses))
+ {
+ return this->peer_addresses->create_enumerator(this->peer_addresses);
+ }
+ /* in case we don't have MOBIKE */
+ return enumerator_create_single(this->other_host, NULL);
+}
+
+METHOD(ike_sa_t, clear_peer_addresses, void,
+ private_ike_sa_t *this)
+{
+ enumerator_t *enumerator;
+ host_t *host;
+
+ enumerator = this->peer_addresses->create_enumerator(this->peer_addresses);
+ while (enumerator->enumerate(enumerator, (void**)&host))
+ {
+ this->peer_addresses->remove_at(this->peer_addresses,
+ enumerator);
+ host->destroy(host);
+ }
+ enumerator->destroy(enumerator);
}
METHOD(ike_sa_t, has_mapping_changed, bool,
@@ -857,7 +880,7 @@ METHOD(ike_sa_t, update_hosts, void,
if (!other->equals(other, this->other_host))
{
- /* update others adress if we are NOT NATed */
+ /* update others address if we are NOT NATed */
if (force || !has_condition(this, COND_NAT_HERE))
{
set_other_host(this, other->clone(other));
@@ -869,11 +892,11 @@ METHOD(ike_sa_t, update_hosts, void,
/* update all associated CHILD_SAs, if required */
if (update)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
child_sa_t *child_sa;
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = this->child_sas->create_enumerator(this->child_sas);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
if (child_sa->update(child_sa, this->my_host,
this->other_host, this->my_virtual_ip,
@@ -884,7 +907,7 @@ METHOD(ike_sa_t, update_hosts, void,
child_sa->get_spi(child_sa, TRUE));
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
}
@@ -1094,7 +1117,11 @@ METHOD(ike_sa_t, initiate, status_t,
if (this->state == IKE_CREATED)
{
- resolve_hosts(this);
+ if (this->my_host->is_anyaddr(this->my_host) ||
+ this->other_host->is_anyaddr(this->other_host))
+ {
+ resolve_hosts(this);
+ }
if (this->other_host->is_anyaddr(this->other_host)
#ifdef ME
@@ -1104,6 +1131,7 @@ METHOD(ike_sa_t, initiate, status_t,
{
child_cfg->destroy(child_cfg);
DBG1(DBG_IKE, "unable to initiate to %%any");
+ charon->bus->alert(charon->bus, ALERT_PEER_ADDR_FAILED);
return DESTROY_ME;
}
@@ -1289,7 +1317,8 @@ 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);
lib->scheduler->schedule_job(lib->scheduler, job,
- HALF_OPEN_IKE_SA_TIMEOUT);
+ lib->settings->get_int(lib->settings,
+ "charon.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT));
}
this->stats[STAT_INBOUND] = time_monotonic(NULL);
status = this->task_manager->process_message(this->task_manager,
@@ -1376,11 +1405,11 @@ METHOD(ike_sa_t, add_child_sa, void,
METHOD(ike_sa_t, get_child_sa, child_sa_t*,
private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi, bool inbound)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
child_sa_t *current, *found = NULL;
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = this->child_sas->create_enumerator(this->child_sas);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
if (current->get_spi(current, inbound) == spi &&
current->get_protocol(current) == protocol)
@@ -1388,14 +1417,26 @@ METHOD(ike_sa_t, get_child_sa, child_sa_t*,
found = current;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return found;
}
-METHOD(ike_sa_t, create_child_sa_iterator, iterator_t*,
+METHOD(ike_sa_t, get_child_count, int,
+ private_ike_sa_t *this)
+{
+ return this->child_sas->get_count(this->child_sas);
+}
+
+METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*,
private_ike_sa_t *this)
{
- return this->child_sas->create_iterator(this->child_sas, TRUE);
+ return this->child_sas->create_enumerator(this->child_sas);
+}
+
+METHOD(ike_sa_t, remove_child_sa, void,
+ private_ike_sa_t *this, enumerator_t *enumerator)
+{
+ this->child_sas->remove_at(this->child_sas, enumerator);
}
METHOD(ike_sa_t, rekey_child_sa, status_t,
@@ -1403,6 +1444,11 @@ METHOD(ike_sa_t, rekey_child_sa, status_t,
{
child_rekey_t *child_rekey;
+ if (this->state == IKE_PASSIVE)
+ {
+ return INVALID_STATE;
+ }
+
child_rekey = child_rekey_create(&this->public, protocol, spi);
this->task_manager->queue_task(this->task_manager, &child_rekey->task);
return this->task_manager->initiate(this->task_manager);
@@ -1413,6 +1459,11 @@ METHOD(ike_sa_t, delete_child_sa, status_t,
{
child_delete_t *child_delete;
+ if (this->state == IKE_PASSIVE)
+ {
+ return INVALID_STATE;
+ }
+
child_delete = child_delete_create(&this->public, protocol, spi);
this->task_manager->queue_task(this->task_manager, &child_delete->task);
return this->task_manager->initiate(this->task_manager);
@@ -1421,23 +1472,23 @@ METHOD(ike_sa_t, delete_child_sa, status_t,
METHOD(ike_sa_t, destroy_child_sa, status_t,
private_ike_sa_t *this, protocol_id_t protocol, u_int32_t spi)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
child_sa_t *child_sa;
status_t status = NOT_FOUND;
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = this->child_sas->create_enumerator(this->child_sas);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
if (child_sa->get_protocol(child_sa) == protocol &&
child_sa->get_spi(child_sa, TRUE) == spi)
{
+ this->child_sas->remove_at(this->child_sas, enumerator);
child_sa->destroy(child_sa);
- iterator->remove(iterator);
status = SUCCESS;
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return status;
}
@@ -1472,6 +1523,10 @@ METHOD(ike_sa_t, rekey, status_t,
{
ike_rekey_t *ike_rekey;
+ if (this->state == IKE_PASSIVE)
+ {
+ return INVALID_STATE;
+ }
ike_rekey = ike_rekey_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, &ike_rekey->task);
@@ -1483,6 +1538,10 @@ METHOD(ike_sa_t, reauth, status_t,
{
task_t *task;
+ if (this->state == IKE_PASSIVE)
+ {
+ return INVALID_STATE;
+ }
/* we can't reauthenticate as responder when we use EAP or virtual IPs.
* If the peer does not support RFC4478, there is no way to keep the
* IKE_SA up. */
@@ -1497,17 +1556,26 @@ METHOD(ike_sa_t, reauth, status_t,
#endif /* ME */
)
{
- time_t now = time_monotonic(NULL);
+ time_t del, now;
- DBG1(DBG_IKE, "IKE_SA will timeout in %V",
- &now, &this->stats[STAT_DELETE]);
+ del = this->stats[STAT_DELETE];
+ now = time_monotonic(NULL);
+ DBG1(DBG_IKE, "IKE_SA %s[%d] will timeout in %V",
+ get_name(this), this->unique_id, &now, &del);
return FAILED;
}
else
{
- DBG1(DBG_IKE, "reauthenticating actively");
+ DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d] actively",
+ get_name(this), this->unique_id);
}
}
+ else
+ {
+ DBG0(DBG_IKE, "reauthenticating IKE_SA %s[%d]",
+ get_name(this), this->unique_id);
+ }
+ this->is_reauthenticating = TRUE;
task = (task_t*)ike_reauth_create(&this->public);
this->task_manager->queue_task(this->task_manager, task);
@@ -1520,45 +1588,64 @@ METHOD(ike_sa_t, reestablish, status_t,
ike_sa_t *new;
host_t *host;
action_t action;
- iterator_t *iterator;
+ enumerator_t *enumerator;
child_sa_t *child_sa;
child_cfg_t *child_cfg;
bool restart = FALSE;
status_t status = FAILED;
- /* check if we have children to keep up at all */
- iterator = create_child_sa_iterator(this);
- while (iterator->iterate(iterator, (void**)&child_sa))
- {
- if (this->state == IKE_DELETING)
+ if (this->is_reauthenticating)
+ { /* only reauthenticate if we have children */
+ if (this->child_sas->get_count(this->child_sas) == 0
+#ifdef ME
+ /* allow reauth of mediation connections without CHILD_SAs */
+ && !this->peer_cfg->is_mediation(this->peer_cfg)
+#endif /* ME */
+ )
{
- action = child_sa->get_close_action(child_sa);
+ DBG1(DBG_IKE, "unable to reauthenticate IKE_SA, no CHILD_SA "
+ "to recreate");
}
else
{
- action = child_sa->get_dpd_action(child_sa);
+ restart = TRUE;
}
- switch (action)
+ }
+ else
+ { /* check if we have children to keep up at all */
+ enumerator = this->child_sas->create_enumerator(this->child_sas);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
- case ACTION_RESTART:
- restart = TRUE;
- break;
- case ACTION_ROUTE:
- charon->traps->install(charon->traps, this->peer_cfg,
- child_sa->get_config(child_sa));
- break;
- default:
- break;
+ if (this->state == IKE_DELETING)
+ {
+ action = child_sa->get_close_action(child_sa);
+ }
+ else
+ {
+ action = child_sa->get_dpd_action(child_sa);
+ }
+ switch (action)
+ {
+ case ACTION_RESTART:
+ restart = TRUE;
+ break;
+ case ACTION_ROUTE:
+ charon->traps->install(charon->traps, this->peer_cfg,
+ child_sa->get_config(child_sa));
+ break;
+ default:
+ break;
+ }
}
- }
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
#ifdef ME
- /* mediation connections have no children, keep them up anyway */
- if (this->peer_cfg->is_mediation(this->peer_cfg))
- {
- restart = TRUE;
- }
+ /* mediation connections have no children, keep them up anyway */
+ if (this->peer_cfg->is_mediation(this->peer_cfg))
+ {
+ restart = TRUE;
+ }
#endif /* ME */
+ }
if (!restart)
{
return FAILED;
@@ -1598,16 +1685,37 @@ METHOD(ike_sa_t, reestablish, status_t,
else
#endif /* ME */
{
- iterator = create_child_sa_iterator(this);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = this->child_sas->create_enumerator(this->child_sas);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
- if (this->state == IKE_DELETING)
+ if (this->is_reauthenticating)
{
- action = child_sa->get_close_action(child_sa);
+ switch (child_sa->get_state(child_sa))
+ {
+ case CHILD_ROUTED:
+ { /* move routed child directly */
+ this->child_sas->remove_at(this->child_sas, enumerator);
+ new->add_child_sa(new, child_sa);
+ action = ACTION_NONE;
+ break;
+ }
+ default:
+ { /* initiate/queue all other CHILD_SAs */
+ action = ACTION_RESTART;
+ break;
+ }
+ }
}
else
- {
- action = child_sa->get_dpd_action(child_sa);
+ { /* only restart CHILD_SAs that are configured accordingly */
+ if (this->state == IKE_DELETING)
+ {
+ action = child_sa->get_close_action(child_sa);
+ }
+ else
+ {
+ action = child_sa->get_dpd_action(child_sa);
+ }
}
switch (action)
{
@@ -1626,7 +1734,7 @@ METHOD(ike_sa_t, reestablish, status_t,
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
if (status == DESTROY_ME)
@@ -1680,6 +1788,10 @@ static void requeue_init_tasks(private_ike_sa_t *this)
METHOD(ike_sa_t, retransmit, status_t,
private_ike_sa_t *this, u_int32_t message_id)
{
+ if (this->state == IKE_PASSIVE)
+ {
+ return INVALID_STATE;
+ }
this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
if (this->task_manager->retransmit(this->task_manager, message_id) != SUCCESS)
{
@@ -1696,6 +1808,7 @@ METHOD(ike_sa_t, retransmit, status_t,
DBG1(DBG_IKE, "peer not responding, trying again (%d/%d)",
this->keyingtry + 1, tries);
reset(this);
+ resolve_hosts(this);
requeue_init_tasks(this);
return this->task_manager->initiate(this->task_manager);
}
@@ -1704,6 +1817,12 @@ METHOD(ike_sa_t, retransmit, status_t,
}
case IKE_DELETING:
DBG1(DBG_IKE, "proper IKE_SA delete failed, peer not responding");
+ if (this->is_reauthenticating)
+ {
+ DBG1(DBG_IKE, "delete during reauthentication failed, "
+ "trying to reestablish IKE_SA anyway");
+ reestablish(this);
+ }
break;
case IKE_REKEYING:
DBG1(DBG_IKE, "rekeying IKE_SA failed, peer not responding");
@@ -1717,35 +1836,67 @@ METHOD(ike_sa_t, retransmit, status_t,
return SUCCESS;
}
-METHOD(ike_sa_t, set_auth_lifetime, void,
+METHOD(ike_sa_t, set_auth_lifetime, status_t,
private_ike_sa_t *this, u_int32_t lifetime)
{
- u_int32_t reduction = this->peer_cfg->get_over_time(this->peer_cfg);
- u_int32_t reauth_time = time_monotonic(NULL) + lifetime - reduction;
+ u_int32_t diff, hard, soft, now;
+ ike_auth_lifetime_t *task;
+ bool send_update;
- if (lifetime < reduction)
+ diff = this->peer_cfg->get_over_time(this->peer_cfg);
+ now = time_monotonic(NULL);
+ hard = now + lifetime;
+ soft = hard - diff;
+
+ /* check if we have to send an AUTH_LIFETIME to enforce the new lifetime.
+ * We send the notify in IKE_AUTH if not yet ESTABLISHED. */
+ send_update = this->state == IKE_ESTABLISHED &&
+ !has_condition(this, COND_ORIGINAL_INITIATOR) &&
+ (this->other_virtual_ip != NULL ||
+ has_condition(this, COND_EAP_AUTHENTICATED));
+
+ if (lifetime < diff)
{
- DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, starting reauthentication",
- lifetime);
- lib->processor->queue_job(lib->processor,
+ this->stats[STAT_REAUTH] = now;
+
+ if (!send_update)
+ {
+ DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, "
+ "starting reauthentication", lifetime);
+ 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 ||
- this->stats[STAT_REAUTH] > reauth_time)
+ this->stats[STAT_REAUTH] > soft)
{
- this->stats[STAT_REAUTH] = reauth_time;
- DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling reauthentication"
- " in %ds", lifetime, lifetime - reduction);
- lib->scheduler->schedule_job(lib->scheduler,
+ this->stats[STAT_REAUTH] = soft;
+ if (!send_update)
+ {
+ DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling "
+ "reauthentication in %ds", lifetime, lifetime - diff);
+ lib->scheduler->schedule_job(lib->scheduler,
(job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE),
- lifetime - reduction);
+ lifetime - diff);
+ }
}
else
{
DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, "
"reauthentication already scheduled in %ds", lifetime,
this->stats[STAT_REAUTH] - time_monotonic(NULL));
+ send_update = FALSE;
}
+ /* give at least some seconds to reauthenticate */
+ this->stats[STAT_DELETE] = max(hard, now + 10);
+
+ if (send_update)
+ {
+ task = ike_auth_lifetime_create(&this->public, TRUE);
+ this->task_manager->queue_task(this->task_manager, &task->task);
+ return this->task_manager->initiate(this->task_manager);
+ }
+ return SUCCESS;
}
/**
@@ -1776,26 +1927,21 @@ static bool is_any_path_valid(private_ike_sa_t *this)
{
bool valid = FALSE;
enumerator_t *enumerator;
- host_t *src, *addr;
+ host_t *src = NULL, *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 = create_peer_address_enumerator(this);
+ while (enumerator->enumerate(enumerator, &addr))
{
- 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)
{
- 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;
- }
+ break;
}
- enumerator->destroy(enumerator);
}
+ enumerator->destroy(enumerator);
if (src)
{
valid = TRUE;
@@ -1874,6 +2020,8 @@ METHOD(ike_sa_t, roam, status_t,
return SUCCESS;
}
DBG1(DBG_IKE, "reauthenticating IKE_SA due to address change");
+ /* since our previous path is not valid anymore, try and find a new one */
+ resolve_hosts(this);
return reauth(this);
}
@@ -1902,6 +2050,8 @@ METHOD(ike_sa_t, inherit, void,
private_ike_sa_t *other = (private_ike_sa_t*)other_public;
child_sa_t *child_sa;
attribute_entry_t *entry;
+ enumerator_t *enumerator;
+ auth_cfg_t *cfg;
/* apply hosts and ids */
this->my_host->destroy(this->my_host);
@@ -1925,6 +2075,20 @@ METHOD(ike_sa_t, inherit, void,
other->other_virtual_ip = NULL;
}
+ /* authentication information */
+ enumerator = other->my_auths->create_enumerator(other->my_auths);
+ while (enumerator->enumerate(enumerator, &cfg))
+ {
+ this->my_auths->insert_last(this->my_auths, cfg->clone(cfg));
+ }
+ enumerator->destroy(enumerator);
+ enumerator = other->other_auths->create_enumerator(other->other_auths);
+ while (enumerator->enumerate(enumerator, &cfg))
+ {
+ this->other_auths->insert_last(this->other_auths, cfg->clone(cfg));
+ }
+ enumerator->destroy(enumerator);
+
/* ... and configuration attributes */
while (other->attributes->remove_last(other->attributes,
(void**)&entry) == SUCCESS)
@@ -2023,8 +2187,8 @@ METHOD(ike_sa_t, destroy, void,
}
this->other_virtual_ip->destroy(this->other_virtual_ip);
}
- this->additional_addresses->destroy_offset(this->additional_addresses,
- offsetof(host_t, destroy));
+ this->peer_addresses->destroy_offset(this->peer_addresses,
+ offsetof(host_t, destroy));
#ifdef ME
if (this->is_mediation_server)
{
@@ -2101,8 +2265,9 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
.has_condition = _has_condition,
.set_pending_updates = _set_pending_updates,
.get_pending_updates = _get_pending_updates,
- .create_additional_address_iterator = _create_additional_address_iterator,
- .add_additional_address = _add_additional_address,
+ .create_peer_address_enumerator = _create_peer_address_enumerator,
+ .add_peer_address = _add_peer_address,
+ .clear_peer_addresses = _clear_peer_addresses,
.has_mapping_changed = _has_mapping_changed,
.retransmit = _retransmit,
.delete = _delete_,
@@ -2112,7 +2277,9 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
.get_keymat = _get_keymat,
.add_child_sa = _add_child_sa,
.get_child_sa = _get_child_sa,
- .create_child_sa_iterator = _create_child_sa_iterator,
+ .get_child_count = _get_child_count,
+ .create_child_sa_enumerator = _create_child_sa_enumerator,
+ .remove_child_sa = _remove_child_sa,
.rekey_child_sa = _rekey_child_sa,
.delete_child_sa = _delete_child_sa,
.destroy_child_sa = _destroy_child_sa,
@@ -2156,13 +2323,13 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
.other_auth = auth_cfg_create(),
.my_auths = linked_list_create(),
.other_auths = linked_list_create(),
- .task_manager = task_manager_create(&this->public),
.unique_id = ++unique_id,
- .additional_addresses = linked_list_create(),
+ .peer_addresses = linked_list_create(),
.attributes = linked_list_create(),
.keepalive_interval = lib->settings->get_time(lib->settings,
"charon.keep_alive", KEEPALIVE_INTERVAL),
);
+ this->task_manager = task_manager_create(&this->public);
this->my_host->set_port(this->my_host, IKEV2_UDP_PORT);
return &this->public;
diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h
index 69a74d8b7..537565e89 100644
--- a/src/libcharon/sa/ike_sa.h
+++ b/src/libcharon/sa/ike_sa.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2008 Tobias Brunner
+ * Copyright (C) 2006-2012 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -97,6 +97,11 @@ enum ike_extension_t {
* peer supports EAP-only authentication, draft-eronen-ipsec-ikev2-eap-auth
*/
EXT_EAP_ONLY_AUTHENTICATION = (1<<5),
+
+ /**
+ * peer is probably a Windows 7 RAS client
+ */
+ EXT_MS_WINDOWS = (1<<6),
};
/**
@@ -260,14 +265,14 @@ struct ike_sa_t {
*
* Returned ike_sa_id_t object is not getting cloned!
*
- * @return ike_sa's ike_sa_id_t
+ * @return ike_sa's ike_sa_id_t
*/
ike_sa_id_t* (*get_id) (ike_sa_t *this);
/**
* Get the numerical ID uniquely defining this IKE_SA.
*
- * @return unique ID
+ * @return unique ID
*/
u_int32_t (*get_unique_id) (ike_sa_t *this);
@@ -469,14 +474,19 @@ struct ike_sa_t {
*
* @param host host to add to list
*/
- void (*add_additional_address)(ike_sa_t *this, host_t *host);
+ void (*add_peer_address)(ike_sa_t *this, host_t *host);
/**
- * Create an iterator over all additional addresses of the peer.
+ * Create an enumerator over all known addresses of the peer.
*
- * @return iterator over addresses
+ * @return enumerator over addresses
+ */
+ enumerator_t* (*create_peer_address_enumerator)(ike_sa_t *this);
+
+ /**
+ * Remove all known addresses of the peer.
*/
- iterator_t* (*create_additional_address_iterator)(ike_sa_t *this);
+ void (*clear_peer_addresses)(ike_sa_t *this);
/**
* Check if mappings have changed on a NAT for our source address.
@@ -567,8 +577,8 @@ struct ike_sa_t {
*
* @param mediated_cfg peer_cfg of the mediated connection
* @return
- * - SUCCESS if initialization started
- * - DESTROY_ME if initialization failed
+ * - SUCCESS if initialization started
+ * - DESTROY_ME if initialization failed
*/
status_t (*initiate_mediation) (ike_sa_t *this, peer_cfg_t *mediated_cfg);
@@ -579,8 +589,8 @@ struct ike_sa_t {
* @param other remote endpoint (gets cloned)
* @param connect_id connect ID (gets cloned)
* @return
- * - SUCCESS if initialization started
- * - DESTROY_ME if initialization failed
+ * - SUCCESS if initialization started
+ * - DESTROY_ME if initialization failed
*/
status_t (*initiate_mediated) (ike_sa_t *this, host_t *me, host_t *other,
chunk_t connect_id);
@@ -597,8 +607,8 @@ struct ike_sa_t {
* @param endpoints endpoints
* @param response TRUE if this is a response
* @return
- * - SUCCESS if relay started
- * - DESTROY_ME if relay failed
+ * - SUCCESS if relay started
+ * - DESTROY_ME if relay failed
*/
status_t (*relay) (ike_sa_t *this, identification_t *requester,
chunk_t connect_id, chunk_t connect_key,
@@ -611,8 +621,8 @@ struct ike_sa_t {
*
* @param peer_id ID of the other peer
* @return
- * - SUCCESS if response started
- * - DESTROY_ME if response failed
+ * - SUCCESS if response started
+ * - DESTROY_ME if response failed
*/
status_t (*callback) (ike_sa_t *this, identification_t *peer_id);
@@ -624,8 +634,8 @@ struct ike_sa_t {
* @param peer_id ID of the other peer
* @param connect_id the connect ID supplied by the initiator
* @return
- * - SUCCESS if response started
- * - DESTROY_ME if response failed
+ * - SUCCESS if response started
+ * - DESTROY_ME if response failed
*/
status_t (*respond) (ike_sa_t *this, identification_t *peer_id,
chunk_t connect_id);
@@ -643,8 +653,8 @@ struct ike_sa_t {
* @param tsi source of triggering packet
* @param tsr destination of triggering packet.
* @return
- * - SUCCESS if initialization started
- * - DESTROY_ME if initialization failed
+ * - SUCCESS if initialization started
+ * - DESTROY_ME if initialization failed
*/
status_t (*initiate) (ike_sa_t *this, child_cfg_t *child_cfg,
u_int32_t reqid, traffic_selector_t *tsi,
@@ -658,10 +668,10 @@ struct ike_sa_t {
* the IKE SA gets deleted.
*
* @return
- * - SUCCESS if deletion is initialized
- * - DESTROY_ME, if the IKE_SA is not in
- * an established state and can not be
- * deleted (but destroyed).
+ * - SUCCESS if deletion is initialized
+ * - DESTROY_ME, if the IKE_SA is not in
+ * an established state and can not be
+ * deleted (but destroyed).
*/
status_t (*delete) (ike_sa_t *this);
@@ -684,13 +694,13 @@ struct ike_sa_t {
*
* Message processing may fail. If a critical failure occurs,
* process_message() return DESTROY_ME. Then the caller must
- * destroy the IKE_SA immediatly, as it is unusable.
+ * destroy the IKE_SA immediately, as it is unusable.
*
- * @param message message to process
+ * @param message message to process
* @return
- * - SUCCESS
- * - FAILED
- * - DESTROY_ME if this IKE_SA MUST be deleted
+ * - SUCCESS
+ * - FAILED
+ * - DESTROY_ME if this IKE_SA MUST be deleted
*/
status_t (*process_message) (ike_sa_t *this, message_t *message);
@@ -700,12 +710,12 @@ struct ike_sa_t {
* This method generates all payloads in the message and encrypts/signs
* the packet.
*
- * @param message message to generate
+ * @param message message to generate
* @param packet generated output packet
* @return
- * - SUCCESS
- * - FAILED
- * - DESTROY_ME if this IKE_SA MUST be deleted
+ * - SUCCESS
+ * - FAILED
+ * - DESTROY_ME if this IKE_SA MUST be deleted
*/
status_t (*generate_message) (ike_sa_t *this, message_t *message,
packet_t **packet);
@@ -715,8 +725,8 @@ struct ike_sa_t {
*
* @param message_id ID of the request to retransmit
* @return
- * - SUCCESS
- * - NOT_FOUND if request doesn't have to be retransmited
+ * - SUCCESS
+ * - NOT_FOUND if request doesn't have to be retransmited
*/
status_t (*retransmit) (ike_sa_t *this, u_int32_t message_id);
@@ -728,8 +738,8 @@ struct ike_sa_t {
* other traffic was received.
*
* @return
- * - SUCCESS
- * - DESTROY_ME, if peer did not respond
+ * - SUCCESS
+ * - DESTROY_ME, if peer did not respond
*/
status_t (*send_dpd) (ike_sa_t *this);
@@ -769,11 +779,25 @@ struct ike_sa_t {
u_int32_t spi, bool inbound);
/**
- * Create an iterator over all CHILD_SAs.
+ * Get the number of CHILD_SAs.
+ *
+ * @return number of CHILD_SAs
+ */
+ int (*get_child_count) (ike_sa_t *this);
+
+ /**
+ * Create an enumerator over all CHILD_SAs.
+ *
+ * @return enumerator
+ */
+ enumerator_t* (*create_child_sa_enumerator) (ike_sa_t *this);
+
+ /**
+ * Remove the CHILD_SA the given enumerator points to from this IKE_SA.
*
- * @return iterator
+ * @param enumerator enumerator pointing to CHILD_SA
*/
- iterator_t* (*create_child_sa_iterator) (ike_sa_t *this);
+ void (*remove_child_sa) (ike_sa_t *this, enumerator_t *enumerator);
/**
* Rekey the CHILD SA with the specified reqid.
@@ -783,8 +807,8 @@ struct ike_sa_t {
* @param protocol protocol of the SA
* @param spi inbound SPI of the CHILD_SA
* @return
- * - NOT_FOUND, if IKE_SA has no such CHILD_SA
- * - SUCCESS, if rekeying initiated
+ * - NOT_FOUND, if IKE_SA has no such CHILD_SA
+ * - SUCCESS, if rekeying initiated
*/
status_t (*rekey_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
@@ -798,8 +822,8 @@ struct ike_sa_t {
* @param protocol protocol of the SA
* @param spi inbound SPI of the CHILD_SA
* @return
- * - NOT_FOUND, if IKE_SA has no such CHILD_SA
- * - SUCCESS, if delete message sent
+ * - NOT_FOUND, if IKE_SA has no such CHILD_SA
+ * - SUCCESS, if delete message sent
*/
status_t (*delete_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
@@ -811,8 +835,8 @@ struct ike_sa_t {
* @param protocol protocol of the SA
* @param spi inbound SPI of the CHILD_SA
* @return
- * - NOT_FOUND, if IKE_SA has no such CHILD_SA
- * - SUCCESS
+ * - NOT_FOUND, if IKE_SA has no such CHILD_SA
+ * - SUCCESS
*/
status_t (*destroy_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
@@ -845,11 +869,15 @@ struct ike_sa_t {
status_t (*reestablish) (ike_sa_t *this);
/**
- * Set the lifetime limit received from a AUTH_LIFETIME notify.
+ * Set the lifetime limit received/to send in a AUTH_LIFETIME notify.
+ *
+ * If the IKE_SA is already ESTABLISHED, an INFORMATIONAL is sent with
+ * an AUTH_LIFETIME notify. The call never fails on unestablished SAs.
*
* @param lifetime lifetime in seconds
+ * @return DESTROY_ME to destroy the IKE_SA
*/
- void (*set_auth_lifetime)(ike_sa_t *this, u_int32_t lifetime);
+ status_t (*set_auth_lifetime)(ike_sa_t *this, u_int32_t lifetime);
/**
* Set the virtual IP to use for this IKE_SA and its children.
@@ -929,8 +957,8 @@ struct ike_sa_t {
/**
* Creates an ike_sa_t object with a specific ID.
*
- * @param ike_sa_id ike_sa_id_t object to associate with new IKE_SA
- * @return ike_sa_t object
+ * @param ike_sa_id ike_sa_id_t object to associate with new IKE_SA
+ * @return ike_sa_t object
*/
ike_sa_t *ike_sa_create(ike_sa_id_t *ike_sa_id);
diff --git a/src/libcharon/sa/ike_sa_id.c b/src/libcharon/sa/ike_sa_id.c
index 94c5405f2..bea4c2124 100644
--- a/src/libcharon/sa/ike_sa_id.c
+++ b/src/libcharon/sa/ike_sa_id.c
@@ -46,42 +46,32 @@ struct private_ike_sa_id_t {
bool is_initiator_flag;
};
-/**
- * Implementation of ike_sa_id_t.set_responder_spi.
- */
-static void set_responder_spi (private_ike_sa_id_t *this, u_int64_t responder_spi)
+METHOD(ike_sa_id_t, set_responder_spi, void,
+ private_ike_sa_id_t *this, u_int64_t responder_spi)
{
this->responder_spi = responder_spi;
}
-/**
- * Implementation of ike_sa_id_t.set_initiator_spi.
- */
-static void set_initiator_spi(private_ike_sa_id_t *this, u_int64_t initiator_spi)
+METHOD(ike_sa_id_t, set_initiator_spi, void,
+ private_ike_sa_id_t *this, u_int64_t initiator_spi)
{
this->initiator_spi = initiator_spi;
}
-/**
- * Implementation of ike_sa_id_t.get_initiator_spi.
- */
-static u_int64_t get_initiator_spi (private_ike_sa_id_t *this)
+METHOD(ike_sa_id_t, get_initiator_spi, u_int64_t,
+ private_ike_sa_id_t *this)
{
return this->initiator_spi;
}
-/**
- * Implementation of ike_sa_id_t.get_responder_spi.
- */
-static u_int64_t get_responder_spi (private_ike_sa_id_t *this)
+METHOD(ike_sa_id_t, get_responder_spi, u_int64_t,
+ private_ike_sa_id_t *this)
{
return this->responder_spi;
}
-/**
- * Implementation of ike_sa_id_t.equals.
- */
-static bool equals (private_ike_sa_id_t *this, private_ike_sa_id_t *other)
+METHOD(ike_sa_id_t, equals, bool,
+ private_ike_sa_id_t *this, private_ike_sa_id_t *other)
{
if (other == NULL)
{
@@ -101,28 +91,22 @@ static bool equals (private_ike_sa_id_t *this, private_ike_sa_id_t *other)
}
}
-/**
- * Implementation of ike_sa_id_t.replace_values.
- */
-static void replace_values(private_ike_sa_id_t *this, private_ike_sa_id_t *other)
+METHOD(ike_sa_id_t, replace_values, void,
+ private_ike_sa_id_t *this, private_ike_sa_id_t *other)
{
this->initiator_spi = other->initiator_spi;
this->responder_spi = other->responder_spi;
this->is_initiator_flag = other->is_initiator_flag;
}
-/**
- * Implementation of ike_sa_id_t.is_initiator.
- */
-static bool is_initiator(private_ike_sa_id_t *this)
+METHOD(ike_sa_id_t, is_initiator, bool,
+ private_ike_sa_id_t *this)
{
return this->is_initiator_flag;
}
-/**
- * Implementation of ike_sa_id_t.switch_initiator.
- */
-static bool switch_initiator(private_ike_sa_id_t *this)
+METHOD(ike_sa_id_t, switch_initiator, bool,
+ private_ike_sa_id_t *this)
{
if (this->is_initiator_flag)
{
@@ -135,18 +119,15 @@ static bool switch_initiator(private_ike_sa_id_t *this)
return this->is_initiator_flag;
}
-/**
- * Implementation of ike_sa_id_t.clone.
- */
-static ike_sa_id_t* clone_(private_ike_sa_id_t *this)
+METHOD(ike_sa_id_t, clone_, ike_sa_id_t*,
+ private_ike_sa_id_t *this)
{
- return ike_sa_id_create(this->initiator_spi, this->responder_spi, this->is_initiator_flag);
+ return ike_sa_id_create(this->initiator_spi, this->responder_spi,
+ this->is_initiator_flag);
}
-/**
- * Implementation of ike_sa_id_t.destroy.
- */
-static void destroy(private_ike_sa_id_t *this)
+METHOD(ike_sa_id_t, destroy, void,
+ private_ike_sa_id_t *this)
{
free(this);
}
@@ -154,26 +135,28 @@ static void destroy(private_ike_sa_id_t *this)
/*
* Described in header.
*/
-ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, bool is_initiator_flag)
+ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi,
+ bool is_initiator_flag)
{
- private_ike_sa_id_t *this = malloc_thing(private_ike_sa_id_t);
-
- /* public functions */
- this->public.set_responder_spi = (void(*)(ike_sa_id_t*,u_int64_t)) set_responder_spi;
- this->public.set_initiator_spi = (void(*)(ike_sa_id_t*,u_int64_t)) set_initiator_spi;
- this->public.get_responder_spi = (u_int64_t(*)(ike_sa_id_t*)) get_responder_spi;
- this->public.get_initiator_spi = (u_int64_t(*)(ike_sa_id_t*)) get_initiator_spi;
- this->public.equals = (bool(*)(ike_sa_id_t*,ike_sa_id_t*)) equals;
- this->public.replace_values = (void(*)(ike_sa_id_t*,ike_sa_id_t*)) replace_values;
- this->public.is_initiator = (bool(*)(ike_sa_id_t*)) is_initiator;
- this->public.switch_initiator = (bool(*)(ike_sa_id_t*)) switch_initiator;
- this->public.clone = (ike_sa_id_t*(*)(ike_sa_id_t*)) clone_;
- this->public.destroy = (void(*)(ike_sa_id_t*))destroy;
-
- /* private data */
- this->initiator_spi = initiator_spi;
- this->responder_spi = responder_spi;
- this->is_initiator_flag = is_initiator_flag;
+ private_ike_sa_id_t *this;
+
+ INIT(this,
+ .public = {
+ .set_responder_spi = _set_responder_spi,
+ .set_initiator_spi = _set_initiator_spi,
+ .get_responder_spi = _get_responder_spi,
+ .get_initiator_spi = _get_initiator_spi,
+ .equals = (void*)_equals,
+ .replace_values = (void*)_replace_values,
+ .is_initiator = _is_initiator,
+ .switch_initiator = _switch_initiator,
+ .clone = _clone_,
+ .destroy = _destroy,
+ },
+ .initiator_spi = initiator_spi,
+ .responder_spi = responder_spi,
+ .is_initiator_flag = is_initiator_flag,
+ );
return &this->public;
}
diff --git a/src/libcharon/sa/ike_sa_id.h b/src/libcharon/sa/ike_sa_id.h
index a833aa9d6..fb55359bc 100644
--- a/src/libcharon/sa/ike_sa_id.h
+++ b/src/libcharon/sa/ike_sa_id.h
@@ -30,7 +30,7 @@ typedef struct ike_sa_id_t ike_sa_id_t;
* An object of type ike_sa_id_t is used to identify an IKE_SA.
*
* An IKE_SA is identified by its initiator and responder spi's.
- * Additionaly it contains the role of the actual running IKEv2-Daemon
+ * Additionally it contains the role of the actual running IKEv2 daemon
* for the specific IKE_SA (original initiator or responder).
*/
struct ike_sa_id_t {
@@ -40,28 +40,28 @@ struct ike_sa_id_t {
*
* This function is called when a request or reply of a IKE_SA_INIT is received.
*
- * @param responder_spi SPI of responder to set
+ * @param responder_spi SPI of responder to set
*/
void (*set_responder_spi) (ike_sa_id_t *this, u_int64_t responder_spi);
/**
* Set the SPI of the initiator.
*
- * @param initiator_spi SPI to set
+ * @param initiator_spi SPI to set
*/
void (*set_initiator_spi) (ike_sa_id_t *this, u_int64_t initiator_spi);
/**
* Get the initiator SPI.
*
- * @return SPI of the initiator
+ * @return SPI of the initiator
*/
u_int64_t (*get_initiator_spi) (ike_sa_id_t *this);
/**
* Get the responder SPI.
*
- * @return SPI of the responder
+ * @return SPI of the responder
*/
u_int64_t (*get_responder_spi) (ike_sa_id_t *this);
@@ -70,8 +70,8 @@ struct ike_sa_id_t {
*
* Two ike_sa_id_t objects are equal if both SPI values and the role matches.
*
- * @param other ike_sa_id_t object to check if equal
- * @return TRUE if given ike_sa_id_t are equal, FALSE otherwise
+ * @param other ike_sa_id_t object to check if equal
+ * @return TRUE if given ike_sa_id_t are equal, FALSE otherwise
*/
bool (*equals) (ike_sa_id_t *this, ike_sa_id_t *other);
@@ -81,28 +81,28 @@ struct ike_sa_id_t {
*
* After calling this function, both objects are equal.
*
- * @param other ike_sa_id_t object from which values will be taken
+ * @param other ike_sa_id_t object from which values will be taken
*/
void (*replace_values) (ike_sa_id_t *this, ike_sa_id_t *other);
/**
* Get the initiator flag.
*
- * @return TRUE if we are the original initator
+ * @return TRUE if we are the original initiator
*/
bool (*is_initiator) (ike_sa_id_t *this);
/**
* Switche the original initiator flag.
*
- * @return TRUE if we are the original initator after switch, FALSE otherwise
+ * @return TRUE if we are the original initiator after switch, FALSE otherwise
*/
bool (*switch_initiator) (ike_sa_id_t *this);
/**
* Clones a given ike_sa_id_t object.
*
- * @return cloned ike_sa_id_t object
+ * @return cloned ike_sa_id_t object
*/
ike_sa_id_t *(*clone) (ike_sa_id_t *this);
diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index d695c7f7c..731ae6007 100644
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -307,72 +307,72 @@ struct private_ike_sa_manager_t {
/**
* Public interface of ike_sa_manager_t.
*/
- ike_sa_manager_t public;
-
- /**
- * Hash table with entries for the ike_sa_t objects.
- */
- linked_list_t **ike_sa_table;
-
- /**
- * The size of the hash table.
- */
- u_int table_size;
-
- /**
- * Mask to map the hashes to table rows.
- */
- u_int table_mask;
-
- /**
- * Segments of the hash table.
- */
- segment_t *segments;
-
- /**
- * The number of segments.
- */
- u_int segment_count;
-
- /**
- * Mask to map a table row to a segment.
- */
- u_int segment_mask;
-
- /**
- * Hash table with half_open_t objects.
- */
- linked_list_t **half_open_table;
-
- /**
+ ike_sa_manager_t public;
+
+ /**
+ * Hash table with entries for the ike_sa_t objects.
+ */
+ linked_list_t **ike_sa_table;
+
+ /**
+ * The size of the hash table.
+ */
+ u_int table_size;
+
+ /**
+ * Mask to map the hashes to table rows.
+ */
+ u_int table_mask;
+
+ /**
+ * Segments of the hash table.
+ */
+ segment_t *segments;
+
+ /**
+ * The number of segments.
+ */
+ u_int segment_count;
+
+ /**
+ * Mask to map a table row to a segment.
+ */
+ u_int segment_mask;
+
+ /**
+ * Hash table with half_open_t objects.
+ */
+ linked_list_t **half_open_table;
+
+ /**
* Segments of the "half-open" hash table.
- */
- shareable_segment_t *half_open_segments;
+ */
+ shareable_segment_t *half_open_segments;
- /**
- * Hash table with connected_peers_t objects.
- */
- linked_list_t **connected_peers_table;
+ /**
+ * Hash table with connected_peers_t objects.
+ */
+ linked_list_t **connected_peers_table;
- /**
- * Segments of the "connected peers" hash table.
- */
- shareable_segment_t *connected_peers_segments;
+ /**
+ * Segments of the "connected peers" hash table.
+ */
+ shareable_segment_t *connected_peers_segments;
- /**
- * RNG to get random SPIs for our side
- */
- rng_t *rng;
+ /**
+ * RNG to get random SPIs for our side
+ */
+ rng_t *rng;
- /**
- * SHA1 hasher for IKE_SA_INIT retransmit detection
- */
- hasher_t *hasher;
+ /**
+ * SHA1 hasher for IKE_SA_INIT retransmit detection
+ */
+ hasher_t *hasher;
/**
* reuse existing IKE_SAs in checkout_by_config
*/
- bool reuse_ikesa;
+ bool reuse_ikesa;
};
/**
@@ -1134,8 +1134,7 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*,
METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*,
private_ike_sa_manager_t *this, u_int32_t id, bool child)
{
- enumerator_t *enumerator;
- iterator_t *children;
+ enumerator_t *enumerator, *children;
entry_t *entry;
ike_sa_t *ike_sa = NULL;
child_sa_t *child_sa;
@@ -1151,8 +1150,8 @@ METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*,
/* look for a child with such a reqid ... */
if (child)
{
- children = entry->ike_sa->create_child_sa_iterator(entry->ike_sa);
- while (children->iterate(children, (void**)&child_sa))
+ children = entry->ike_sa->create_child_sa_enumerator(entry->ike_sa);
+ while (children->enumerate(children, (void**)&child_sa))
{
if (child_sa->get_reqid(child_sa) == id)
{
@@ -1188,8 +1187,7 @@ METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*,
METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*,
private_ike_sa_manager_t *this, char *name, bool child)
{
- enumerator_t *enumerator;
- iterator_t *children;
+ enumerator_t *enumerator, *children;
entry_t *entry;
ike_sa_t *ike_sa = NULL;
child_sa_t *child_sa;
@@ -1203,8 +1201,8 @@ METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*,
/* look for a child with such a policy name ... */
if (child)
{
- children = entry->ike_sa->create_child_sa_iterator(entry->ike_sa);
- while (children->iterate(children, (void**)&child_sa))
+ children = entry->ike_sa->create_child_sa_enumerator(entry->ike_sa);
+ while (children->enumerate(children, (void**)&child_sa))
{
if (streq(child_sa->get_name(child_sa), name))
{
@@ -1238,10 +1236,10 @@ METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*,
}
/**
- * enumerator filter function
+ * enumerator filter function, waiting variant
*/
-static bool enumerator_filter(private_ike_sa_manager_t *this,
- entry_t **in, ike_sa_t **out, u_int *segment)
+static bool enumerator_filter_wait(private_ike_sa_manager_t *this,
+ entry_t **in, ike_sa_t **out, u_int *segment)
{
if (wait_for_entry(this, *in, *segment))
{
@@ -1251,11 +1249,28 @@ static bool enumerator_filter(private_ike_sa_manager_t *this,
return FALSE;
}
+/**
+ * enumerator filter function, skipping variant
+ */
+static bool enumerator_filter_skip(private_ike_sa_manager_t *this,
+ entry_t **in, ike_sa_t **out, u_int *segment)
+{
+ if (!(*in)->driveout_new_threads &&
+ !(*in)->driveout_waiting_threads &&
+ !(*in)->checked_out)
+ {
+ *out = (*in)->ike_sa;
+ return TRUE;
+ }
+ return FALSE;
+}
+
METHOD(ike_sa_manager_t, create_enumerator, enumerator_t*,
- private_ike_sa_manager_t* this)
+ private_ike_sa_manager_t* this, bool wait)
{
return enumerator_create_filter(create_table_enumerator(this),
- (void*)enumerator_filter, this, NULL);
+ wait ? (void*)enumerator_filter_wait : (void*)enumerator_filter_skip,
+ this, NULL);
}
METHOD(ike_sa_manager_t, checkin, void,
@@ -1539,14 +1554,30 @@ METHOD(ike_sa_manager_t, has_contact, bool,
return found;
}
-METHOD(ike_sa_manager_t, get_half_open_count, int,
+METHOD(ike_sa_manager_t, get_count, u_int,
+ private_ike_sa_manager_t *this)
+{
+ u_int segment, count = 0;
+ mutex_t *mutex;
+
+ for (segment = 0; segment < this->segment_count; segment++)
+ {
+ mutex = this->segments[segment & this->segment_mask].mutex;
+ mutex->lock(mutex);
+ count += this->segments[segment].count;
+ mutex->unlock(mutex);
+ }
+ return count;
+}
+
+METHOD(ike_sa_manager_t, get_half_open_count, u_int,
private_ike_sa_manager_t *this, host_t *ip)
{
linked_list_t *list;
u_int segment, row;
rwlock_t *lock;
chunk_t addr;
- int count = 0;
+ u_int count = 0;
if (ip)
{
@@ -1728,6 +1759,7 @@ ike_sa_manager_t *ike_sa_manager_create()
.create_enumerator = _create_enumerator,
.checkin = _checkin,
.checkin_and_destroy = _checkin_and_destroy,
+ .get_count = _get_count,
.get_half_open_count = _get_half_open_count,
.flush = _flush,
.destroy = _destroy,
diff --git a/src/libcharon/sa/ike_sa_manager.h b/src/libcharon/sa/ike_sa_manager.h
index ec157ab3a..5e542e7df 100644
--- a/src/libcharon/sa/ike_sa_manager.h
+++ b/src/libcharon/sa/ike_sa_manager.h
@@ -162,9 +162,10 @@ struct ike_sa_manager_t {
* While enumerating an IKE_SA, it is temporarily checked out and
* automatically checked in after the current enumeration step.
*
+ * @param wait TRUE to wait for checked out SAs, FALSE to skip
* @return enumerator over all IKE_SAs.
*/
- enumerator_t *(*create_enumerator) (ike_sa_manager_t* this);
+ enumerator_t *(*create_enumerator) (ike_sa_manager_t* this, bool wait);
/**
* Checkin the SA after usage.
@@ -191,6 +192,13 @@ struct ike_sa_manager_t {
void (*checkin_and_destroy) (ike_sa_manager_t* this, ike_sa_t *ike_sa);
/**
+ * Get the number of IKE_SAs currently registered.
+ *
+ * @return number of registered IKE_SAs
+ */
+ u_int (*get_count)(ike_sa_manager_t *this);
+
+ /**
* Get the number of IKE_SAs which are in the connecting state.
*
* To prevent the server from resource exhaustion, cookies and other
@@ -203,7 +211,7 @@ struct ike_sa_manager_t {
* @param ip NULL for all, IP for half open IKE_SAs with IP
* @return number of half open IKE_SAs
*/
- int (*get_half_open_count) (ike_sa_manager_t *this, host_t *ip);
+ u_int (*get_half_open_count) (ike_sa_manager_t *this, host_t *ip);
/**
* Delete all existing IKE_SAs and destroy them immediately.
diff --git a/src/libcharon/sa/keymat.c b/src/libcharon/sa/keymat.c
index 33ece24b2..d762fa34e 100644
--- a/src/libcharon/sa/keymat.c
+++ b/src/libcharon/sa/keymat.c
@@ -99,7 +99,9 @@ keylen_entry_t keylen_enc[] = {
*/
keylen_entry_t keylen_int[] = {
{AUTH_HMAC_MD5_96, 128},
+ {AUTH_HMAC_MD5_128, 128},
{AUTH_HMAC_SHA1_96, 160},
+ {AUTH_HMAC_SHA1_160, 160},
{AUTH_HMAC_SHA2_256_96, 256},
{AUTH_HMAC_SHA2_256_128, 256},
{AUTH_HMAC_SHA2_384_192, 384},
diff --git a/src/libcharon/sa/keymat.h b/src/libcharon/sa/keymat.h
index 11e0fa79a..6c2b5d4b5 100644
--- a/src/libcharon/sa/keymat.h
+++ b/src/libcharon/sa/keymat.h
@@ -40,7 +40,12 @@ struct keymat_t {
*
* The diffie hellman is either for IKE negotiation/rekeying or
* CHILD_SA rekeying (using PFS). The resulting DH object must be passed
- * to derive_keys or to derive_child_keys and destroyed after use
+ * to derive_keys or to derive_child_keys and destroyed after use.
+ *
+ * Only DH objects allocated through this method are passed to other
+ * keymat_t methods, allowing private DH implementations. In some cases
+ * (such as retrying with a COOKIE), a DH object allocated from a different
+ * keymat_t instance may be passed to other methods.
*
* @param group diffie hellman group
* @return DH object, NULL if group not supported
diff --git a/src/libcharon/sa/mediation_manager.c b/src/libcharon/sa/mediation_manager.c
index 2fbab7c7c..60eeb5d4b 100644
--- a/src/libcharon/sa/mediation_manager.c
+++ b/src/libcharon/sa/mediation_manager.c
@@ -53,13 +53,12 @@ static void peer_destroy(peer_t *this)
*/
static peer_t *peer_create(identification_t *id, ike_sa_id_t* ike_sa_id)
{
- peer_t *this = malloc_thing(peer_t);
-
- /* clone everything */
- this->id = id->clone(id);
- this->ike_sa_id = ike_sa_id ? ike_sa_id->clone(ike_sa_id) : NULL;
- this->requested_by = linked_list_create();
-
+ peer_t *this;
+ INIT(this,
+ .id = id->clone(id),
+ .ike_sa_id = ike_sa_id ? ike_sa_id->clone(ike_sa_id) : NULL,
+ .requested_by = linked_list_create(),
+ );
return this;
}
@@ -90,19 +89,19 @@ struct private_mediation_manager_t {
*/
static void register_peer(peer_t *peer, identification_t *peer_id)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
identification_t *current;
- iterator = peer->requested_by->create_iterator(peer->requested_by, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = peer->requested_by->create_enumerator(peer->requested_by);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
if (peer_id->equals(peer_id, current))
{
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
peer->requested_by->insert_last(peer->requested_by,
peer_id->clone(peer_id));
@@ -114,12 +113,12 @@ static void register_peer(peer_t *peer, identification_t *peer_id)
static status_t get_peer_by_id(private_mediation_manager_t *this,
identification_t *id, peer_t **peer)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
peer_t *current;
status_t status = NOT_FOUND;
- iterator = this->peers->create_iterator(this->peers, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = this->peers->create_enumerator(this->peers);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
if (id->equals(id, current->id))
{
@@ -131,7 +130,7 @@ static status_t get_peer_by_id(private_mediation_manager_t *this,
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return status;
}
@@ -144,52 +143,50 @@ static status_t get_peer_by_id(private_mediation_manager_t *this,
static void unregister_peer(private_mediation_manager_t *this,
identification_t *peer_id)
{
- iterator_t *iterator, *iterator_r;
+ enumerator_t *enumerator, *enumerator_r;
peer_t *peer;
identification_t *registered;
- iterator = this->peers->create_iterator(this->peers, TRUE);
- while (iterator->iterate(iterator, (void**)&peer))
+ enumerator = this->peers->create_enumerator(this->peers);
+ while (enumerator->enumerate(enumerator, (void**)&peer))
{
- iterator_r = peer->requested_by->create_iterator(peer->requested_by,
- TRUE);
- while (iterator_r->iterate(iterator_r, (void**)&registered))
+ enumerator_r = peer->requested_by->create_enumerator(peer->requested_by);
+ while (enumerator_r->enumerate(enumerator_r, (void**)&registered))
{
if (peer_id->equals(peer_id, registered))
{
- iterator_r->remove(iterator_r);
+ peer->requested_by->remove_at(peer->requested_by, enumerator_r);
registered->destroy(registered);
break;
}
}
- iterator_r->destroy(iterator_r);
+ enumerator_r->destroy(enumerator_r);
- if (!peer->ike_sa_id && !peer->requested_by->get_count(peer->requested_by))
+ if (!peer->ike_sa_id &&
+ !peer->requested_by->get_count(peer->requested_by))
{
- iterator->remove(iterator);
+ this->peers->remove_at(this->peers, enumerator);
peer_destroy(peer);
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
-/**
- * Implementation of mediation_manager_t.remove
- */
-static void remove_sa(private_mediation_manager_t *this, ike_sa_id_t *ike_sa_id)
+METHOD(mediation_manager_t, remove_sa, void,
+ private_mediation_manager_t *this, ike_sa_id_t *ike_sa_id)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
peer_t *peer;
this->mutex->lock(this->mutex);
- iterator = this->peers->create_iterator(this->peers, TRUE);
- while (iterator->iterate(iterator, (void**)&peer))
+ enumerator = this->peers->create_enumerator(this->peers);
+ while (enumerator->enumerate(enumerator, (void**)&peer))
{
if (ike_sa_id->equals(ike_sa_id, peer->ike_sa_id))
{
- iterator->remove(iterator);
+ this->peers->remove_at(this->peers, enumerator);
unregister_peer(this, peer->id);
@@ -197,24 +194,23 @@ static void remove_sa(private_mediation_manager_t *this, ike_sa_id_t *ike_sa_id)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);
}
-/**
- * Implementation of mediation_manager_t.update_sa_id
- */
-static void update_sa_id(private_mediation_manager_t *this, identification_t *peer_id, ike_sa_id_t *ike_sa_id)
+METHOD(mediation_manager_t, update_sa_id, void,
+ private_mediation_manager_t *this, identification_t *peer_id,
+ ike_sa_id_t *ike_sa_id)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
peer_t *peer;
bool found = FALSE;
this->mutex->lock(this->mutex);
- iterator = this->peers->create_iterator(this->peers, TRUE);
- while (iterator->iterate(iterator, (void**)&peer))
+ enumerator = this->peers->create_enumerator(this->peers);
+ while (enumerator->enumerate(enumerator, (void**)&peer))
{
if (peer_id->equals(peer_id, peer->id))
{
@@ -223,7 +219,7 @@ static void update_sa_id(private_mediation_manager_t *this, identification_t *pe
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
if (!found)
{
@@ -248,11 +244,8 @@ static void update_sa_id(private_mediation_manager_t *this, identification_t *pe
this->mutex->unlock(this->mutex);
}
-/**
- * Implementation of mediation_manager_t.check.
- */
-static ike_sa_id_t *check(private_mediation_manager_t *this,
- identification_t *peer_id)
+METHOD(mediation_manager_t, check, ike_sa_id_t*,
+ private_mediation_manager_t *this, identification_t *peer_id)
{
peer_t *peer;
ike_sa_id_t *ike_sa_id;
@@ -272,11 +265,9 @@ static ike_sa_id_t *check(private_mediation_manager_t *this,
return ike_sa_id;
}
-/**
- * Implementation of mediation_manager_t.check_and_register.
- */
-static ike_sa_id_t *check_and_register(private_mediation_manager_t *this,
- identification_t *peer_id, identification_t *requester)
+METHOD(mediation_manager_t, check_and_register, ike_sa_id_t*,
+ private_mediation_manager_t *this, identification_t *peer_id,
+ identification_t *requester)
{
peer_t *peer;
ike_sa_id_t *ike_sa_id;
@@ -307,10 +298,8 @@ static ike_sa_id_t *check_and_register(private_mediation_manager_t *this,
return ike_sa_id;
}
-/**
- * Implementation of mediation_manager_t.destroy.
- */
-static void destroy(private_mediation_manager_t *this)
+METHOD(mediation_manager_t, destroy, void,
+ private_mediation_manager_t *this)
{
this->mutex->lock(this->mutex);
@@ -326,16 +315,18 @@ static void destroy(private_mediation_manager_t *this)
*/
mediation_manager_t *mediation_manager_create()
{
- private_mediation_manager_t *this = malloc_thing(private_mediation_manager_t);
-
- this->public.destroy = (void(*)(mediation_manager_t*))destroy;
- this->public.remove = (void(*)(mediation_manager_t*,ike_sa_id_t*))remove_sa;
- this->public.update_sa_id = (void(*)(mediation_manager_t*,identification_t*,ike_sa_id_t*))update_sa_id;
- this->public.check = (ike_sa_id_t*(*)(mediation_manager_t*,identification_t*))check;
- this->public.check_and_register = (ike_sa_id_t*(*)(mediation_manager_t*,identification_t*,identification_t*))check_and_register;
-
- this->peers = linked_list_create();
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
-
- return (mediation_manager_t*)this;
+ private_mediation_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .destroy = _destroy,
+ .remove = _remove_sa,
+ .update_sa_id = _update_sa_id,
+ .check = _check,
+ .check_and_register = _check_and_register,
+ },
+ .peers = linked_list_create(),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ );
+ return &this->public;
}
diff --git a/src/libcharon/sa/shunt_manager.c b/src/libcharon/sa/shunt_manager.c
new file mode 100644
index 000000000..52b2ecd62
--- /dev/null
+++ b/src/libcharon/sa/shunt_manager.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2011 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 "shunt_manager.h"
+
+#include <hydra.h>
+#include <daemon.h>
+#include <threading/rwlock.h>
+#include <utils/linked_list.h>
+
+
+typedef struct private_shunt_manager_t private_shunt_manager_t;
+
+/**
+ * Private data of an shunt_manager_t object.
+ */
+struct private_shunt_manager_t {
+
+ /**
+ * Public shunt_manager_t interface.
+ */
+ shunt_manager_t public;
+
+ /**
+ * Installed shunts, as child_cfg_t
+ */
+ linked_list_t *shunts;
+};
+
+/**
+ * Install in and out shunt policies in the kernel
+ */
+static bool install_shunt_policy(child_cfg_t *child)
+{
+ enumerator_t *e_my_ts, *e_other_ts;
+ linked_list_t *my_ts_list, *other_ts_list;
+ traffic_selector_t *my_ts, *other_ts;
+ host_t *host_any;
+ policy_type_t policy_type;
+ status_t status = SUCCESS;
+ ipsec_sa_cfg_t sa = { .mode = MODE_TRANSPORT };
+
+ policy_type = (child->get_mode(child) == MODE_PASS) ?
+ POLICY_PASS : POLICY_DROP;
+ my_ts_list = child->get_traffic_selectors(child, TRUE, NULL, NULL);
+ other_ts_list = child->get_traffic_selectors(child, FALSE, NULL, NULL);
+ host_any = host_create_any(AF_INET);
+
+ /* enumerate pairs of traffic selectors */
+ e_my_ts = my_ts_list->create_enumerator(my_ts_list);
+ while (e_my_ts->enumerate(e_my_ts, &my_ts))
+ {
+ e_other_ts = other_ts_list->create_enumerator(other_ts_list);
+ while (e_other_ts->enumerate(e_other_ts, &other_ts))
+ {
+ /* install out policy */
+ status |= hydra->kernel_interface->add_policy(
+ hydra->kernel_interface, host_any, host_any,
+ my_ts, other_ts, POLICY_OUT, policy_type,
+ &sa, child->get_mark(child, FALSE),
+ POLICY_PRIORITY_DEFAULT);
+
+ /* install in policy */
+ status |= hydra->kernel_interface->add_policy(
+ hydra->kernel_interface, host_any, host_any,
+ other_ts, my_ts, POLICY_IN, policy_type,
+ &sa, child->get_mark(child, TRUE),
+ POLICY_PRIORITY_DEFAULT);
+
+ /* install forward policy */
+ status |= hydra->kernel_interface->add_policy(
+ hydra->kernel_interface, host_any, host_any,
+ other_ts, my_ts, POLICY_FWD, policy_type,
+ &sa, child->get_mark(child, TRUE),
+ POLICY_PRIORITY_DEFAULT);
+ }
+ e_other_ts->destroy(e_other_ts);
+ }
+ e_my_ts->destroy(e_my_ts);
+
+ my_ts_list->destroy_offset(my_ts_list,
+ offsetof(traffic_selector_t, destroy));
+ other_ts_list->destroy_offset(other_ts_list,
+ offsetof(traffic_selector_t, destroy));
+ host_any->destroy(host_any);
+
+ return status == SUCCESS;
+}
+
+METHOD(shunt_manager_t, install, bool,
+ private_shunt_manager_t *this, child_cfg_t *child)
+{
+ enumerator_t *enumerator;
+ child_cfg_t *child_cfg;
+ bool found = FALSE;
+
+ /* check if not already installed */
+ enumerator = this->shunts->create_enumerator(this->shunts);
+ while (enumerator->enumerate(enumerator, &child_cfg))
+ {
+ if (streq(child_cfg->get_name(child_cfg), child->get_name(child)))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (found)
+ {
+ DBG1(DBG_CFG, "shunt %N policy '%s' already installed",
+ ipsec_mode_names, child->get_mode(child), child->get_name(child));
+ return TRUE;
+ }
+ this->shunts->insert_last(this->shunts, child->get_ref(child));
+
+ return install_shunt_policy(child);
+}
+
+/**
+ * Uninstall in and out shunt policies in the kernel
+ */
+static void uninstall_shunt_policy(child_cfg_t *child)
+{
+ enumerator_t *e_my_ts, *e_other_ts;
+ linked_list_t *my_ts_list, *other_ts_list;
+ traffic_selector_t *my_ts, *other_ts;
+ status_t status = SUCCESS;
+
+ my_ts_list = child->get_traffic_selectors(child, TRUE, NULL, NULL);
+ other_ts_list = child->get_traffic_selectors(child, FALSE, NULL, NULL);
+
+ /* enumerate pairs of traffic selectors */
+ e_my_ts = my_ts_list->create_enumerator(my_ts_list);
+ while (e_my_ts->enumerate(e_my_ts, &my_ts))
+ {
+ e_other_ts = other_ts_list->create_enumerator(other_ts_list);
+ while (e_other_ts->enumerate(e_other_ts, &other_ts))
+ {
+ /* uninstall out policy */
+ status |= hydra->kernel_interface->del_policy(
+ hydra->kernel_interface, my_ts, other_ts,
+ POLICY_OUT, 0, child->get_mark(child, FALSE),
+ POLICY_PRIORITY_DEFAULT);
+
+ /* uninstall in policy */
+ status |= hydra->kernel_interface->del_policy(
+ hydra->kernel_interface, other_ts, my_ts,
+ POLICY_IN, 0, child->get_mark(child, TRUE),
+ POLICY_PRIORITY_DEFAULT);
+
+ /* uninstall forward policy */
+ status |= hydra->kernel_interface->del_policy(
+ hydra->kernel_interface, other_ts, my_ts,
+ POLICY_FWD, 0, child->get_mark(child, TRUE),
+ POLICY_PRIORITY_DEFAULT);
+ }
+ e_other_ts->destroy(e_other_ts);
+ }
+ e_my_ts->destroy(e_my_ts);
+
+ my_ts_list->destroy_offset(my_ts_list,
+ offsetof(traffic_selector_t, destroy));
+ other_ts_list->destroy_offset(other_ts_list,
+ offsetof(traffic_selector_t, destroy));
+
+ if (status != SUCCESS)
+ {
+ DBG1(DBG_CFG, "uninstalling shunt %N 'policy %s' failed",
+ ipsec_mode_names, child->get_mode(child), child->get_name(child));
+ }
+}
+
+METHOD(shunt_manager_t, uninstall, bool,
+ private_shunt_manager_t *this, char *name)
+{
+ enumerator_t *enumerator;
+ child_cfg_t *child, *found = NULL;
+
+ enumerator = this->shunts->create_enumerator(this->shunts);
+ while (enumerator->enumerate(enumerator, &child))
+ {
+ if (streq(name, child->get_name(child)))
+ {
+ this->shunts->remove_at(this->shunts, enumerator);
+ found = child;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ return FALSE;
+ }
+ uninstall_shunt_policy(child);
+ return TRUE;
+}
+
+METHOD(shunt_manager_t, create_enumerator, enumerator_t*,
+ private_shunt_manager_t *this)
+{
+ return this->shunts->create_enumerator(this->shunts);
+}
+
+METHOD(shunt_manager_t, destroy, void,
+ private_shunt_manager_t *this)
+{
+ child_cfg_t *child;
+
+ while (this->shunts->remove_last(this->shunts, (void**)&child) == SUCCESS)
+ {
+ uninstall_shunt_policy(child);
+ child->destroy(child);
+ }
+ this->shunts->destroy(this->shunts);
+ free(this);
+}
+
+/**
+ * See header
+ */
+shunt_manager_t *shunt_manager_create()
+{
+ private_shunt_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .install = _install,
+ .uninstall = _uninstall,
+ .create_enumerator = _create_enumerator,
+ .destroy = _destroy,
+ },
+ .shunts = linked_list_create(),
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libcharon/sa/shunt_manager.h b/src/libcharon/sa/shunt_manager.h
new file mode 100644
index 000000000..12ff08558
--- /dev/null
+++ b/src/libcharon/sa/shunt_manager.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 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 shunt_manager shunt_manager
+ * @{ @ingroup sa
+ */
+
+#ifndef SHUNT_MANAGER_H_
+#define SHUNT_MANAGER_H_
+
+#include <library.h>
+#include <utils/enumerator.h>
+#include <config/child_cfg.h>
+
+typedef struct shunt_manager_t shunt_manager_t;
+
+/**
+ * Manage PASS and DROP shunt policy excepting traffic from IPsec SAs.
+ */
+struct shunt_manager_t {
+
+ /**
+ * Install a policy as a shunt.
+ *
+ * @param child child configuration to install as a shunt
+ * @return TRUE if installed successfully
+ */
+ bool (*install)(shunt_manager_t *this, child_cfg_t *child);
+
+ /**
+ * Uninstall a shunt policy.
+ *
+ * @param name name of child configuration to uninstall as a shunt
+ * @return TRUE if uninstalled successfully
+ */
+ bool (*uninstall)(shunt_manager_t *this, char *name);
+
+ /**
+ * Create an enumerator over all installed shunts.
+ *
+ * @return enumerator over (child_sa_t)
+ */
+ enumerator_t* (*create_enumerator)(shunt_manager_t *this);
+
+ /**
+ * Destroy a shunt_manager_t.
+ */
+ void (*destroy)(shunt_manager_t *this);
+};
+
+/**
+ * Create a shunt_manager instance.
+ */
+shunt_manager_t *shunt_manager_create();
+
+#endif /** SHUNT_MANAGER_H_ @}*/
diff --git a/src/libcharon/sa/task_manager.c b/src/libcharon/sa/task_manager.c
index f07d2e384..022a5e3d6 100644
--- a/src/libcharon/sa/task_manager.c
+++ b/src/libcharon/sa/task_manager.c
@@ -159,15 +159,15 @@ struct private_task_manager_t {
*/
static void flush(private_task_manager_t *this)
{
- this->queued_tasks->destroy_offset(this->queued_tasks,
- offsetof(task_t, destroy));
- this->queued_tasks = linked_list_create();
this->passive_tasks->destroy_offset(this->passive_tasks,
offsetof(task_t, destroy));
this->passive_tasks = linked_list_create();
this->active_tasks->destroy_offset(this->active_tasks,
offsetof(task_t, destroy));
this->active_tasks = linked_list_create();
+ this->queued_tasks->destroy_offset(this->queued_tasks,
+ offsetof(task_t, destroy));
+ this->queued_tasks = linked_list_create();
}
/**
@@ -175,23 +175,23 @@ static void flush(private_task_manager_t *this)
*/
static bool activate_task(private_task_manager_t *this, task_type_t type)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
task_t *task;
bool found = FALSE;
- iterator = this->queued_tasks->create_iterator(this->queued_tasks, TRUE);
- while (iterator->iterate(iterator, (void**)&task))
+ enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
+ while (enumerator->enumerate(enumerator, (void**)&task))
{
if (task->get_type(task) == type)
{
DBG2(DBG_IKE, " activating %N task", task_type_names, type);
- iterator->remove(iterator);
+ this->queued_tasks->remove_at(this->queued_tasks, enumerator);
this->active_tasks->insert_last(this->active_tasks, task);
found = TRUE;
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return found;
}
@@ -202,14 +202,14 @@ METHOD(task_manager_t, retransmit, status_t,
{
u_int32_t timeout;
job_t *job;
- iterator_t *iterator;
+ enumerator_t *enumerator;
packet_t *packet;
task_t *task;
ike_mobike_t *mobike = NULL;
/* check if we are retransmitting a MOBIKE routability check */
- iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
- while (iterator->iterate(iterator, (void*)&task))
+ enumerator = this->active_tasks->create_enumerator(this->active_tasks);
+ while (enumerator->enumerate(enumerator, (void*)&task))
{
if (task->get_type(task) == IKE_MOBIKE)
{
@@ -221,7 +221,7 @@ METHOD(task_manager_t, retransmit, status_t,
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
if (mobike == NULL)
{
@@ -282,7 +282,7 @@ METHOD(task_manager_t, retransmit, status_t,
METHOD(task_manager_t, initiate, status_t,
private_task_manager_t *this)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
task_t *task;
message_t *message;
host_t *me, *other;
@@ -366,6 +366,11 @@ METHOD(task_manager_t, initiate, status_t,
exchange = INFORMATIONAL;
break;
}
+ if (activate_task(this, IKE_AUTH_LIFETIME))
+ {
+ exchange = INFORMATIONAL;
+ break;
+ }
#ifdef ME
if (activate_task(this, IKE_ME))
{
@@ -387,8 +392,8 @@ METHOD(task_manager_t, initiate, status_t,
else
{
DBG2(DBG_IKE, "reinitiating already active tasks");
- iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
- while (iterator->iterate(iterator, (void**)&task))
+ enumerator = this->active_tasks->create_enumerator(this->active_tasks);
+ while (enumerator->enumerate(enumerator, (void**)&task))
{
DBG2(DBG_IKE, " %N task", task_type_names, task->get_type(task));
switch (task->get_type(task))
@@ -406,12 +411,13 @@ METHOD(task_manager_t, initiate, status_t,
break;
case IKE_MOBIKE:
exchange = INFORMATIONAL;
+ break;
default:
continue;
}
break;
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
if (exchange == 0)
@@ -432,14 +438,14 @@ METHOD(task_manager_t, initiate, status_t,
this->initiating.type = exchange;
this->initiating.retransmitted = 0;
- iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
- while (iterator->iterate(iterator, (void*)&task))
+ enumerator = this->active_tasks->create_enumerator(this->active_tasks);
+ while (enumerator->enumerate(enumerator, (void*)&task))
{
switch (task->build(task, message))
{
case SUCCESS:
/* task completed, remove it */
- iterator->remove(iterator);
+ this->active_tasks->remove_at(this->active_tasks, enumerator);
task->destroy(task);
break;
case NEED_MORE:
@@ -454,13 +460,13 @@ METHOD(task_manager_t, initiate, status_t,
/* FALL */
case DESTROY_ME:
/* critical failure, destroy IKE_SA */
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
message->destroy(message);
flush(this);
return DESTROY_ME;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* update exchange type if a task changed it */
this->initiating.type = message->get_exchange_type(message);
@@ -487,7 +493,7 @@ METHOD(task_manager_t, initiate, status_t,
static status_t process_response(private_task_manager_t *this,
message_t *message)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
task_t *task;
if (message->get_exchange_type(message) != this->initiating.type)
@@ -501,14 +507,14 @@ static status_t process_response(private_task_manager_t *this,
/* catch if we get resetted while processing */
this->reset = FALSE;
- iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
- while (iterator->iterate(iterator, (void*)&task))
+ enumerator = this->active_tasks->create_enumerator(this->active_tasks);
+ while (enumerator->enumerate(enumerator, (void*)&task))
{
switch (task->process(task, message))
{
case SUCCESS:
/* task completed, remove it */
- iterator->remove(iterator);
+ this->active_tasks->remove_at(this->active_tasks, enumerator);
task->destroy(task);
break;
case NEED_MORE:
@@ -520,19 +526,19 @@ static status_t process_response(private_task_manager_t *this,
/* FALL */
case DESTROY_ME:
/* critical failure, destroy IKE_SA */
- iterator->remove(iterator);
- iterator->destroy(iterator);
+ this->active_tasks->remove_at(this->active_tasks, enumerator);
+ enumerator->destroy(enumerator);
task->destroy(task);
return DESTROY_ME;
}
if (this->reset)
{ /* start all over again if we were reset */
this->reset = FALSE;
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return initiate(this);
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
this->initiating.mid++;
this->initiating.type = EXCHANGE_TYPE_UNDEFINED;
@@ -547,7 +553,7 @@ static status_t process_response(private_task_manager_t *this,
*/
static bool handle_collisions(private_task_manager_t *this, task_t *task)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
task_t *active;
task_type_t type;
@@ -558,8 +564,8 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task)
type == CHILD_DELETE || type == IKE_DELETE || type == IKE_REAUTH)
{
/* find an exchange collision, and notify these tasks */
- iterator = this->active_tasks->create_iterator(this->active_tasks, TRUE);
- while (iterator->iterate(iterator, (void**)&active))
+ enumerator = this->active_tasks->create_enumerator(this->active_tasks);
+ while (enumerator->enumerate(enumerator, (void**)&active))
{
switch (active->get_type(active))
{
@@ -583,10 +589,10 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task)
default:
continue;
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return TRUE;
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
return FALSE;
}
@@ -596,11 +602,11 @@ static bool handle_collisions(private_task_manager_t *this, task_t *task)
*/
static status_t build_response(private_task_manager_t *this, message_t *request)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
task_t *task;
message_t *message;
host_t *me, *other;
- bool delete = FALSE;
+ bool delete = FALSE, hook = FALSE;
status_t status;
me = request->get_destination(request);
@@ -614,14 +620,14 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
message->set_message_id(message, this->responding.mid);
message->set_request(message, FALSE);
- iterator = this->passive_tasks->create_iterator(this->passive_tasks, TRUE);
- while (iterator->iterate(iterator, (void*)&task))
+ enumerator = this->passive_tasks->create_enumerator(this->passive_tasks);
+ while (enumerator->enumerate(enumerator, (void*)&task))
{
switch (task->build(task, message))
{
case SUCCESS:
/* task completed, remove it */
- iterator->remove(iterator);
+ this->passive_tasks->remove_at(this->passive_tasks, enumerator);
if (!handle_collisions(this, task))
{
task->destroy(task);
@@ -631,12 +637,13 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
/* processed, but task needs another exchange */
if (handle_collisions(this, task))
{
- iterator->remove(iterator);
+ this->passive_tasks->remove_at(this->passive_tasks,
+ enumerator);
}
break;
case FAILED:
default:
- charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
+ hook = TRUE;
/* FALL */
case DESTROY_ME:
/* destroy IKE_SA, but SEND response first */
@@ -648,7 +655,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* remove resonder SPI if IKE_SA_INIT failed */
if (delete && request->get_exchange_type(request) == IKE_SA_INIT)
@@ -673,6 +680,10 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
this->responding.packet->clone(this->responding.packet));
if (delete)
{
+ if (hook)
+ {
+ charon->bus->ike_updown(charon->bus, this->ike_sa, FALSE);
+ }
return DESTROY_ME;
}
return SUCCESS;
@@ -685,7 +696,6 @@ static status_t process_request(private_task_manager_t *this,
message_t *message)
{
enumerator_t *enumerator;
- iterator_t *iterator;
task_t *task = NULL;
payload_t *payload;
notify_payload_t *notify;
@@ -854,14 +864,14 @@ static status_t process_request(private_task_manager_t *this,
}
/* let the tasks process the message */
- iterator = this->passive_tasks->create_iterator(this->passive_tasks, TRUE);
- while (iterator->iterate(iterator, (void*)&task))
+ enumerator = this->passive_tasks->create_enumerator(this->passive_tasks);
+ while (enumerator->enumerate(enumerator, (void*)&task))
{
switch (task->process(task, message))
{
case SUCCESS:
/* task completed, remove it */
- iterator->remove(iterator);
+ this->passive_tasks->remove_at(this->passive_tasks, enumerator);
task->destroy(task);
break;
case NEED_MORE:
@@ -873,13 +883,13 @@ static status_t process_request(private_task_manager_t *this,
/* FALL */
case DESTROY_ME:
/* critical failure, destroy IKE_SA */
- iterator->remove(iterator);
- iterator->destroy(iterator);
+ this->passive_tasks->remove_at(this->passive_tasks, enumerator);
+ enumerator->destroy(enumerator);
task->destroy(task);
return DESTROY_ME;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return build_response(this, message);
}
@@ -978,20 +988,20 @@ METHOD(task_manager_t, queue_task, void,
{
if (task->get_type(task) == IKE_MOBIKE)
{ /* there is no need to queue more than one mobike task */
- iterator_t *iterator;
+ enumerator_t *enumerator;
task_t *current;
- iterator = this->queued_tasks->create_iterator(this->queued_tasks, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ enumerator = this->queued_tasks->create_enumerator(this->queued_tasks);
+ while (enumerator->enumerate(enumerator, (void**)&current))
{
if (current->get_type(current) == IKE_MOBIKE)
{
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
task->destroy(task);
return;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
DBG2(DBG_IKE, "queueing %N task", task_type_names, task->get_type(task));
this->queued_tasks->insert_last(this->queued_tasks, task);
diff --git a/src/libcharon/sa/tasks/child_create.c b/src/libcharon/sa/tasks/child_create.c
index fc02a334b..67c29d31f 100644
--- a/src/libcharon/sa/tasks/child_create.c
+++ b/src/libcharon/sa/tasks/child_create.c
@@ -213,13 +213,13 @@ static bool ts_list_is_host(linked_list_t *list, host_t *host)
{
traffic_selector_t *ts;
bool is_host = TRUE;
- iterator_t *iterator = list->create_iterator(list, TRUE);
+ enumerator_t *enumerator = list->create_enumerator(list);
- while (is_host && iterator->iterate(iterator, (void**)&ts))
+ while (is_host && enumerator->enumerate(enumerator, (void**)&ts))
{
is_host = is_host && ts->is_host(ts, host);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return is_host;
}
@@ -886,6 +886,10 @@ static void handle_child_sa_failure(private_child_create_t *this,
delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE),
100);
}
+ else
+ {
+ DBG1(DBG_IKE, "failed to establish CHILD_SA, keeping IKE_SA");
+ }
}
METHOD(task_t, build_r, status_t,
diff --git a/src/libcharon/sa/tasks/child_delete.c b/src/libcharon/sa/tasks/child_delete.c
index e6834a93c..dc4b30dd3 100644
--- a/src/libcharon/sa/tasks/child_delete.c
+++ b/src/libcharon/sa/tasks/child_delete.c
@@ -73,11 +73,11 @@ struct private_child_delete_t {
static void build_payloads(private_child_delete_t *this, message_t *message)
{
delete_payload_t *ah = NULL, *esp = NULL;
- iterator_t *iterator;
+ enumerator_t *enumerator;
child_sa_t *child_sa;
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = this->child_sas->create_enumerator(this->child_sas);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
protocol_id_t protocol = child_sa->get_protocol(child_sa);
u_int32_t spi = child_sa->get_spi(child_sa, TRUE);
@@ -109,7 +109,7 @@ static void build_payloads(private_child_delete_t *this, message_t *message)
}
child_sa->set_state(child_sa, CHILD_DELETING);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -186,7 +186,7 @@ static void process_payloads(private_child_delete_t *this, message_t *message)
*/
static status_t destroy_and_reestablish(private_child_delete_t *this)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
child_sa_t *child_sa;
child_cfg_t *child_cfg;
protocol_id_t protocol;
@@ -194,8 +194,8 @@ static status_t destroy_and_reestablish(private_child_delete_t *this)
action_t action;
status_t status = SUCCESS;
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = this->child_sas->create_enumerator(this->child_sas);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
/* signal child down event if we are not rekeying */
if (!this->rekeyed)
@@ -231,7 +231,7 @@ static status_t destroy_and_reestablish(private_child_delete_t *this)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return status;
}
@@ -240,12 +240,12 @@ static status_t destroy_and_reestablish(private_child_delete_t *this)
*/
static void log_children(private_child_delete_t *this)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
child_sa_t *child_sa;
u_int64_t bytes_in, bytes_out;
- iterator = this->child_sas->create_iterator(this->child_sas, TRUE);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = this->child_sas->create_enumerator(this->child_sas);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
child_sa->get_usestats(child_sa, TRUE, NULL, &bytes_in);
child_sa->get_usestats(child_sa, FALSE, NULL, &bytes_out);
@@ -258,13 +258,11 @@ static void log_children(private_child_delete_t *this)
child_sa->get_traffic_selectors(child_sa, TRUE),
child_sa->get_traffic_selectors(child_sa, FALSE));
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
-/**
- * Implementation of task_t.build for initiator
- */
-static status_t build_i(private_child_delete_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_child_delete_t *this, message_t *message)
{
child_sa_t *child_sa;
@@ -291,10 +289,8 @@ static status_t build_i(private_child_delete_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_child_delete_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_child_delete_t *this, message_t *message)
{
/* flush the list before adding new SAs */
this->child_sas->destroy(this->child_sas);
@@ -305,20 +301,16 @@ static status_t process_i(private_child_delete_t *this, message_t *message)
return destroy_and_reestablish(this);
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_r(private_child_delete_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_child_delete_t *this, message_t *message)
{
process_payloads(this, message);
log_children(this);
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_child_delete_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_child_delete_t *this, message_t *message)
{
/* if we are rekeying, we send an empty informational */
if (this->ike_sa->get_state(this->ike_sa) != IKE_REKEYING)
@@ -329,28 +321,22 @@ static status_t build_r(private_child_delete_t *this, message_t *message)
return destroy_and_reestablish(this);
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_child_delete_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_child_delete_t *this)
{
return CHILD_DELETE;
}
-/**
- * Implementation of child_delete_t.get_child
- */
-static child_sa_t* get_child(private_child_delete_t *this)
+METHOD(child_delete_t , get_child, child_sa_t*,
+ private_child_delete_t *this)
{
child_sa_t *child_sa = NULL;
this->child_sas->get_first(this->child_sas, (void**)&child_sa);
return child_sa;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_child_delete_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_child_delete_t *this, ike_sa_t *ike_sa)
{
this->check_delete_action = FALSE;
this->ike_sa = ike_sa;
@@ -359,10 +345,8 @@ static void migrate(private_child_delete_t *this, ike_sa_t *ike_sa)
this->child_sas = linked_list_create();
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_child_delete_t *this)
+METHOD(task_t, destroy, void,
+ private_child_delete_t *this)
{
this->child_sas->destroy(this->child_sas);
free(this);
@@ -374,30 +358,33 @@ static void destroy(private_child_delete_t *this)
child_delete_t *child_delete_create(ike_sa_t *ike_sa, protocol_id_t protocol,
u_int32_t spi)
{
- private_child_delete_t *this = malloc_thing(private_child_delete_t);
-
- this->public.get_child = (child_sa_t*(*)(child_delete_t*))get_child;
- 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;
-
- this->ike_sa = ike_sa;
- this->check_delete_action = FALSE;
- this->child_sas = linked_list_create();
- this->protocol = protocol;
- this->spi = spi;
- this->rekeyed = FALSE;
+ private_child_delete_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ .get_child = _get_child,
+ },
+ .ike_sa = ike_sa,
+ .child_sas = linked_list_create(),
+ .protocol = protocol,
+ .spi = spi,
+ );
if (protocol != PROTO_NONE)
{
- 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;
this->initiator = TRUE;
}
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->initiator = FALSE;
}
return &this->public;
diff --git a/src/libcharon/sa/tasks/child_rekey.c b/src/libcharon/sa/tasks/child_rekey.c
index b39a5fc67..76d185590 100644
--- a/src/libcharon/sa/tasks/child_rekey.c
+++ b/src/libcharon/sa/tasks/child_rekey.c
@@ -128,10 +128,8 @@ static void find_child(private_child_rekey_t *this, message_t *message)
}
}
-/**
- * Implementation of task_t.build for initiator
- */
-static status_t build_i(private_child_rekey_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_child_rekey_t *this, message_t *message)
{
notify_payload_t *notify;
u_int32_t reqid;
@@ -175,10 +173,8 @@ static status_t build_i(private_child_rekey_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_r(private_child_rekey_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_child_rekey_t *this, message_t *message)
{
/* let the CHILD_CREATE task process the message */
this->child_create->task.process(&this->child_create->task, message);
@@ -188,10 +184,8 @@ static status_t process_r(private_child_rekey_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_child_rekey_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_child_rekey_t *this, message_t *message)
{
u_int32_t reqid;
@@ -252,7 +246,10 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
{
/* 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);
+ if (child_sa)
+ {
+ child_sa->set_close_action(child_sa, ACTION_NONE);
+ }
}
}
else
@@ -284,10 +281,8 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
return to_delete;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_child_rekey_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_child_rekey_t *this, message_t *message)
{
protocol_id_t protocol;
u_int32_t spi;
@@ -314,7 +309,7 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
if (message->get_payload(message, SECURITY_ASSOCIATION) == NULL)
{
/* establishing new child failed, reuse old. but not when we
- * recieved a delete in the meantime */
+ * received a delete in the meantime */
if (!(this->collision &&
this->collision->get_type(this->collision) == CHILD_DELETE))
{
@@ -364,18 +359,14 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_child_rekey_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_child_rekey_t *this)
{
return CHILD_REKEY;
}
-/**
- * Implementation of child_rekey_t.collide
- */
-static void collide(private_child_rekey_t *this, task_t *other)
+METHOD(child_rekey_t, collide, void,
+ private_child_rekey_t *this, task_t *other)
{
/* the task manager only detects exchange collision, but not if
* the collision is for the same child. we check it here. */
@@ -418,10 +409,8 @@ static void collide(private_child_rekey_t *this, task_t *other)
this->collision = other;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_child_rekey_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_child_rekey_t *this, ike_sa_t *ike_sa)
{
if (this->child_create)
{
@@ -437,10 +426,8 @@ static void migrate(private_child_rekey_t *this, ike_sa_t *ike_sa)
this->collision = NULL;
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_child_rekey_t *this)
+METHOD(task_t, destroy, void,
+ private_child_rekey_t *this)
{
if (this->child_create)
{
@@ -460,34 +447,36 @@ static void destroy(private_child_rekey_t *this)
child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol,
u_int32_t spi)
{
- private_child_rekey_t *this = malloc_thing(private_child_rekey_t);
-
- this->public.collide = (void (*)(child_rekey_t*,task_t*))collide;
- 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_child_rekey_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ .collide = _collide,
+ },
+ .ike_sa = ike_sa,
+ .protocol = protocol,
+ .spi = spi,
+ );
+
if (protocol != PROTO_NONE)
{
- 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;
this->initiator = TRUE;
this->child_create = NULL;
}
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->initiator = FALSE;
this->child_create = child_create_create(ike_sa, NULL, TRUE, NULL, NULL);
}
- this->ike_sa = ike_sa;
- this->child_sa = NULL;
- this->protocol = 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 0756c7d60..665468fe8 100644
--- a/src/libcharon/sa/tasks/ike_auth.c
+++ b/src/libcharon/sa/tasks/ike_auth.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -417,10 +418,14 @@ METHOD(task_t, build_i, status_t,
cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
idi = cfg->get(cfg, AUTH_RULE_IDENTITY);
- if (!idi)
- {
- DBG1(DBG_CFG, "configuration misses IDi");
- return FAILED;
+ if (!idi || idi->get_type(idi) == ID_ANY)
+ { /* ID_ANY is invalid as IDi, use local IP address instead */
+ host_t *me;
+
+ DBG1(DBG_CFG, "no IDi configured, fall back on IP address");
+ me = this->ike_sa->get_my_host(this->ike_sa);
+ idi = identification_create_from_sockaddr(me->get_sockaddr(me));
+ cfg->add(cfg, AUTH_RULE_IDENTITY, idi);
}
this->ike_sa->set_my_id(this->ike_sa, idi->clone(idi));
id_payload = id_payload_create_from_identification(ID_INITIATOR, idi);
@@ -669,8 +674,7 @@ METHOD(task_t, build_r, status_t,
if (this->authentication_failed || this->peer_cfg == NULL)
{
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
- return FAILED;
+ goto peer_auth_failed;
}
if (this->my_auth == NULL && this->do_another_auth)
@@ -688,11 +692,14 @@ METHOD(task_t, build_r, status_t,
if (id->get_type(id) == ID_ANY)
{ /* no IDr received, apply configured ID */
if (!id_cfg || id_cfg->contains_wildcards(id_cfg))
- {
- DBG1(DBG_CFG, "IDr not configured and negotiation failed");
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
- chunk_empty);
- return FAILED;
+ { /* no ID configured, use local IP address */
+ host_t *me;
+
+ DBG1(DBG_CFG, "no IDr configured, fall back on IP address");
+ me = this->ike_sa->get_my_host(this->ike_sa);
+ id_cfg = identification_create_from_sockaddr(
+ me->get_sockaddr(me));
+ cfg->add(cfg, AUTH_RULE_IDENTITY, id_cfg);
}
this->ike_sa->set_my_id(this->ike_sa, id_cfg->clone(id_cfg));
id = id_cfg;
@@ -702,9 +709,7 @@ METHOD(task_t, build_r, status_t,
if (id_cfg && !id->matches(id, id_cfg))
{
DBG1(DBG_CFG, "received IDr %Y, but require %Y", id, id_cfg);
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
- chunk_empty);
- return FAILED;
+ goto peer_auth_failed;
}
}
@@ -726,9 +731,7 @@ METHOD(task_t, build_r, status_t,
{
DBG1(DBG_IKE, "configured EAP-only authentication, but peer "
"does not support it");
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
- chunk_empty);
- return FAILED;
+ goto peer_auth_failed;
}
}
else
@@ -741,9 +744,7 @@ METHOD(task_t, build_r, status_t,
this->reserved);
if (!this->my_auth)
{
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
- chunk_empty);
- return FAILED;
+ goto peer_auth_failed;
}
}
}
@@ -759,12 +760,11 @@ METHOD(task_t, build_r, status_t,
case NEED_MORE:
break;
default:
- if (!message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
+ if (message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
{ /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
- chunk_empty);
+ goto peer_auth_failed_no_notify;
}
- return FAILED;
+ goto peer_auth_failed;
}
}
if (this->my_auth)
@@ -802,7 +802,7 @@ METHOD(task_t, build_r, status_t,
if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
this->ike_sa, FALSE))
{
- DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy");
+ DBG1(DBG_IKE, "cancelling IKE_SA setup due to uniqueness policy");
message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
chunk_empty);
return FAILED;
@@ -810,9 +810,7 @@ METHOD(task_t, build_r, status_t,
if (!charon->bus->authorize(charon->bus, TRUE))
{
DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
- message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
- chunk_empty);
- return FAILED;
+ goto peer_auth_failed;
}
DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
this->ike_sa->get_name(this->ike_sa),
@@ -826,6 +824,13 @@ METHOD(task_t, build_r, status_t,
return SUCCESS;
}
return NEED_MORE;
+
+peer_auth_failed:
+ message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+ chunk_empty);
+peer_auth_failed_no_notify:
+ charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
+ return FAILED;
}
METHOD(task_t, process_i, status_t,
@@ -908,7 +913,7 @@ METHOD(task_t, process_i, status_t,
if (!id_payload)
{
DBG1(DBG_IKE, "IDr payload missing");
- return FAILED;
+ goto peer_auth_failed;
}
id = id_payload->get_identification(id_payload);
get_reserved_id_bytes(this, id_payload);
@@ -926,7 +931,7 @@ METHOD(task_t, process_i, status_t,
this->reserved);
if (!this->other_auth)
{
- return FAILED;
+ goto peer_auth_failed;
}
}
else
@@ -944,7 +949,7 @@ METHOD(task_t, process_i, status_t,
case NEED_MORE:
return NEED_MORE;
default:
- return FAILED;
+ goto peer_auth_failed;
}
this->other_auth->destroy(this->other_auth);
this->other_auth = NULL;
@@ -953,7 +958,7 @@ METHOD(task_t, process_i, status_t,
if (!charon->bus->authorize(charon->bus, FALSE))
{
DBG1(DBG_IKE, "authorization forbids IKE_SA, cancelling");
- return FAILED;
+ goto peer_auth_failed;
}
/* store authentication information, reset authenticator */
@@ -986,7 +991,7 @@ METHOD(task_t, process_i, status_t,
if (!this->my_auth || !this->my_auth->is_mutual(this->my_auth))
{
DBG1(DBG_IKE, "do not allow non-mutual EAP-only authentication");
- return FAILED;
+ goto peer_auth_failed;
}
DBG1(DBG_IKE, "allow mutual EAP-only authentication");
}
@@ -999,12 +1004,13 @@ METHOD(task_t, process_i, status_t,
{
if (!update_cfg_candidates(this, TRUE))
{
- return FAILED;
+ goto peer_auth_failed;
}
if (!charon->bus->authorize(charon->bus, TRUE))
{
- DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
- return FAILED;
+ DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, "
+ "cancelling");
+ goto peer_auth_failed;
}
DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
this->ike_sa->get_name(this->ike_sa),
@@ -1018,6 +1024,10 @@ METHOD(task_t, process_i, status_t,
return SUCCESS;
}
return NEED_MORE;
+
+peer_auth_failed:
+ charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
+ return FAILED;
}
METHOD(task_t, get_type, task_type_t,
diff --git a/src/libcharon/sa/tasks/ike_auth.h b/src/libcharon/sa/tasks/ike_auth.h
index bba46d961..132907941 100644
--- a/src/libcharon/sa/tasks/ike_auth.h
+++ b/src/libcharon/sa/tasks/ike_auth.h
@@ -49,7 +49,7 @@ struct ike_auth_t {
* Create a new task of type IKE_AUTHENTICATE.
*
* @param ike_sa IKE_SA this task works for
- * @param initiator TRUE if thask is the initator of an exchange
+ * @param initiator TRUE if task is the initiator of an exchange
* @return ike_auth task to handle by the task_manager
*/
ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator);
diff --git a/src/libcharon/sa/tasks/ike_auth_lifetime.c b/src/libcharon/sa/tasks/ike_auth_lifetime.c
index 75ff35168..a57cfd075 100644
--- a/src/libcharon/sa/tasks/ike_auth_lifetime.c
+++ b/src/libcharon/sa/tasks/ike_auth_lifetime.c
@@ -75,10 +75,8 @@ static void process_payloads(private_ike_auth_lifetime_t *this, message_t *messa
}
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t build_i(private_ike_auth_lifetime_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_auth_lifetime_t *this, message_t *message)
{
if (message->get_exchange_type(message) == INFORMATIONAL)
{
@@ -88,10 +86,8 @@ static status_t build_i(private_ike_auth_lifetime_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_auth_lifetime_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_ike_auth_lifetime_t *this, message_t *message)
{
if (message->get_exchange_type(message) == INFORMATIONAL)
{
@@ -101,10 +97,8 @@ static status_t process_r(private_ike_auth_lifetime_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_auth_lifetime_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_ike_auth_lifetime_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
@@ -115,10 +109,8 @@ static status_t build_r(private_ike_auth_lifetime_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_auth_lifetime_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_auth_lifetime_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
@@ -129,26 +121,20 @@ static status_t process_i(private_ike_auth_lifetime_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_auth_lifetime_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_auth_lifetime_t *this)
{
return IKE_AUTH_LIFETIME;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_auth_lifetime_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_auth_lifetime_t *this, ike_sa_t *ike_sa)
{
this->ike_sa = ike_sa;
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_auth_lifetime_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_auth_lifetime_t *this)
{
free(this);
}
@@ -158,25 +144,30 @@ static void destroy(private_ike_auth_lifetime_t *this)
*/
ike_auth_lifetime_t *ike_auth_lifetime_create(ike_sa_t *ike_sa, bool initiator)
{
- private_ike_auth_lifetime_t *this = malloc_thing(private_ike_auth_lifetime_t);
-
- 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_auth_lifetime_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa = ike_sa,
+ );
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;
-
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_cert_post.c b/src/libcharon/sa/tasks/ike_cert_post.c
index cc810a49a..94af50eae 100644
--- a/src/libcharon/sa/tasks/ike_cert_post.c
+++ b/src/libcharon/sa/tasks/ike_cert_post.c
@@ -87,6 +87,7 @@ static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this,
if (enumerator->enumerate(enumerator, &url))
{
payload = cert_payload_create_from_hash_and_url(hash, url);
+ DBG1(DBG_IKE, "sending hash-and-url \"%s\"", url);
}
else
{
@@ -167,28 +168,22 @@ static void build_certs(private_ike_cert_post_t *this, message_t *message)
}
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t build_i(private_ike_cert_post_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_cert_post_t *this, message_t *message)
{
build_certs(this, message);
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_cert_post_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_ike_cert_post_t *this, message_t *message)
{
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_cert_post_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_ike_cert_post_t *this, message_t *message)
{
build_certs(this, message);
@@ -199,10 +194,8 @@ static status_t build_r(private_ike_cert_post_t *this, message_t *message)
return SUCCESS;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_cert_post_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_cert_post_t *this, message_t *message)
{
if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
{ /* stay alive, we might have additional rounds with CERTS */
@@ -211,26 +204,20 @@ static status_t process_i(private_ike_cert_post_t *this, message_t *message)
return SUCCESS;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_cert_post_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_cert_post_t *this)
{
return IKE_CERT_POST;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_cert_post_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_cert_post_t *this, ike_sa_t *ike_sa)
{
this->ike_sa = ike_sa;
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_cert_post_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_cert_post_t *this)
{
free(this);
}
@@ -240,26 +227,31 @@ static void destroy(private_ike_cert_post_t *this)
*/
ike_cert_post_t *ike_cert_post_create(ike_sa_t *ike_sa, bool initiator)
{
- private_ike_cert_post_t *this = malloc_thing(private_ike_cert_post_t);
-
- 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_cert_post_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ },
+ .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;
-
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_cert_post.h b/src/libcharon/sa/tasks/ike_cert_post.h
index a21f45927..b3881a01a 100644
--- a/src/libcharon/sa/tasks/ike_cert_post.h
+++ b/src/libcharon/sa/tasks/ike_cert_post.h
@@ -45,7 +45,7 @@ struct ike_cert_post_t {
* of the certificate request.
*
* @param ike_sa IKE_SA this task works for
- * @param initiator TRUE if thask is the original initator
+ * @param initiator TRUE if task is the original initiator
* @return ike_cert_post task to handle by the task_manager
*/
ike_cert_post_t *ike_cert_post_create(ike_sa_t *ike_sa, bool initiator);
diff --git a/src/libcharon/sa/tasks/ike_cert_pre.c b/src/libcharon/sa/tasks/ike_cert_pre.c
index a59b8dcce..b33aebe46 100644
--- a/src/libcharon/sa/tasks/ike_cert_pre.c
+++ b/src/libcharon/sa/tasks/ike_cert_pre.c
@@ -51,7 +51,7 @@ struct private_ike_cert_pre_t {
bool do_http_lookup;
/**
- * wheter this is the final authentication round
+ * whether this is the final authentication round
*/
bool final;
};
@@ -424,10 +424,8 @@ static bool final_auth(message_t *message)
return TRUE;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t build_i(private_ike_cert_pre_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_cert_pre_t *this, message_t *message)
{
if (message->get_message_id(message) == 1)
{ /* initiator sends CERTREQs in first IKE_AUTH */
@@ -436,10 +434,8 @@ static status_t build_i(private_ike_cert_pre_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_cert_pre_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_ike_cert_pre_t *this, message_t *message)
{
if (message->get_exchange_type(message) != IKE_SA_INIT)
{ /* handle certreqs/certs in any IKE_AUTH, just in case */
@@ -450,10 +446,8 @@ static status_t process_r(private_ike_cert_pre_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_cert_pre_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_ike_cert_pre_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
@@ -466,10 +460,8 @@ static status_t build_r(private_ike_cert_pre_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_cert_pre_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_cert_pre_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
@@ -484,26 +476,20 @@ static status_t process_i(private_ike_cert_pre_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_cert_pre_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_cert_pre_t *this)
{
return IKE_CERT_PRE;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_cert_pre_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_cert_pre_t *this, ike_sa_t *ike_sa)
{
this->ike_sa = ike_sa;
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_cert_pre_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_cert_pre_t *this)
{
free(this);
}
@@ -513,27 +499,30 @@ static void destroy(private_ike_cert_pre_t *this)
*/
ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator)
{
- private_ike_cert_pre_t *this = malloc_thing(private_ike_cert_pre_t);
-
- 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_cert_pre_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ },
+ .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->do_http_lookup = FALSE;
- this->final = FALSE;
-
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_cert_pre.h b/src/libcharon/sa/tasks/ike_cert_pre.h
index 1541b80e5..4b2d0d470 100644
--- a/src/libcharon/sa/tasks/ike_cert_pre.h
+++ b/src/libcharon/sa/tasks/ike_cert_pre.h
@@ -45,7 +45,7 @@ struct ike_cert_pre_t {
* of the certificate request.
*
* @param ike_sa IKE_SA this task works for
- * @param initiator TRUE if thask is the original initator
+ * @param initiator TRUE if task is the original initiator
* @return ike_cert_pre task to handle by the task_manager
*/
ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator);
diff --git a/src/libcharon/sa/tasks/ike_config.c b/src/libcharon/sa/tasks/ike_config.c
index a61663c48..4ef9c56a5 100644
--- a/src/libcharon/sa/tasks/ike_config.c
+++ b/src/libcharon/sa/tasks/ike_config.c
@@ -174,6 +174,11 @@ static void process_attribute(private_ike_config_t *this,
}
break;
}
+ case INTERNAL_IP4_SERVER:
+ case INTERNAL_IP6_SERVER:
+ /* assume it's a Windows client if we see proprietary attributes */
+ this->ike_sa->enable_extension(this->ike_sa, EXT_MS_WINDOWS);
+ /* fall */
default:
{
if (this->initiator)
@@ -225,10 +230,8 @@ static void process_payloads(private_ike_config_t *this, message_t *message)
enumerator->destroy(enumerator);
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t build_i(private_ike_config_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_config_t *this, message_t *message)
{
if (message->get_message_id(message) == 1)
{ /* in first IKE_AUTH only */
@@ -287,10 +290,8 @@ static status_t build_i(private_ike_config_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_config_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_ike_config_t *this, message_t *message)
{
if (message->get_message_id(message) == 1)
{ /* in first IKE_AUTH only */
@@ -299,10 +300,8 @@ static status_t process_r(private_ike_config_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_config_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_ike_config_t *this, message_t *message)
{
if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
{ /* in last IKE_AUTH exchange */
@@ -366,10 +365,8 @@ static status_t build_r(private_ike_config_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_config_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_config_t *this, message_t *message)
{
if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
{ /* in last IKE_AUTH exchange */
@@ -385,18 +382,14 @@ static status_t process_i(private_ike_config_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_config_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_config_t *this)
{
return IKE_CONFIG;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_config_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_config_t *this, ike_sa_t *ike_sa)
{
DESTROY_IF(this->virtual_ip);
@@ -406,10 +399,8 @@ static void migrate(private_ike_config_t *this, ike_sa_t *ike_sa)
this->requested = linked_list_create();
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_config_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_config_t *this)
{
DESTROY_IF(this->virtual_ip);
this->requested->destroy_function(this->requested, free);
@@ -421,26 +412,30 @@ static void destroy(private_ike_config_t *this)
*/
ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator)
{
- private_ike_config_t *this = malloc_thing(private_ike_config_t);
-
- 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;
-
- this->initiator = initiator;
- this->ike_sa = ike_sa;
- this->virtual_ip = NULL;
- this->requested = linked_list_create();
+ private_ike_config_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ },
+ .initiator = initiator,
+ .ike_sa = ike_sa,
+ .requested = linked_list_create(),
+ );
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;
}
return &this->public;
diff --git a/src/libcharon/sa/tasks/ike_delete.c b/src/libcharon/sa/tasks/ike_delete.c
index 130948836..d79674fe4 100644
--- a/src/libcharon/sa/tasks/ike_delete.c
+++ b/src/libcharon/sa/tasks/ike_delete.c
@@ -52,10 +52,8 @@ struct private_ike_delete_t {
bool simultaneous;
};
-/**
- * Implementation of task_t.build for initiator
- */
-static status_t build_i(private_ike_delete_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_delete_t *this, message_t *message)
{
delete_payload_t *delete_payload;
@@ -83,10 +81,8 @@ static status_t build_i(private_ike_delete_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_delete_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_delete_t *this, message_t *message)
{
DBG0(DBG_IKE, "IKE_SA deleted");
if (!this->rekeyed)
@@ -97,10 +93,8 @@ static status_t process_i(private_ike_delete_t *this, message_t *message)
return DESTROY_ME;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_delete_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_ike_delete_t *this, message_t *message)
{
/* we don't even scan the payloads, as the message wouldn't have
* come so far without being correct */
@@ -134,16 +128,14 @@ static status_t process_r(private_ike_delete_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_delete_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_ike_delete_t *this, message_t *message)
{
DBG0(DBG_IKE, "IKE_SA deleted");
if (this->simultaneous)
{
- /* wait for peer's response for our delete request, but set a timeout */
+ /* wait for peer's response for our delete request */
return SUCCESS;
}
if (!this->rekeyed)
@@ -154,27 +146,21 @@ static status_t build_r(private_ike_delete_t *this, message_t *message)
return DESTROY_ME;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_delete_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_delete_t *this)
{
return IKE_DELETE;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_delete_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_delete_t *this, ike_sa_t *ike_sa)
{
this->ike_sa = ike_sa;
this->simultaneous = FALSE;
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_delete_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_delete_t *this)
{
free(this);
}
@@ -184,27 +170,30 @@ static void destroy(private_ike_delete_t *this)
*/
ike_delete_t *ike_delete_create(ike_sa_t *ike_sa, bool initiator)
{
- private_ike_delete_t *this = malloc_thing(private_ike_delete_t);
-
- 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_delete_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ },
+ .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->rekeyed = FALSE;
- this->simultaneous = FALSE;
-
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_dpd.c b/src/libcharon/sa/tasks/ike_dpd.c
index 4c6ba7662..106eff87c 100644
--- a/src/libcharon/sa/tasks/ike_dpd.c
+++ b/src/libcharon/sa/tasks/ike_dpd.c
@@ -31,44 +31,33 @@ struct private_ike_dpd_t {
ike_dpd_t public;
};
-/**
- * Implementation of task_t.build for initiator
- * Implementation of task_t.process for responder
- */
-static status_t return_need_more(private_ike_dpd_t *this, message_t *message)
+METHOD(task_t, return_need_more, status_t,
+ private_ike_dpd_t *this, message_t *message)
{
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for initiator
- * Implementation of task_t.build for responder
- */
-static status_t return_success(private_ike_dpd_t *this, message_t *message)
+METHOD(task_t, return_success, status_t,
+ private_ike_dpd_t *this, message_t *message)
{
return SUCCESS;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_dpd_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_dpd_t *this)
{
return IKE_DPD;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_dpd_t *this, ike_sa_t *ike_sa)
+
+METHOD(task_t, migrate, void,
+ private_ike_dpd_t *this, ike_sa_t *ike_sa)
{
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_dpd_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_dpd_t *this)
{
free(this);
}
@@ -78,21 +67,27 @@ static void destroy(private_ike_dpd_t *this)
*/
ike_dpd_t *ike_dpd_create(bool initiator)
{
- private_ike_dpd_t *this = malloc_thing(private_ike_dpd_t);
-
- 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_dpd_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ },
+ );
if (initiator)
{
- this->public.task.build = (status_t(*)(task_t*,message_t*))return_need_more;
- this->public.task.process = (status_t(*)(task_t*,message_t*))return_success;
+ this->public.task.build = _return_need_more;
+ this->public.task.process = _return_success;
}
else
{
- this->public.task.build = (status_t(*)(task_t*,message_t*))return_success;
- this->public.task.process = (status_t(*)(task_t*,message_t*))return_need_more;
+ this->public.task.build = _return_success;
+ this->public.task.process = _return_need_more;
}
return &this->public;
diff --git a/src/libcharon/sa/tasks/ike_dpd.h b/src/libcharon/sa/tasks/ike_dpd.h
index 36388d15b..a9f68c31c 100644
--- a/src/libcharon/sa/tasks/ike_dpd.h
+++ b/src/libcharon/sa/tasks/ike_dpd.h
@@ -43,7 +43,7 @@ struct ike_dpd_t {
/**
* Create a new ike_dpd task.
*
- * @param initiator TRUE if thask is the original initator
+ * @param initiator TRUE if task is the original initiator
* @return ike_dpd task to handle by the task_manager
*/
ike_dpd_t *ike_dpd_create(bool initiator);
diff --git a/src/libcharon/sa/tasks/ike_init.c b/src/libcharon/sa/tasks/ike_init.c
index dd4a5f5c0..dd8a4b086 100644
--- a/src/libcharon/sa/tasks/ike_init.c
+++ b/src/libcharon/sa/tasks/ike_init.c
@@ -112,7 +112,7 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
linked_list_t *proposal_list;
ike_sa_id_t *id;
proposal_t *proposal;
- iterator_t *iterator;
+ enumerator_t *enumerator;
id = this->ike_sa->get_id(this->ike_sa);
@@ -124,12 +124,12 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
if (this->old_sa)
{
/* include SPI of new IKE_SA when we are rekeying */
- iterator = proposal_list->create_iterator(proposal_list, TRUE);
- while (iterator->iterate(iterator, (void**)&proposal))
+ enumerator = proposal_list->create_enumerator(proposal_list);
+ while (enumerator->enumerate(enumerator, (void**)&proposal))
{
proposal->set_spi(proposal, id->get_initiator_spi(id));
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
sa_payload = sa_payload_create_from_proposal_list(proposal_list);
@@ -221,10 +221,8 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
enumerator->destroy(enumerator);
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t build_i(private_ike_init_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_init_t *this, message_t *message)
{
rng_t *rng;
@@ -287,10 +285,8 @@ static status_t build_i(private_ike_init_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_init_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_ike_init_t *this, message_t *message)
{
rng_t *rng;
@@ -361,10 +357,8 @@ static bool derive_keys(private_ike_init_t *this,
return TRUE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_init_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_ike_init_t *this, message_t *message)
{
/* check if we have everything we need */
if (this->proposal == NULL ||
@@ -409,10 +403,8 @@ static status_t build_r(private_ike_init_t *this, message_t *message)
return SUCCESS;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_init_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_init_t *this, message_t *message)
{
enumerator_t *enumerator;
payload_t *payload;
@@ -510,34 +502,14 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
return SUCCESS;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_init_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_init_t *this)
{
return IKE_INIT;
}
-/**
- * Implementation of task_t.get_type
- */
-static chunk_t get_lower_nonce(private_ike_init_t *this)
-{
- if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr,
- min(this->my_nonce.len, this->other_nonce.len)) < 0)
- {
- return this->my_nonce;
- }
- else
- {
- return this->other_nonce;
- }
-}
-
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_init_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_init_t *this, ike_sa_t *ike_sa)
{
DESTROY_IF(this->proposal);
chunk_free(&this->other_nonce);
@@ -545,14 +517,15 @@ static void migrate(private_ike_init_t *this, ike_sa_t *ike_sa)
this->ike_sa = ike_sa;
this->keymat = ike_sa->get_keymat(ike_sa);
this->proposal = NULL;
- DESTROY_IF(this->dh);
- this->dh = this->keymat->create_dh(this->keymat, this->dh_group);
+ if (this->dh && this->dh->get_dh_group(this->dh) != this->dh_group)
+ { /* reset DH value only if group changed (INVALID_KE_PAYLOAD) */
+ this->dh->destroy(this->dh);
+ this->dh = this->keymat->create_dh(this->keymat, this->dh_group);
+ }
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_init_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_init_t *this)
{
DESTROY_IF(this->dh);
DESTROY_IF(this->proposal);
@@ -562,40 +535,53 @@ static void destroy(private_ike_init_t *this)
free(this);
}
+METHOD(ike_init_t, get_lower_nonce, chunk_t,
+ private_ike_init_t *this)
+{
+ if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr,
+ min(this->my_nonce.len, this->other_nonce.len)) < 0)
+ {
+ return this->my_nonce;
+ }
+ else
+ {
+ return this->other_nonce;
+ }
+}
+
/*
* Described in header.
*/
ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa)
{
- private_ike_init_t *this = malloc_thing(private_ike_init_t);
+ private_ike_init_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ .get_lower_nonce = _get_lower_nonce,
+ },
+ .ike_sa = ike_sa,
+ .initiator = initiator,
+ .dh_group = MODP_NONE,
+ .keymat = ike_sa->get_keymat(ike_sa),
+ .old_sa = old_sa,
+ );
- this->public.get_lower_nonce = (chunk_t(*)(ike_init_t*))get_lower_nonce;
- 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;
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->dh_group = MODP_NONE;
- this->dh = NULL;
- this->keymat = ike_sa->get_keymat(ike_sa);
- this->my_nonce = chunk_empty;
- this->other_nonce = chunk_empty;
- this->cookie = chunk_empty;
- this->proposal = NULL;
- this->config = NULL;
- this->old_sa = old_sa;
- this->retry = 0;
-
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_init.h b/src/libcharon/sa/tasks/ike_init.h
index 7bd784cff..4b7f60416 100644
--- a/src/libcharon/sa/tasks/ike_init.h
+++ b/src/libcharon/sa/tasks/ike_init.h
@@ -51,7 +51,7 @@ struct ike_init_t {
* Create a new IKE_INIT task.
*
* @param ike_sa IKE_SA this task works for (new one when rekeying)
- * @param initiator TRUE if thask is the original initator
+ * @param initiator TRUE if task is the original initiator
* @param old_sa old IKE_SA when we are rekeying
* @return ike_init task to handle by the task_manager
*/
diff --git a/src/libcharon/sa/tasks/ike_me.c b/src/libcharon/sa/tasks/ike_me.c
index 1de6ae8fc..8f90efcc3 100644
--- a/src/libcharon/sa/tasks/ike_me.c
+++ b/src/libcharon/sa/tasks/ike_me.c
@@ -111,15 +111,15 @@ struct private_ike_me_t {
*/
static void add_endpoints_to_message(message_t *message, linked_list_t *endpoints)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
endpoint_notify_t *endpoint;
- iterator = endpoints->create_iterator(endpoints, TRUE);
- while (iterator->iterate(iterator, (void**)&endpoint))
+ enumerator = endpoints->create_enumerator(endpoints);
+ while (enumerator->enumerate(enumerator, (void**)&endpoint))
{
message->add_payload(message, (payload_t*)endpoint->build_notify(endpoint));
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -242,10 +242,8 @@ static void process_payloads(private_ike_me_t *this, message_t *message)
enumerator->destroy(enumerator);
}
-/**
- * Implementation of task_t.build for initiator
- */
-static status_t build_i(private_ike_me_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
@@ -321,10 +319,8 @@ static status_t build_i(private_ike_me_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_me_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
@@ -381,10 +377,8 @@ static status_t process_r(private_ike_me_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_me_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
@@ -440,10 +434,8 @@ static status_t build_r(private_ike_me_t *this, message_t *message)
return SUCCESS;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_me_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
@@ -520,9 +512,10 @@ static status_t process_i(private_ike_me_t *this, message_t *message)
}
/**
- * Implementation of task_t.build for initiator (mediation server)
+ * For mediation server
*/
-static status_t build_i_ms(private_ike_me_t *this, message_t *message)
+METHOD(task_t, build_i_ms, status_t,
+ private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
@@ -559,9 +552,10 @@ static status_t build_i_ms(private_ike_me_t *this, message_t *message)
}
/**
- * Implementation of task_t.process for responder (mediation server)
+ * For mediation server
*/
-static status_t process_r_ms(private_ike_me_t *this, message_t *message)
+METHOD(task_t, process_r_ms, status_t,
+ private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
@@ -632,9 +626,10 @@ static status_t process_r_ms(private_ike_me_t *this, message_t *message)
}
/**
- * Implementation of task_t.build for responder (mediation server)
+ * For mediation server
*/
-static status_t build_r_ms(private_ike_me_t *this, message_t *message)
+METHOD(task_t, build_r_ms, status_t,
+ private_ike_me_t *this, message_t *message)
{
switch(message->get_exchange_type(message))
{
@@ -703,9 +698,10 @@ static status_t build_r_ms(private_ike_me_t *this, message_t *message)
}
/**
- * Implementation of task_t.process for initiator (mediation server)
+ * For mediation server
*/
-static status_t process_i_ms(private_ike_me_t *this, message_t *message)
+METHOD(task_t, process_i_ms, status_t,
+ private_ike_me_t *this, message_t *message)
{
/* FIXME: theoretically we should be prepared to receive a ME_CONNECT_FAILED
* here if the responding peer is not able to proceed. in this case we shall
@@ -714,40 +710,30 @@ static status_t process_i_ms(private_ike_me_t *this, message_t *message)
return SUCCESS;
}
-/**
- * Implementation of ike_me.connect
- */
-static void me_connect(private_ike_me_t *this, identification_t *peer_id)
+METHOD(ike_me_t, me_connect, void,
+ private_ike_me_t *this, identification_t *peer_id)
{
this->peer_id = peer_id->clone(peer_id);
}
-/**
- * Implementation of ike_me.respond
- */
-static void me_respond(private_ike_me_t *this, identification_t *peer_id,
- chunk_t connect_id)
+METHOD(ike_me_t, me_respond, void,
+ private_ike_me_t *this, identification_t *peer_id, chunk_t connect_id)
{
this->peer_id = peer_id->clone(peer_id);
this->connect_id = chunk_clone(connect_id);
this->response = TRUE;
}
-/**
- * Implementation of ike_me.callback
- */
-static void me_callback(private_ike_me_t *this, identification_t *peer_id)
+METHOD(ike_me_t, me_callback, void,
+ private_ike_me_t *this, identification_t *peer_id)
{
this->peer_id = peer_id->clone(peer_id);
this->callback = TRUE;
}
-/**
- * Implementation of ike_me.relay
- */
-static void relay(private_ike_me_t *this, identification_t *requester,
- chunk_t connect_id, chunk_t connect_key,
- linked_list_t *endpoints, bool response)
+METHOD(ike_me_t, relay, void,
+ private_ike_me_t *this, identification_t *requester, chunk_t connect_id,
+ chunk_t connect_key, linked_list_t *endpoints, bool response)
{
this->peer_id = requester->clone(requester);
this->connect_id = chunk_clone(connect_id);
@@ -761,26 +747,20 @@ static void relay(private_ike_me_t *this, identification_t *requester,
this->response = response;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_me_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_me_t *this)
{
return IKE_ME;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_me_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_me_t *this, ike_sa_t *ike_sa)
{
this->ike_sa = ike_sa;
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_me_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_me_t *this)
{
DESTROY_IF(this->peer_id);
@@ -801,23 +781,37 @@ static void destroy(private_ike_me_t *this)
*/
ike_me_t *ike_me_create(ike_sa_t *ike_sa, bool initiator)
{
- private_ike_me_t *this = malloc_thing(private_ike_me_t);
-
- 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_me_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ .connect = _me_connect,
+ .respond = _me_respond,
+ .callback = _me_callback,
+ .relay = _relay,
+ },
+ .ike_sa = ike_sa,
+ .initiator = initiator,
+ .local_endpoints = linked_list_create(),
+ .remote_endpoints = linked_list_create(),
+ );
if (ike_sa->has_condition(ike_sa, COND_ORIGINAL_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;
}
}
else
@@ -825,36 +819,15 @@ ike_me_t *ike_me_create(ike_sa_t *ike_sa, bool initiator)
/* mediation server */
if (initiator)
{
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_i_ms;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_i_ms;
+ this->public.task.build = _build_i_ms;
+ this->public.task.process = _process_i_ms;
}
else
{
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_r_ms;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_r_ms;
+ this->public.task.build = _build_r_ms;
+ this->public.task.process = _process_r_ms;
}
}
- this->public.connect = (void(*)(ike_me_t*,identification_t*))me_connect;
- this->public.respond = (void(*)(ike_me_t*,identification_t*,chunk_t))me_respond;
- this->public.callback = (void(*)(ike_me_t*,identification_t*))me_callback;
- this->public.relay = (void(*)(ike_me_t*,identification_t*,chunk_t,chunk_t,linked_list_t*,bool))relay;
-
- this->ike_sa = ike_sa;
- this->initiator = initiator;
-
- this->peer_id = NULL;
- this->connect_id = chunk_empty;
- this->connect_key = chunk_empty;
- this->local_endpoints = linked_list_create();
- this->remote_endpoints = linked_list_create();
- this->mediation = FALSE;
- this->response = FALSE;
- this->callback = FALSE;
- this->failed = FALSE;
- this->invalid_syntax = FALSE;
-
- this->mediated_cfg = NULL;
-
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_mobike.c b/src/libcharon/sa/tasks/ike_mobike.c
index 5b12eaaac..fb1100028 100644
--- a/src/libcharon/sa/tasks/ike_mobike.c
+++ b/src/libcharon/sa/tasks/ike_mobike.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2010-2012 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -79,24 +80,6 @@ struct private_ike_mobike_t {
};
/**
- * flush the IKE_SAs list of additional addresses
- */
-static void flush_additional_addresses(private_ike_mobike_t *this)
-{
- iterator_t *iterator;
- host_t *host;
-
- iterator = this->ike_sa->create_additional_address_iterator(this->ike_sa);
- while (iterator->iterate(iterator, (void**)&host))
- {
- iterator->remove(iterator);
- host->destroy(host);
- }
- iterator->destroy(iterator);
-}
-
-
-/**
* read notifys from message and evaluate them
*/
static void process_payloads(private_ike_mobike_t *this, message_t *message)
@@ -152,13 +135,17 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
{
if (first)
{ /* an ADDITIONAL_*_ADDRESS means replace, so flush once */
- flush_additional_addresses(this);
+ this->ike_sa->clear_peer_addresses(this->ike_sa);
first = FALSE;
+ /* add the peer's current address to the list */
+ host = message->get_source(message);
+ this->ike_sa->add_peer_address(this->ike_sa,
+ host->clone(host));
}
data = notify->get_notification_data(notify);
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->ike_sa->add_peer_address(this->ike_sa, host);
this->addresses_updated = TRUE;
break;
}
@@ -169,7 +156,10 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
}
case NO_ADDITIONAL_ADDRESSES:
{
- flush_additional_addresses(this);
+ this->ike_sa->clear_peer_addresses(this->ike_sa);
+ /* add the peer's current address to the list */
+ host = message->get_source(message);
+ this->ike_sa->add_peer_address(this->ike_sa, host->clone(host));
this->addresses_updated = TRUE;
break;
}
@@ -256,11 +246,11 @@ static void build_cookie(private_ike_mobike_t *this, message_t *message)
*/
static void update_children(private_ike_mobike_t *this)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
child_sa_t *child_sa;
- iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
if (child_sa->update(child_sa,
this->ike_sa->get_my_host(this->ike_sa),
@@ -273,7 +263,7 @@ static void update_children(private_ike_mobike_t *this)
child_sa->get_spi(child_sa, TRUE));
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
/**
@@ -296,7 +286,7 @@ 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;
+ enumerator_t *enumerator;
ike_cfg_t *ike_cfg;
packet_t *copy;
@@ -309,19 +299,8 @@ METHOD(ike_mobike_t, transmit, void,
other_old = this->ike_sa->get_other_host(this->ike_sa);
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
- me = hydra->kernel_interface->get_source_addr(
- hydra->kernel_interface, other_old, NULL);
- if (me)
- {
- 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);
- charon->sender->send(charon->sender, copy);
- }
-
- iterator = this->ike_sa->create_additional_address_iterator(this->ike_sa);
- while (iterator->iterate(iterator, (void**)&other))
+ enumerator = this->ike_sa->create_peer_address_enumerator(this->ike_sa);
+ while (enumerator->enumerate(enumerator, (void**)&other))
{
me = hydra->kernel_interface->get_source_addr(
hydra->kernel_interface, other, NULL);
@@ -343,7 +322,7 @@ METHOD(ike_mobike_t, transmit, void,
charon->sender->send(charon->sender, copy);
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
METHOD(task_t, build_i, status_t,
diff --git a/src/libcharon/sa/tasks/ike_natd.c b/src/libcharon/sa/tasks/ike_natd.c
index 7839b52eb..f06a518fa 100644
--- a/src/libcharon/sa/tasks/ike_natd.c
+++ b/src/libcharon/sa/tasks/ike_natd.c
@@ -256,10 +256,8 @@ static void process_payloads(private_ike_natd_t *this, message_t *message)
}
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_natd_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_natd_t *this, message_t *message)
{
process_payloads(this, message);
@@ -281,10 +279,8 @@ static status_t process_i(private_ike_natd_t *this, message_t *message)
return SUCCESS;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t build_i(private_ike_natd_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_natd_t *this, message_t *message)
{
notify_payload_t *notify;
enumerator_t *enumerator;
@@ -345,15 +341,13 @@ static status_t build_i(private_ike_natd_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_natd_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_ike_natd_t *this, message_t *message)
{
notify_payload_t *notify;
host_t *me, *other;
- /* only add notifies on successfull responses. */
+ /* only add notifies on successful responses. */
if (message->get_exchange_type(message) == IKE_SA_INIT &&
message->get_payload(message, SECURITY_ASSOCIATION) == NULL)
{
@@ -380,28 +374,22 @@ static status_t build_r(private_ike_natd_t *this, message_t *message)
return SUCCESS;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_natd_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_ike_natd_t *this, message_t *message)
{
process_payloads(this, message);
return NEED_MORE;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_natd_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_natd_t *this)
{
return IKE_NATD;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_natd_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_natd_t *this, ike_sa_t *ike_sa)
{
this->ike_sa = ike_sa;
this->src_seen = FALSE;
@@ -411,21 +399,17 @@ static void migrate(private_ike_natd_t *this, ike_sa_t *ike_sa)
this->mapping_changed = FALSE;
}
-/**
- * Implementation of ike_natd_t.has_mapping_changed
- */
-static bool has_mapping_changed(private_ike_natd_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_natd_t *this)
{
- return this->mapping_changed;
+ DESTROY_IF(this->hasher);
+ free(this);
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_natd_t *this)
+METHOD(ike_natd_t, has_mapping_changed, bool,
+ private_ike_natd_t *this)
{
- DESTROY_IF(this->hasher);
- free(this);
+ return this->mapping_changed;
}
/*
@@ -433,33 +417,32 @@ static void destroy(private_ike_natd_t *this)
*/
ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator)
{
- private_ike_natd_t *this = malloc_thing(private_ike_natd_t);
-
- 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_natd_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ .has_mapping_changed = _has_mapping_changed,
+ },
+ .ike_sa = ike_sa,
+ .initiator = initiator,
+ .hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1),
+ );
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->public.has_mapping_changed = (bool(*)(ike_natd_t*))has_mapping_changed;
-
- this->ike_sa = ike_sa;
- this->initiator = initiator;
- this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- this->src_seen = FALSE;
- this->dst_seen = FALSE;
- this->src_matched = FALSE;
- this->dst_matched = FALSE;
- this->mapping_changed = FALSE;
-
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_natd.h b/src/libcharon/sa/tasks/ike_natd.h
index 97b652ead..68114af42 100644
--- a/src/libcharon/sa/tasks/ike_natd.h
+++ b/src/libcharon/sa/tasks/ike_natd.h
@@ -51,7 +51,7 @@ struct ike_natd_t {
* Create a new ike_natd task.
*
* @param ike_sa IKE_SA this task works for
- * @param initiator TRUE if thask is the original initator
+ * @param initiator TRUE if task is the original initiator
* @return ike_natd task to handle by the task_manager
*/
ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator);
diff --git a/src/libcharon/sa/tasks/ike_reauth.c b/src/libcharon/sa/tasks/ike_reauth.c
index ac89c358b..48002d81c 100644
--- a/src/libcharon/sa/tasks/ike_reauth.c
+++ b/src/libcharon/sa/tasks/ike_reauth.c
@@ -42,134 +42,44 @@ struct private_ike_reauth_t {
ike_delete_t *ike_delete;
};
-/**
- * Implementation of task_t.build for initiator
- */
-static status_t build_i(private_ike_reauth_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_reauth_t *this, message_t *message)
{
return this->ike_delete->task.build(&this->ike_delete->task, message);
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_reauth_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_reauth_t *this, message_t *message)
{
- ike_sa_t *new;
- host_t *host;
- iterator_t *iterator;
- child_sa_t *child_sa;
- peer_cfg_t *peer_cfg;
-
/* process delete response first */
this->ike_delete->task.process(&this->ike_delete->task, message);
- peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
-
- /* reauthenticate only if we have children */
- iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa);
- if (iterator->get_count(iterator) == 0
-#ifdef ME
- /* we allow peers to reauth mediation connections (without children) */
- && !peer_cfg->is_mediation(peer_cfg)
-#endif /* ME */
- )
+ /* reestablish the IKE_SA with all children */
+ if (this->ike_sa->reestablish(this->ike_sa) != SUCCESS)
{
- DBG1(DBG_IKE, "unable to reauthenticate IKE_SA, no CHILD_SA to recreate");
- iterator->destroy(iterator);
+ DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
return FAILED;
}
- new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, TRUE);
-
- new->set_peer_cfg(new, peer_cfg);
- host = this->ike_sa->get_other_host(this->ike_sa);
- new->set_other_host(new, host->clone(host));
- host = this->ike_sa->get_my_host(this->ike_sa);
- new->set_my_host(new, host->clone(host));
- /* if we already have a virtual IP, we reuse it */
- host = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
- if (host)
- {
- new->set_virtual_ip(new, TRUE, host);
- }
-
-#ifdef ME
- /* we initiate the new IKE_SA of the mediation connection without CHILD_SA */
- if (peer_cfg->is_mediation(peer_cfg))
- {
- if (new->initiate(new, NULL, 0, NULL, NULL) == DESTROY_ME)
- {
- charon->ike_sa_manager->checkin_and_destroy(
- charon->ike_sa_manager, new);
- /* set threads active IKE_SA after checkin */
- charon->bus->set_sa(charon->bus, this->ike_sa);
- DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
- return FAILED;
- }
- }
-#endif /* ME */
-
- while (iterator->iterate(iterator, (void**)&child_sa))
- {
- switch (child_sa->get_state(child_sa))
- {
- case CHILD_ROUTED:
- {
- /* move routed child directly */
- iterator->remove(iterator);
- new->add_child_sa(new, child_sa);
- break;
- }
- default:
- {
- /* initiate/queue all child SAs */
- child_cfg_t *child_cfg = child_sa->get_config(child_sa);
- child_cfg->get_ref(child_cfg);
- if (new->initiate(new, child_cfg, 0, NULL, NULL) == DESTROY_ME)
- {
- iterator->destroy(iterator);
- charon->ike_sa_manager->checkin_and_destroy(
- charon->ike_sa_manager, new);
- /* set threads active IKE_SA after checkin */
- charon->bus->set_sa(charon->bus, this->ike_sa);
- DBG1(DBG_IKE, "reauthenticating IKE_SA failed");
- return FAILED;
- }
- break;
- }
- }
- }
- iterator->destroy(iterator);
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, new);
- /* set threads active IKE_SA after checkin */
- charon->bus->set_sa(charon->bus, this->ike_sa);
-
- /* we always return failed to delete the obsolete IKE_SA */
- return FAILED;
+ /* we always destroy the obsolete IKE_SA */
+ return DESTROY_ME;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_reauth_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_reauth_t *this)
{
return IKE_REAUTH;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_reauth_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_reauth_t *this, ike_sa_t *ike_sa)
{
this->ike_delete->task.migrate(&this->ike_delete->task, ike_sa);
this->ike_sa = ike_sa;
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_reauth_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_reauth_t *this)
{
this->ike_delete->task.destroy(&this->ike_delete->task);
free(this);
@@ -180,16 +90,21 @@ static void destroy(private_ike_reauth_t *this)
*/
ike_reauth_t *ike_reauth_create(ike_sa_t *ike_sa)
{
- private_ike_reauth_t *this = malloc_thing(private_ike_reauth_t);
-
- 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;
- 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->ike_sa = ike_sa;
- this->ike_delete = ike_delete_create(ike_sa, TRUE);
+ private_ike_reauth_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .build = _build_i,
+ .process = _process_i,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa = ike_sa,
+ .ike_delete = ike_delete_create(ike_sa, TRUE),
+ );
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_rekey.c b/src/libcharon/sa/tasks/ike_rekey.c
index c055dabc1..826d6e192 100644
--- a/src/libcharon/sa/tasks/ike_rekey.c
+++ b/src/libcharon/sa/tasks/ike_rekey.c
@@ -147,8 +147,8 @@ METHOD(task_t, build_i, status_t,
METHOD(task_t, process_r, status_t,
private_ike_rekey_t *this, message_t *message)
{
+ enumerator_t *enumerator;
peer_cfg_t *peer_cfg;
- iterator_t *iterator;
child_sa_t *child_sa;
if (this->ike_sa->get_state(this->ike_sa) == IKE_DELETING)
@@ -157,8 +157,8 @@ METHOD(task_t, process_r, status_t,
return NEED_MORE;
}
- iterator = this->ike_sa->create_child_sa_iterator(this->ike_sa);
- while (iterator->iterate(iterator, (void**)&child_sa))
+ enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
+ while (enumerator->enumerate(enumerator, (void**)&child_sa))
{
switch (child_sa->get_state(child_sa))
{
@@ -167,13 +167,13 @@ METHOD(task_t, process_r, status_t,
case CHILD_DELETING:
/* we do not allow rekeying while we have children in-progress */
DBG1(DBG_IKE, "peer initiated rekeying, but a child is half-open");
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return NEED_MORE;
default:
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
this->new_sa = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
FALSE);
diff --git a/src/libcharon/sa/tasks/ike_vendor.h b/src/libcharon/sa/tasks/ike_vendor.h
index dcdd37424..6c353c447 100644
--- a/src/libcharon/sa/tasks/ike_vendor.h
+++ b/src/libcharon/sa/tasks/ike_vendor.h
@@ -42,7 +42,7 @@ struct ike_vendor_t {
* Create a ike_vendor instance.
*
* @param ike_sa IKE_SA this task works for
- * @param initiator TRUE if thask is the original initator
+ * @param initiator TRUE if task is the original initiator
*/
ike_vendor_t *ike_vendor_create(ike_sa_t *ike_sa, bool initiator);
diff --git a/src/libcharon/sa/tasks/task.h b/src/libcharon/sa/tasks/task.h
index 4468f2ebe..d57085954 100644
--- a/src/libcharon/sa/tasks/task.h
+++ b/src/libcharon/sa/tasks/task.h
@@ -89,7 +89,7 @@ extern enum_name_t *task_type_names;
* A responder does the opposite; it calls process() first to handle an incoming
* request and secondly calls build() to build an appropriate response.
* Both methods return either SUCCESS, NEED_MORE or FAILED. A SUCCESS indicates
- * that the task completed, even when the task completed unsuccesfully. The
+ * that the task completed, even when the task completed unsuccessfully. The
* manager then removes the task from the list. A NEED_MORE is returned when
* the task needs further build()/process() calls to complete, the manager
* leaves the taks in the queue. A returned FAILED indicates a critical failure.
@@ -102,7 +102,7 @@ struct task_t {
*
* @param message message to add payloads to
* @return
- * - FAILED if a critical error occured
+ * - FAILED if a critical error occurred
* - DESTROY_ME if IKE_SA has been properly deleted
* - NEED_MORE if another call to build/process needed
* - SUCCESS if task completed
@@ -114,7 +114,7 @@ struct task_t {
*
* @param message message to read payloads from
* @return
- * - FAILED if a critical error occured
+ * - FAILED if a critical error occurred
* - DESTROY_ME if IKE_SA has been properly deleted
* - NEED_MORE if another call to build/process needed
* - SUCCESS if task completed
diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c
index f91eff077..86d9f4c22 100644
--- a/src/libcharon/sa/trap_manager.c
+++ b/src/libcharon/sa/trap_manager.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2011 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -74,8 +75,10 @@ typedef struct {
peer_cfg_t *peer_cfg;
/** ref to instanciated CHILD_SA */
child_sa_t *child_sa;
+ /** TRUE if an acquire is pending */
+ bool pending;
/** pending IKE_SA connecting upon acquire */
- ike_sa_t *pending;
+ ike_sa_t *ike_sa;
} entry_t;
/**
@@ -88,11 +91,8 @@ static void destroy_entry(entry_t *entry)
free(entry);
}
-/**
- * Implementation of trap_manager_t.install
- */
-static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer,
- child_cfg_t *child)
+METHOD(trap_manager_t, install, u_int32_t,
+ private_trap_manager_t *this, peer_cfg_t *peer, child_cfg_t *child)
{
entry_t *entry;
ike_cfg_t *ike_cfg;
@@ -158,8 +158,8 @@ static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer,
other->destroy(other);
/* while we don't know the finally negotiated protocol (ESP|AH), we
- * could iterate all proposals for a best guest (TODO). But as we
- * support ESP only for now, we set here. */
+ * could iterate all proposals for a best guess (TODO). But as we
+ * support ESP only for now, we set it here. */
child_sa->set_protocol(child_sa, PROTO_ESP);
child_sa->set_mode(child_sa, child->get_mode(child));
status = child_sa->add_policies(child_sa, my_ts, other_ts);
@@ -173,10 +173,10 @@ static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer,
}
reqid = child_sa->get_reqid(child_sa);
- entry = malloc_thing(entry_t);
- entry->child_sa = child_sa;
- entry->peer_cfg = peer->get_ref(peer);
- entry->pending = NULL;
+ INIT(entry,
+ .child_sa = child_sa,
+ .peer_cfg = peer->get_ref(peer),
+ );
this->lock->write_lock(this->lock);
this->traps->insert_last(this->traps, entry);
@@ -185,10 +185,8 @@ static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer,
return reqid;
}
-/**
- * Implementation of trap_manager_t.uninstall
- */
-static bool uninstall(private_trap_manager_t *this, u_int32_t reqid)
+METHOD(trap_manager_t, uninstall, bool,
+ private_trap_manager_t *this, u_int32_t reqid)
{
enumerator_t *enumerator;
entry_t *entry, *found = NULL;
@@ -234,10 +232,8 @@ static bool trap_filter(rwlock_t *lock, entry_t **entry, peer_cfg_t **peer_cfg,
return TRUE;
}
-/**
- * Implementation of trap_manager_t.create_enumerator
- */
-static enumerator_t* create_enumerator(private_trap_manager_t *this)
+METHOD(trap_manager_t, create_enumerator, enumerator_t*,
+ private_trap_manager_t *this)
{
this->lock->read_lock(this->lock);
return enumerator_create_filter(this->traps->create_enumerator(this->traps),
@@ -245,11 +241,9 @@ static enumerator_t* create_enumerator(private_trap_manager_t *this)
(void*)this->lock->unlock);
}
-/**
- * Implementation of trap_manager_t.acquire
- */
-static void acquire(private_trap_manager_t *this, u_int32_t reqid,
- traffic_selector_t *src, traffic_selector_t *dst)
+METHOD(trap_manager_t, acquire, void,
+ private_trap_manager_t *this, u_int32_t reqid,
+ traffic_selector_t *src, traffic_selector_t *dst)
{
enumerator_t *enumerator;
entry_t *entry, *found = NULL;
@@ -272,35 +266,46 @@ static void acquire(private_trap_manager_t *this, u_int32_t reqid,
if (!found)
{
DBG1(DBG_CFG, "trap not found, unable to acquire reqid %d",reqid);
+ this->lock->unlock(this->lock);
+ return;
}
- else if (found->pending)
+ if (!cas_bool(&found->pending, FALSE, TRUE))
{
DBG1(DBG_CFG, "ignoring acquire, connection attempt pending");
+ this->lock->unlock(this->lock);
+ return;
}
- else
+ peer = found->peer_cfg->get_ref(found->peer_cfg);
+ child = found->child_sa->get_config(found->child_sa);
+ child = child->get_ref(child);
+ reqid = found->child_sa->get_reqid(found->child_sa);
+ /* don't hold the lock while checking out the IKE_SA */
+ this->lock->unlock(this->lock);
+
+ ike_sa = charon->ike_sa_manager->checkout_by_config(
+ charon->ike_sa_manager, peer);
+ if (ike_sa->get_peer_cfg(ike_sa) == NULL)
{
- child = found->child_sa->get_config(found->child_sa);
- peer = found->peer_cfg;
- ike_sa = charon->ike_sa_manager->checkout_by_config(
- charon->ike_sa_manager, peer);
- if (ike_sa->get_peer_cfg(ike_sa) == NULL)
- {
- ike_sa->set_peer_cfg(ike_sa, peer);
- }
- child->get_ref(child);
- reqid = found->child_sa->get_reqid(found->child_sa);
- if (ike_sa->initiate(ike_sa, child, reqid, src, dst) != DESTROY_ME)
- {
- found->pending = ike_sa;
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
- }
- else
+ ike_sa->set_peer_cfg(ike_sa, peer);
+ }
+ if (ike_sa->initiate(ike_sa, child, reqid, src, dst) != DESTROY_ME)
+ {
+ /* make sure the entry is still there */
+ this->lock->read_lock(this->lock);
+ if (this->traps->find_first(this->traps, NULL,
+ (void**)&found) == SUCCESS)
{
- charon->ike_sa_manager->checkin_and_destroy(
- charon->ike_sa_manager, ike_sa);
+ found->ike_sa = ike_sa;
}
+ this->lock->unlock(this->lock);
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
- this->lock->unlock(this->lock);
+ else
+ {
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
+ }
+ peer->destroy(peer);
}
/**
@@ -316,7 +321,7 @@ static void complete(private_trap_manager_t *this, ike_sa_t *ike_sa,
enumerator = this->traps->create_enumerator(this->traps);
while (enumerator->enumerate(enumerator, &entry))
{
- if (entry->pending != ike_sa)
+ if (entry->ike_sa != ike_sa)
{
continue;
}
@@ -325,17 +330,15 @@ static void complete(private_trap_manager_t *this, ike_sa_t *ike_sa,
{
continue;
}
- entry->pending = NULL;
+ entry->ike_sa = NULL;
+ entry->pending = FALSE;
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
}
-/**
- * Implementation of listener_t.ike_state_change
- */
-static bool ike_state_change(trap_listener_t *listener, ike_sa_t *ike_sa,
- ike_sa_state_t state)
+METHOD(listener_t, ike_state_change, bool,
+ trap_listener_t *listener, ike_sa_t *ike_sa, ike_sa_state_t state)
{
switch (state)
{
@@ -347,11 +350,9 @@ static bool ike_state_change(trap_listener_t *listener, ike_sa_t *ike_sa,
}
}
-/**
- * Implementation of listener_t.child_state_change
- */
-static bool child_state_change(trap_listener_t *listener, ike_sa_t *ike_sa,
- child_sa_t *child_sa, child_sa_state_t state)
+METHOD(listener_t, child_state_change, bool,
+ trap_listener_t *listener, ike_sa_t *ike_sa, child_sa_t *child_sa,
+ child_sa_state_t state)
{
switch (state)
{
@@ -364,14 +365,24 @@ static bool child_state_change(trap_listener_t *listener, ike_sa_t *ike_sa,
}
}
-/**
- * Implementation of trap_manager_t.destroy.
- */
-static void destroy(private_trap_manager_t *this)
+METHOD(trap_manager_t, flush, void,
+ private_trap_manager_t *this)
+{
+ linked_list_t *traps;
+ /* since destroying the CHILD_SA results in events which require a read
+ * lock we cannot destroy the list while holding the write lock */
+ this->lock->write_lock(this->lock);
+ traps = this->traps;
+ this->traps = linked_list_create();
+ this->lock->unlock(this->lock);
+ traps->destroy_function(traps, (void*)destroy_entry);
+}
+
+METHOD(trap_manager_t, destroy, void,
+ private_trap_manager_t *this)
{
charon->bus->remove_listener(charon->bus, &this->listener.listener);
- this->traps->invoke_function(this->traps, (void*)destroy_entry);
- this->traps->destroy(this->traps);
+ this->traps->destroy_function(this->traps, (void*)destroy_entry);
this->lock->destroy(this->lock);
free(this);
}
@@ -379,24 +390,29 @@ static void destroy(private_trap_manager_t *this)
/**
* See header
*/
-trap_manager_t *trap_manager_create()
+trap_manager_t *trap_manager_create(void)
{
- private_trap_manager_t *this = malloc_thing(private_trap_manager_t);
-
- this->public.install = (u_int(*)(trap_manager_t*, peer_cfg_t *peer, child_cfg_t *child))install;
- this->public.uninstall = (bool(*)(trap_manager_t*, u_int32_t id))uninstall;
- this->public.create_enumerator = (enumerator_t*(*)(trap_manager_t*))create_enumerator;
- this->public.acquire = (void(*)(trap_manager_t*, u_int32_t reqid, traffic_selector_t *src, traffic_selector_t *dst))acquire;
- this->public.destroy = (void(*)(trap_manager_t*))destroy;
-
- this->traps = linked_list_create();
- this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
-
- /* register listener for IKE state changes */
- this->listener.traps = this;
- memset(&this->listener.listener, 0, sizeof(listener_t));
- this->listener.listener.ike_state_change = (void*)ike_state_change;
- this->listener.listener.child_state_change = (void*)child_state_change;
+ private_trap_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .install = _install,
+ .uninstall = _uninstall,
+ .create_enumerator = _create_enumerator,
+ .acquire = _acquire,
+ .flush = _flush,
+ .destroy = _destroy,
+ },
+ .listener = {
+ .traps = this,
+ .listener = {
+ .ike_state_change = _ike_state_change,
+ .child_state_change = _child_state_change,
+ },
+ },
+ .traps = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
charon->bus->add_listener(charon->bus, &this->listener.listener);
return &this->public;
diff --git a/src/libcharon/sa/trap_manager.h b/src/libcharon/sa/trap_manager.h
index 37b42e2b0..928b2a49f 100644
--- a/src/libcharon/sa/trap_manager.h
+++ b/src/libcharon/sa/trap_manager.h
@@ -68,6 +68,11 @@ struct trap_manager_t {
traffic_selector_t *src, traffic_selector_t *dst);
/**
+ * Clear any installed trap.
+ */
+ void (*flush)(trap_manager_t *this);
+
+ /**
* Destroy a trap_manager_t.
*/
void (*destroy)(trap_manager_t *this);
diff --git a/src/libfast/Makefile.am b/src/libfast/Makefile.am
index 5a1193658..35d102109 100644
--- a/src/libfast/Makefile.am
+++ b/src/libfast/Makefile.am
@@ -1,8 +1,8 @@
-lib_LTLIBRARIES = libfast.la
+ipseclib_LTLIBRARIES = libfast.la
libfast_la_SOURCES = context.h dispatcher.c request.h session.h \
controller.h dispatcher.h request.c session.c filter.h smtp.c smtp.h
libfast_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
- -lfcgi -lneo_cgi -lneo_cs -lneo_utl -lz $(PTHREADLIB)
+ -lfcgi $(clearsilver_LIBS) $(PTHREADLIB)
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I/usr/include/ClearSilver
AM_CFLAGS = -rdynamic
diff --git a/src/libfast/Makefile.in b/src/libfast/Makefile.in
index 47678029f..abb721758 100644
--- a/src/libfast/Makefile.in
+++ b/src/libfast/Makefile.in
@@ -72,12 +72,12 @@ am__nobase_list = $(am__nobase_strip_setup); \
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)$(libdir)"
-LTLIBRARIES = $(lib_LTLIBRARIES)
+am__installdirs = "$(DESTDIR)$(ipseclibdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libfast_la_DEPENDENCIES = \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
- $(am__DEPENDENCIES_1)
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
am_libfast_la_OBJECTS = dispatcher.lo request.lo session.lo smtp.lo
libfast_la_OBJECTS = $(am_libfast_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
@@ -189,6 +189,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -197,6 +200,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -213,11 +217,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -261,6 +267,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -271,12 +278,12 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-lib_LTLIBRARIES = libfast.la
+ipseclib_LTLIBRARIES = libfast.la
libfast_la_SOURCES = context.h dispatcher.c request.h session.h \
controller.h dispatcher.h request.c session.c filter.h smtp.c smtp.h
libfast_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
- -lfcgi -lneo_cgi -lneo_cs -lneo_utl -lz $(PTHREADLIB)
+ -lfcgi $(clearsilver_LIBS) $(PTHREADLIB)
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I/usr/include/ClearSilver
AM_CFLAGS = -rdynamic
@@ -314,39 +321,39 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(libdir)'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
}
-uninstall-libLTLIBRARIES:
+uninstall-ipseclibLTLIBRARIES:
@$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
done
-clean-libLTLIBRARIES:
- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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
libfast.la: $(libfast_la_OBJECTS) $(libfast_la_DEPENDENCIES)
- $(LINK) -rpath $(libdir) $(libfast_la_OBJECTS) $(libfast_la_LIBADD) $(LIBS)
+ $(LINK) -rpath $(ipseclibdir) $(libfast_la_OBJECTS) $(libfast_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -472,7 +479,7 @@ check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
- for dir in "$(DESTDIR)$(libdir)"; do \
+ for dir in "$(DESTDIR)$(ipseclibdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -502,7 +509,7 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
@@ -523,13 +530,13 @@ info: info-am
info-am:
-install-data-am:
+install-data-am: install-ipseclibLTLIBRARIES
install-dvi: install-dvi-am
install-dvi-am:
-install-exec-am: install-libLTLIBRARIES
+install-exec-am:
install-html: install-html-am
@@ -569,23 +576,23 @@ ps: ps-am
ps-am:
-uninstall-am: uninstall-libLTLIBRARIES
+uninstall-am: uninstall-ipseclibLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-libLTLIBRARIES clean-libtool ctags distclean \
+ clean-ipseclibLTLIBRARIES clean-libtool 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-libLTLIBRARIES install-man install-pdf install-pdf-am \
- install-ps install-ps-am install-strip installcheck \
- installcheck-am installdirs maintainer-clean \
+ install-ipseclibLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags uninstall uninstall-am uninstall-libLTLIBRARIES
+ tags uninstall uninstall-am uninstall-ipseclibLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/libfast/dispatcher.c b/src/libfast/dispatcher.c
index 7690230d3..e5fca7074 100644
--- a/src/libfast/dispatcher.c
+++ b/src/libfast/dispatcher.c
@@ -180,14 +180,12 @@ static session_entry_t *session_entry_create(private_dispatcher_t *this,
{
session_entry_t *entry;
- entry = malloc_thing(session_entry_t);
- entry->in_use = FALSE;
- entry->closed = FALSE;
- entry->cond = condvar_create(CONDVAR_TYPE_DEFAULT);
- entry->session = load_session(this);
- entry->used = time_monotonic(NULL);
- entry->host = strdup(host);
-
+ INIT(entry,
+ .cond = condvar_create(CONDVAR_TYPE_DEFAULT),
+ .session = load_session(this),
+ .host = strdup(host),
+ .used = time_monotonic(NULL),
+ );
return entry;
}
@@ -202,29 +200,28 @@ static void session_entry_destroy(session_entry_t *entry)
free(entry);
}
-/**
- * Implementation of dispatcher_t.add_controller.
- */
-static void add_controller(private_dispatcher_t *this,
- controller_constructor_t constructor, void *param)
+METHOD(dispatcher_t, add_controller, void,
+ private_dispatcher_t *this, controller_constructor_t constructor,
+ void *param)
{
- controller_entry_t *entry = malloc_thing(controller_entry_t);
+ controller_entry_t *entry;
- entry->constructor = constructor;
- entry->param = param;
+ INIT(entry,
+ .constructor = constructor,
+ .param = param,
+ );
this->controllers->insert_last(this->controllers, entry);
}
-/**
- * Implementation of dispatcher_t.add_filter.
- */
-static void add_filter(private_dispatcher_t *this,
- filter_constructor_t constructor, void *param)
+METHOD(dispatcher_t, add_filter, void,
+ private_dispatcher_t *this, filter_constructor_t constructor, void *param)
{
- filter_entry_t *entry = malloc_thing(filter_entry_t);
+ filter_entry_t *entry;
- entry->constructor = constructor;
- entry->param = param;
+ INIT(entry,
+ .constructor = constructor,
+ .param = param,
+ );
this->filters->insert_last(this->filters, entry);
}
@@ -349,10 +346,8 @@ static void dispatch(private_dispatcher_t *this)
}
}
-/**
- * Implementation of dispatcher_t.run.
- */
-static void run(private_dispatcher_t *this, int threads)
+METHOD(dispatcher_t, run, void,
+ private_dispatcher_t *this, int threads)
{
this->thread_count = threads;
this->threads = malloc(sizeof(thread_t*) * threads);
@@ -367,10 +362,8 @@ static void run(private_dispatcher_t *this, int threads)
}
}
-/**
- * Implementation of dispatcher_t.waitsignal.
- */
-static void waitsignal(private_dispatcher_t *this)
+METHOD(dispatcher_t, waitsignal, void,
+ private_dispatcher_t *this)
{
sigset_t set;
int sig;
@@ -383,10 +376,8 @@ static void waitsignal(private_dispatcher_t *this)
sigwait(&set, &sig);
}
-/**
- * Implementation of dispatcher_t.destroy
- */
-static void destroy(private_dispatcher_t *this)
+METHOD(dispatcher_t, destroy, void,
+ private_dispatcher_t *this)
{
char *sid;
session_entry_t *entry;
@@ -419,26 +410,27 @@ static void destroy(private_dispatcher_t *this)
dispatcher_t *dispatcher_create(char *socket, bool debug, int timeout,
context_constructor_t constructor, void *param)
{
- private_dispatcher_t *this = malloc_thing(private_dispatcher_t);
-
- this->public.add_controller = (void(*)(dispatcher_t*, controller_constructor_t, void*))add_controller;
- this->public.add_filter = (void(*)(dispatcher_t*,filter_constructor_t constructor, void *param))add_filter;
- this->public.run = (void(*)(dispatcher_t*, int threads))run;
- this->public.waitsignal = (void(*)(dispatcher_t*))waitsignal;
- this->public.destroy = (void(*)(dispatcher_t*))destroy;
-
- this->sessions = hashtable_create((void*)session_hash,
- (void*)session_equals, 4096);
- this->controllers = linked_list_create();
- this->filters = linked_list_create();
- this->context_constructor = constructor;
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
- this->param = param;
- this->fd = 0;
- this->timeout = timeout;
- this->last_cleanup = time_monotonic(NULL);
- this->debug = debug;
- this->threads = NULL;
+ private_dispatcher_t *this;
+
+ INIT(this,
+ .public = {
+ .add_controller = _add_controller,
+ .add_filter = _add_filter,
+ .run = _run,
+ .waitsignal = _waitsignal,
+ .destroy = _destroy,
+ },
+ .sessions = hashtable_create((void*)session_hash,
+ (void*)session_equals, 4096),
+ .controllers = linked_list_create(),
+ .filters = linked_list_create(),
+ .context_constructor = constructor,
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .param = param,
+ .timeout = timeout,
+ .last_cleanup = time_monotonic(NULL),
+ .debug = debug,
+ );
FCGX_Init();
diff --git a/src/libfast/request.c b/src/libfast/request.c
index a3db70e82..3acd831b2 100644
--- a/src/libfast/request.c
+++ b/src/libfast/request.c
@@ -160,86 +160,66 @@ static int iterenv_cb(void *null, int num, char **key, char **value)
return 0;
}
-/**
- * Implementation of request_t.get_cookie.
- */
-static char* get_cookie(private_request_t *this, char *name)
+METHOD(request_t, get_cookie, char*,
+ private_request_t *this, char *name)
{
return hdf_get_valuef(this->hdf, "Cookie.%s", name);
}
-/**
- * Implementation of request_t.get_path.
- */
-static char* get_path(private_request_t *this)
+METHOD(request_t, get_path, char*,
+ private_request_t *this)
{
char * path = FCGX_GetParam("PATH_INFO", this->req.envp);
return path ? path : "";
}
-/**
- * Implementation of request_t.get_host.
- */
-static char* get_host(private_request_t *this)
+METHOD(request_t, get_host, char*,
+ private_request_t *this)
{
char *addr = FCGX_GetParam("REMOTE_ADDR", this->req.envp);
return addr ? addr : "";
}
-/**
- * Implementation of request_t.get_user_agent.
- */
-static char* get_user_agent(private_request_t *this)
+METHOD(request_t, get_user_agent, char*,
+ private_request_t *this)
{
char *agent = FCGX_GetParam("HTTP_USER_AGENT", this->req.envp);
return agent ? agent : "";
}
-/**
- * Implementation of request_t.get_post_data.
- */
-static char* get_query_data(private_request_t *this, char *name)
+METHOD(request_t, get_query_data, char*,
+ private_request_t *this, char *name)
{
return hdf_get_valuef(this->hdf, "Query.%s", name);
}
-/**
- * Implementation of request_t.get_env_var.
- */
-static char* get_env_var(private_request_t *this, char *name)
+METHOD(request_t, get_env_var, char*,
+ private_request_t *this, char *name)
{
return FCGX_GetParam(name, this->req.envp);
}
-/**
- * Implementation of request_t.read_data.
- */
-static int read_data(private_request_t *this, char *buf, int len)
+METHOD(request_t, read_data, int,
+ private_request_t *this, char *buf, int len)
{
return FCGX_GetStr(buf, len, this->req.in);
}
-/**
- * Implementation of request_t.get_base.
- */
-static char* get_base(private_request_t *this)
+METHOD(request_t, get_base, char*,
+ private_request_t *this)
{
return FCGX_GetParam("SCRIPT_NAME", this->req.envp);
}
-/**
- * Implementation of request_t.add_cookie.
- */
-static void add_cookie(private_request_t *this, char *name, char *value)
+METHOD(request_t, add_cookie, void,
+ private_request_t *this, char *name, char *value)
{
thread_this->set(thread_this, this);
- cgi_cookie_set (this->cgi, name, value, get_base(this), NULL, NULL, 0, 0);
+ cgi_cookie_set(this->cgi, name, value, NULL, NULL, NULL, 0, 0);
}
-/**
- * Implementation of request_t.redirect.
- */
-static void redirect(private_request_t *this, char *fmt, ...)
+METHOD(request_t, redirect, void,
+ private_request_t *this, char *fmt, ...)
{
va_list args;
@@ -252,18 +232,14 @@ static void redirect(private_request_t *this, char *fmt, ...)
FCGX_FPrintF(this->req.out, "\n\n");
}
-/**
- * Implementation of request_t.get_referer.
- */
-static char* get_referer(private_request_t *this)
+METHOD(request_t, get_referer, char*,
+ private_request_t *this)
{
return FCGX_GetParam("HTTP_REFERER", this->req.envp);
}
-/**
- * Implementation of request_t.to_referer.
- */
-static void to_referer(private_request_t *this)
+METHOD(request_t, to_referer, void,
+ private_request_t *this)
{
char *referer;
@@ -279,36 +255,28 @@ static void to_referer(private_request_t *this)
}
}
-/**
- * Implementation of request_t.session_closed.
- */
-static bool session_closed(private_request_t *this)
+METHOD(request_t, session_closed, bool,
+ private_request_t *this)
{
return this->closed;
}
-/**
- * Implementation of request_t.close_session.
- */
-static void close_session(private_request_t *this)
+METHOD(request_t, close_session, void,
+ private_request_t *this)
{
this->closed = TRUE;
}
-/**
- * Implementation of request_t.serve.
- */
-static void serve(private_request_t *this, char *headers, chunk_t chunk)
+METHOD(request_t, serve, void,
+ private_request_t *this, char *headers, chunk_t chunk)
{
FCGX_FPrintF(this->req.out, "%s\n\n", headers);
FCGX_PutStr(chunk.ptr, chunk.len, this->req.out);
}
-/**
- * Implementation of request_t.render.
- */
-static void render(private_request_t *this, char *template)
+METHOD(request_t, render, void,
+ private_request_t *this, char *template)
{
NEOERR* err;
@@ -319,13 +287,10 @@ static void render(private_request_t *this, char *template)
cgi_neo_error(this->cgi, err);
nerr_log_error(err);
}
- return;
}
-/**
- * Implementation of request_t.streamf.
- */
-static int streamf(private_request_t *this, char *format, ...)
+METHOD(request_t, streamf, int,
+ private_request_t *this, char *format, ...)
{
va_list args;
int written;
@@ -341,18 +306,14 @@ static int streamf(private_request_t *this, char *format, ...)
return written;
}
-/**
- * Implementation of request_t.set.
- */
-static void set(private_request_t *this, char *key, char *value)
+METHOD(request_t, set, void,
+ private_request_t *this, char *key, char *value)
{
hdf_set_value(this->hdf, key, value);
}
-/**
- * Implementation of request_t.setf.
- */
-static void setf(private_request_t *this, char *format, ...)
+METHOD(request_t, setf, void,
+ private_request_t *this, char *format, ...)
{
va_list args;
@@ -361,19 +322,15 @@ static void setf(private_request_t *this, char *format, ...)
va_end(args);
}
-/**
- * Implementation of request_t.get_ref.
- */
-static request_t* get_ref(private_request_t *this)
+METHOD(request_t, get_ref, request_t*,
+ private_request_t *this)
{
ref_get(&this->ref);
return &this->public;
}
-/**
- * Implementation of request_t.destroy
- */
-static void destroy(private_request_t *this)
+METHOD(request_t, destroy, void,
+ private_request_t *this)
{
if (ref_put(&this->ref))
{
@@ -401,9 +358,36 @@ static void init(void)
request_t *request_create(int fd, bool debug)
{
NEOERR* err;
- private_request_t *this = malloc_thing(private_request_t);
+ private_request_t *this;
bool failed = FALSE;
+ INIT(this,
+ .public = {
+ .get_path = _get_path,
+ .get_base = _get_base,
+ .get_host = _get_host,
+ .get_user_agent = _get_user_agent,
+ .add_cookie = _add_cookie,
+ .get_cookie = _get_cookie,
+ .get_query_data = _get_query_data,
+ .get_env_var = _get_env_var,
+ .read_data = _read_data,
+ .session_closed = _session_closed,
+ .close_session = _close_session,
+ .redirect = _redirect,
+ .get_referer = _get_referer,
+ .to_referer = _to_referer,
+ .render = _render,
+ .streamf = _streamf,
+ .serve = _serve,
+ .set = _set,
+ .setf = _setf,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .ref = 1,
+ );
+
thread_cleanup_push(free, this);
if (FCGX_InitRequest(&this->req, fd, 0) != 0 ||
FCGX_Accept_r(&this->req) != 0)
@@ -416,34 +400,9 @@ request_t *request_create(int fd, bool debug)
return NULL;
}
- this->public.get_path = (char*(*)(request_t*))get_path;
- this->public.get_base = (char*(*)(request_t*))get_base;
- this->public.get_host = (char*(*)(request_t*))get_host;
- this->public.get_user_agent = (char*(*)(request_t*))get_user_agent;
- this->public.add_cookie = (void(*)(request_t*, char *name, char *value))add_cookie;
- this->public.get_cookie = (char*(*)(request_t*,char*))get_cookie;
- this->public.get_query_data = (char*(*)(request_t*, char *name))get_query_data;
- this->public.get_env_var = (char*(*)(request_t*, char *name))get_env_var;
- this->public.read_data = (int(*)(request_t*, char*, int))read_data;
- this->public.session_closed = (bool(*)(request_t*))session_closed;
- this->public.close_session = (void(*)(request_t*))close_session;
- this->public.redirect = (void(*)(request_t*, char *fmt,...))redirect;
- this->public.get_referer = (char*(*)(request_t*))get_referer;
- this->public.to_referer = (void(*)(request_t*))to_referer;
- this->public.render = (void(*)(request_t*,char*))render;
- this->public.streamf = (int(*)(request_t*, char *format, ...))streamf;
- this->public.serve = (void(*)(request_t*,char*,chunk_t))serve;
- this->public.set = (void(*)(request_t*, char *, char*))set;
- this->public.setf = (void(*)(request_t*, char *format, ...))setf;
- this->public.get_ref = (request_t*(*)(request_t*))get_ref;
- this->public.destroy = (void(*)(request_t*))destroy;
-
pthread_once(&once, init);
thread_this->set(thread_this, this);
- this->ref = 1;
- this->closed = FALSE;
- this->req_env_len = 0;
while (this->req.envp[this->req_env_len] != NULL)
{
this->req_env_len++;
diff --git a/src/libfast/session.c b/src/libfast/session.c
index 7c4548ee5..1d9ed0107 100644
--- a/src/libfast/session.c
+++ b/src/libfast/session.c
@@ -63,18 +63,14 @@ struct private_session_t {
context_t *context;
};
-/**
- * Implementation of session_t.add_controller.
- */
-static void add_controller(private_session_t *this, controller_t *controller)
+METHOD(session_t, add_controller, void,
+ private_session_t *this, controller_t *controller)
{
this->controllers->insert_last(this->controllers, controller);
}
-/**
- * Implementation of session_t.add_filter.
- */
-static void add_filter(private_session_t *this, filter_t *filter)
+METHOD(session_t, add_filter, void,
+ private_session_t *this, filter_t *filter)
{
this->filters->insert_last(this->filters, filter);
}
@@ -120,10 +116,8 @@ static bool run_filter(private_session_t *this, request_t *request, char *p0,
return TRUE;
}
-/**
- * Implementation of session_t.process.
- */
-static void process(private_session_t *this, request_t *request)
+METHOD(session_t, process, void,
+ private_session_t *this, request_t *request)
{
char *pos, *start, *param[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
enumerator_t *enumerator;
@@ -184,18 +178,14 @@ static void process(private_session_t *this, request_t *request)
}
}
-/**
- * Implementation of session_t.get_sid.
- */
-static char* get_sid(private_session_t *this)
+METHOD(session_t, get_sid, char*,
+ private_session_t *this)
{
return this->sid;
}
-/**
- * Implementation of session_t.destroy
- */
-static void destroy(private_session_t *this)
+METHOD(session_t, destroy, void,
+ private_session_t *this)
{
this->controllers->destroy_offset(this->controllers, offsetof(controller_t, destroy));
this->filters->destroy_offset(this->filters, offsetof(filter_t, destroy));
@@ -208,19 +198,21 @@ static void destroy(private_session_t *this)
*/
session_t *session_create(context_t *context)
{
- private_session_t *this = malloc_thing(private_session_t);
-
- this->public.add_controller = (void(*)(session_t*, controller_t*))add_controller;
- this->public.add_filter = (void(*)(session_t*, filter_t*))add_filter;
- this->public.process = (void(*)(session_t*,request_t*))process;
- this->public.get_sid = (char*(*)(session_t*))get_sid;
- this->public.destroy = (void(*)(session_t*))destroy;
-
+ private_session_t *this;
+
+ INIT(this,
+ .public = {
+ .add_controller = _add_controller,
+ .add_filter = _add_filter,
+ .process = _process,
+ .get_sid = _get_sid,
+ .destroy = _destroy,
+ },
+ .controllers = linked_list_create(),
+ .filters = linked_list_create(),
+ .context = context,
+ );
create_sid(this);
- this->cookie_sent = FALSE;
- this->controllers = linked_list_create();
- this->filters = linked_list_create();
- this->context = context;
return &this->public;
}
diff --git a/src/libfast/session.h b/src/libfast/session.h
index c6633f9ae..f60fa9ef2 100644
--- a/src/libfast/session.h
+++ b/src/libfast/session.h
@@ -62,8 +62,6 @@ struct session_t {
/**
* Destroy the session_t.
- *
- * @param this calling object
*/
void (*destroy) (session_t *this);
};
diff --git a/src/libfast/smtp.h b/src/libfast/smtp.h
index 910f18127..9589ea2a6 100644
--- a/src/libfast/smtp.h
+++ b/src/libfast/smtp.h
@@ -34,7 +34,7 @@ struct smtp_t {
* Send an e-mail message.
*
* @param from sender address
- * @param to receipient address
+ * @param to recipient address
* @param subject mail subject
* @param fmt mail body format string
* @param ... arguments for body format string
diff --git a/src/libfreeswan/Android.mk b/src/libfreeswan/Android.mk
new file mode 100644
index 000000000..a834d4846
--- /dev/null
+++ b/src/libfreeswan/Android.mk
@@ -0,0 +1,38 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# copy-n-paste from Makefile.am
+LOCAL_SRC_FILES := \
+addrtoa.c addrtot.c addrtypeof.c anyaddr.c atoaddr.c atoasr.c \
+atosubnet.c atoul.c copyright.c datatot.c freeswan.h \
+goodmask.c initaddr.c initsaid.c initsubnet.c internal.h ipsec_param.h \
+pfkey_v2_build.c pfkey_v2_debug.c \
+pfkey_v2_ext_bits.c pfkey_v2_parse.c portof.c rangetoa.c \
+pfkey.h pfkeyv2.h rangetosubnet.c sameaddr.c \
+satot.c subnetof.c subnettoa.c subnettot.c \
+subnettypeof.c ttoaddr.c ttodata.c ttoprotoport.c ttosa.c ttosubnet.c ttoul.c \
+ultoa.c ultot.c
+
+# build libfreeswan ------------------------------------------------------------
+
+LOCAL_C_INCLUDES += \
+ $(libvstr_PATH) \
+ $(strongswan_PATH)/src/include \
+ $(strongswan_PATH)/src/libstrongswan \
+ $(strongswan_PATH)/src/libhydra \
+ $(strongswan_PATH)/src/pluto
+
+LOCAL_CFLAGS := $(strongswan_CFLAGS)
+
+LOCAL_MODULE := libfreeswan
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_SHARED_LIBRARIES += libstrongswan
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/src/libfreeswan/Makefile.am b/src/libfreeswan/Makefile.am
index 09f5fe2cd..b38343d34 100644
--- a/src/libfreeswan/Makefile.am
+++ b/src/libfreeswan/Makefile.am
@@ -1,13 +1,14 @@
noinst_LIBRARIES = libfreeswan.a
-libfreeswan_a_SOURCES = addrtoa.c addrtot.c addrtypeof.c anyaddr.c atoaddr.c atoasr.c \
- atosubnet.c atoul.c copyright.c datatot.c freeswan.h \
- goodmask.c initaddr.c initsaid.c initsubnet.c internal.h ipsec_param.h \
- pfkey_v2_build.c pfkey_v2_debug.c \
- pfkey_v2_ext_bits.c pfkey_v2_parse.c portof.c rangetoa.c \
- pfkey.h pfkeyv2.h rangetosubnet.c sameaddr.c \
- satot.c subnetof.c subnettoa.c subnettot.c \
- subnettypeof.c ttoaddr.c ttodata.c ttoprotoport.c ttosa.c ttosubnet.c ttoul.c \
- ultoa.c ultot.c
+libfreeswan_a_SOURCES = \
+addrtoa.c addrtot.c addrtypeof.c anyaddr.c atoaddr.c atoasr.c \
+atosubnet.c atoul.c copyright.c datatot.c freeswan.h \
+goodmask.c initaddr.c initsaid.c initsubnet.c internal.h ipsec_param.h \
+pfkey_v2_build.c pfkey_v2_debug.c \
+pfkey_v2_ext_bits.c pfkey_v2_parse.c portof.c rangetoa.c \
+pfkey.h pfkeyv2.h rangetosubnet.c sameaddr.c \
+satot.c subnetof.c subnettoa.c subnettot.c \
+subnettypeof.c ttoaddr.c ttodata.c ttoprotoport.c ttosa.c ttosubnet.c ttoul.c \
+ultoa.c ultot.c
INCLUDES = \
-I$(top_srcdir)/src/libstrongswan \
@@ -18,3 +19,4 @@ dist_man3_MANS = anyaddr.3 atoaddr.3 atoasr.3 atoul.3 goodmask.3 initaddr.3 init
portof.3 rangetosubnet.3 sameaddr.3 subnetof.3 \
ttoaddr.3 ttodata.3 ttosa.3 ttoul.3
+EXTRA_DIST = Android.mk
diff --git a/src/libfreeswan/Makefile.in b/src/libfreeswan/Makefile.in
index d00ae91e0..b6ee06630 100644
--- a/src/libfreeswan/Makefile.in
+++ b/src/libfreeswan/Makefile.in
@@ -204,6 +204,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -212,6 +215,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -228,11 +232,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -276,6 +282,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -287,15 +294,16 @@ urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
noinst_LIBRARIES = libfreeswan.a
-libfreeswan_a_SOURCES = addrtoa.c addrtot.c addrtypeof.c anyaddr.c atoaddr.c atoasr.c \
- atosubnet.c atoul.c copyright.c datatot.c freeswan.h \
- goodmask.c initaddr.c initsaid.c initsubnet.c internal.h ipsec_param.h \
- pfkey_v2_build.c pfkey_v2_debug.c \
- pfkey_v2_ext_bits.c pfkey_v2_parse.c portof.c rangetoa.c \
- pfkey.h pfkeyv2.h rangetosubnet.c sameaddr.c \
- satot.c subnetof.c subnettoa.c subnettot.c \
- subnettypeof.c ttoaddr.c ttodata.c ttoprotoport.c ttosa.c ttosubnet.c ttoul.c \
- ultoa.c ultot.c
+libfreeswan_a_SOURCES = \
+addrtoa.c addrtot.c addrtypeof.c anyaddr.c atoaddr.c atoasr.c \
+atosubnet.c atoul.c copyright.c datatot.c freeswan.h \
+goodmask.c initaddr.c initsaid.c initsubnet.c internal.h ipsec_param.h \
+pfkey_v2_build.c pfkey_v2_debug.c \
+pfkey_v2_ext_bits.c pfkey_v2_parse.c portof.c rangetoa.c \
+pfkey.h pfkeyv2.h rangetosubnet.c sameaddr.c \
+satot.c subnetof.c subnettoa.c subnettot.c \
+subnettypeof.c ttoaddr.c ttodata.c ttoprotoport.c ttosa.c ttosubnet.c ttoul.c \
+ultoa.c ultot.c
INCLUDES = \
-I$(top_srcdir)/src/libstrongswan \
@@ -306,6 +314,7 @@ dist_man3_MANS = anyaddr.3 atoaddr.3 atoasr.3 atoul.3 goodmask.3 initaddr.3 init
portof.3 rangetosubnet.3 sameaddr.3 subnetof.3 \
ttoaddr.3 ttodata.3 ttosa.3 ttoul.3
+EXTRA_DIST = Android.mk
all: all-am
.SUFFIXES:
diff --git a/src/libfreeswan/datatot.c b/src/libfreeswan/datatot.c
index 3e2aed76d..e3b9d6417 100644
--- a/src/libfreeswan/datatot.c
+++ b/src/libfreeswan/datatot.c
@@ -58,7 +58,6 @@ size_t dstlen;
prefix = "0x";
break;
case ':':
- format = 'x';
breakevery = 2;
breakchar = ':';
/* FALLTHROUGH */
diff --git a/src/libfreeswan/pfkey_v2_parse.c b/src/libfreeswan/pfkey_v2_parse.c
index a143003b3..8fec9d119 100644
--- a/src/libfreeswan/pfkey_v2_parse.c
+++ b/src/libfreeswan/pfkey_v2_parse.c
@@ -40,11 +40,11 @@ char pfkey_v2_parse_c_version[] = "";
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-struct satype_tbl {
+static struct {
uint8_t proto;
uint8_t satype;
char* name;
-} static satype_tbl[] = {
+} satype_tbl[] = {
{ SA_ESP, SADB_SATYPE_ESP, "ESP" },
{ SA_AH, SADB_SATYPE_AH, "AH" },
{ SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
diff --git a/src/libhydra/Android.mk b/src/libhydra/Android.mk
index 2418e76ad..075f8dbcb 100644
--- a/src/libhydra/Android.mk
+++ b/src/libhydra/Android.mk
@@ -10,7 +10,7 @@ attributes/attribute_manager.c attributes/attribute_manager.h \
attributes/mem_pool.c attributes/mem_pool.h \
kernel/kernel_interface.c kernel/kernel_interface.h \
kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
-kernel/kernel_net.h \
+kernel/kernel_net.c kernel/kernel_net.h \
kernel/kernel_listener.h
# adding the plugin source files
@@ -32,6 +32,8 @@ LOCAL_CFLAGS := $(strongswan_CFLAGS)
LOCAL_MODULE := libhydra
+LOCAL_MODULE_TAGS := optional
+
LOCAL_ARM_MODE := arm
LOCAL_PRELINK_MODULE := false
diff --git a/src/libhydra/Makefile.am b/src/libhydra/Makefile.am
index d0698d0f5..1c7b3ba43 100644
--- a/src/libhydra/Makefile.am
+++ b/src/libhydra/Makefile.am
@@ -1,4 +1,4 @@
-lib_LTLIBRARIES = libhydra.la
+ipseclib_LTLIBRARIES = libhydra.la
libhydra_la_SOURCES = \
hydra.c hydra.h \
@@ -8,7 +8,7 @@ attributes/attribute_manager.c attributes/attribute_manager.h \
attributes/mem_pool.c attributes/mem_pool.h \
kernel/kernel_interface.c kernel/kernel_interface.h \
kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
-kernel/kernel_net.h \
+kernel/kernel_net.c kernel/kernel_net.h \
kernel/kernel_listener.h
libhydra_la_LIBADD =
diff --git a/src/libhydra/Makefile.in b/src/libhydra/Makefile.in
index 08c73b5e3..f452719dd 100644
--- a/src/libhydra/Makefile.in
+++ b/src/libhydra/Makefile.in
@@ -86,13 +86,13 @@ am__nobase_list = $(am__nobase_strip_setup); \
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)$(libdir)"
-LTLIBRARIES = $(lib_LTLIBRARIES)
+am__installdirs = "$(DESTDIR)$(ipseclibdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
libhydra_la_DEPENDENCIES = $(am__append_2) $(am__append_4) \
$(am__append_6) $(am__append_8) $(am__append_10) \
$(am__append_12) $(am__append_14)
am_libhydra_la_OBJECTS = hydra.lo attributes.lo attribute_manager.lo \
- mem_pool.lo kernel_interface.lo kernel_ipsec.lo
+ mem_pool.lo kernel_interface.lo kernel_ipsec.lo kernel_net.lo
libhydra_la_OBJECTS = $(am_libhydra_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -243,6 +243,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -251,6 +254,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -267,11 +271,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -315,6 +321,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -325,7 +332,7 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-lib_LTLIBRARIES = libhydra.la
+ipseclib_LTLIBRARIES = libhydra.la
libhydra_la_SOURCES = \
hydra.c hydra.h \
attributes/attributes.c attributes/attributes.h \
@@ -334,7 +341,7 @@ attributes/attribute_manager.c attributes/attribute_manager.h \
attributes/mem_pool.c attributes/mem_pool.h \
kernel/kernel_interface.c kernel/kernel_interface.h \
kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
-kernel/kernel_net.h \
+kernel/kernel_net.c kernel/kernel_net.h \
kernel/kernel_listener.h
libhydra_la_LIBADD = $(am__append_2) $(am__append_4) $(am__append_6) \
@@ -392,39 +399,39 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(libdir)'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
}
-uninstall-libLTLIBRARIES:
+uninstall-ipseclibLTLIBRARIES:
@$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
done
-clean-libLTLIBRARIES:
- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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
libhydra.la: $(libhydra_la_OBJECTS) $(libhydra_la_DEPENDENCIES)
- $(LINK) -rpath $(libdir) $(libhydra_la_OBJECTS) $(libhydra_la_LIBADD) $(LIBS)
+ $(LINK) -rpath $(ipseclibdir) $(libhydra_la_OBJECTS) $(libhydra_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -437,6 +444,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hydra.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_net.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem_pool.Plo@am__quote@
.c.o:
@@ -495,6 +503,13 @@ kernel_ipsec.lo: kernel/kernel_ipsec.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 kernel_ipsec.lo `test -f 'kernel/kernel_ipsec.c' || echo '$(srcdir)/'`kernel/kernel_ipsec.c
+kernel_net.lo: kernel/kernel_net.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_net.lo -MD -MP -MF $(DEPDIR)/kernel_net.Tpo -c -o kernel_net.lo `test -f 'kernel/kernel_net.c' || echo '$(srcdir)/'`kernel/kernel_net.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/kernel_net.Tpo $(DEPDIR)/kernel_net.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='kernel/kernel_net.c' object='kernel_net.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_net.lo `test -f 'kernel/kernel_net.c' || echo '$(srcdir)/'`kernel/kernel_net.c
+
mostlyclean-libtool:
-rm -f *.lo
@@ -699,7 +714,7 @@ check: check-recursive
all-am: Makefile $(LTLIBRARIES)
installdirs: installdirs-recursive
installdirs-am:
- for dir in "$(DESTDIR)$(libdir)"; do \
+ for dir in "$(DESTDIR)$(ipseclibdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
@@ -729,7 +744,7 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-recursive
@@ -750,13 +765,13 @@ info: info-recursive
info-am:
-install-data-am:
+install-data-am: install-ipseclibLTLIBRARIES
install-dvi: install-dvi-recursive
install-dvi-am:
-install-exec-am: install-libLTLIBRARIES
+install-exec-am:
install-html: install-html-recursive
@@ -796,26 +811,26 @@ ps: ps-recursive
ps-am:
-uninstall-am: uninstall-libLTLIBRARIES
+uninstall-am: uninstall-ipseclibLTLIBRARIES
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
install-am install-strip tags-recursive
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am check check-am clean clean-generic \
- clean-libLTLIBRARIES clean-libtool ctags ctags-recursive \
+ clean-ipseclibLTLIBRARIES clean-libtool ctags ctags-recursive \
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-libLTLIBRARIES install-man install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs installdirs-am \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
- uninstall-libLTLIBRARIES
+ install-info-am install-ipseclibLTLIBRARIES install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-ipseclibLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/libhydra/attributes/attribute_manager.c b/src/libhydra/attributes/attribute_manager.c
index 0d4cbda82..95520531e 100644
--- a/src/libhydra/attributes/attribute_manager.c
+++ b/src/libhydra/attributes/attribute_manager.c
@@ -59,12 +59,9 @@ typedef struct {
host_t *vip;
} enum_data_t;
-/**
- * Implementation of attribute_manager_t.acquire_address.
- */
-static host_t* acquire_address(private_attribute_manager_t *this,
- char *pool, identification_t *id,
- host_t *requested)
+METHOD(attribute_manager_t, acquire_address, host_t*,
+ private_attribute_manager_t *this, char *pool, identification_t *id,
+ host_t *requested)
{
enumerator_t *enumerator;
attribute_provider_t *current;
@@ -90,11 +87,9 @@ static host_t* acquire_address(private_attribute_manager_t *this,
return host;
}
-/**
- * Implementation of attribute_manager_t.release_address.
- */
-static void release_address(private_attribute_manager_t *this,
- char *pool, host_t *address, identification_t *id)
+METHOD(attribute_manager_t, release_address, void,
+ private_attribute_manager_t *this, char *pool, host_t *address,
+ identification_t *id)
{
enumerator_t *enumerator;
attribute_provider_t *current;
@@ -129,12 +124,9 @@ static enumerator_t *responder_enum_create(attribute_provider_t *provider,
data->id, data->vip);
}
-/**
- * Implementation of attribute_manager_t.create_responder_enumerator
- */
-static enumerator_t* create_responder_enumerator(
- private_attribute_manager_t *this, char *pool,
- identification_t *id, host_t *vip)
+METHOD(attribute_manager_t, create_responder_enumerator, enumerator_t*,
+ private_attribute_manager_t *this, char *pool, identification_t *id,
+ host_t *vip)
{
enum_data_t *data = malloc_thing(enum_data_t);
@@ -149,34 +141,26 @@ static enumerator_t* create_responder_enumerator(
(void*)this->lock->unlock, this->lock);
}
-/**
- * Implementation of attribute_manager_t.add_provider.
- */
-static void add_provider(private_attribute_manager_t *this,
- attribute_provider_t *provider)
+METHOD(attribute_manager_t, add_provider, void,
+ private_attribute_manager_t *this, attribute_provider_t *provider)
{
this->lock->write_lock(this->lock);
this->providers->insert_last(this->providers, provider);
this->lock->unlock(this->lock);
}
-/**
- * Implementation of attribute_manager_t.remove_provider.
- */
-static void remove_provider(private_attribute_manager_t *this,
- attribute_provider_t *provider)
+METHOD(attribute_manager_t, remove_provider, void,
+ private_attribute_manager_t *this, attribute_provider_t *provider)
{
this->lock->write_lock(this->lock);
this->providers->remove(this->providers, provider, NULL);
this->lock->unlock(this->lock);
}
-/**
- * Implementation of attribute_manager_t.handle
- */
-static attribute_handler_t* handle(private_attribute_manager_t *this,
- identification_t *server, attribute_handler_t *handler,
- configuration_attribute_type_t type, chunk_t data)
+METHOD(attribute_manager_t, handle, attribute_handler_t*,
+ private_attribute_manager_t *this, identification_t *server,
+ attribute_handler_t *handler, configuration_attribute_type_t type,
+ chunk_t data)
{
enumerator_t *enumerator;
attribute_handler_t *current, *handled = NULL;
@@ -217,13 +201,9 @@ static attribute_handler_t* handle(private_attribute_manager_t *this,
return handled;
}
-/**
- * Implementation of attribute_manager_t.release
- */
-static void release(private_attribute_manager_t *this,
- attribute_handler_t *handler,
- identification_t *server,
- configuration_attribute_type_t type, chunk_t data)
+METHOD(attribute_manager_t, release, void,
+ private_attribute_manager_t *this, attribute_handler_t *handler,
+ identification_t *server, configuration_attribute_type_t type, chunk_t data)
{
enumerator_t *enumerator;
attribute_handler_t *current;
@@ -297,11 +277,8 @@ static void initiator_destroy(initiator_enumerator_t *this)
free(this);
}
-/**
- * Implementation of attribute_manager_t.create_initiator_enumerator
- */
-static enumerator_t* create_initiator_enumerator(
- private_attribute_manager_t *this, identification_t *id, host_t *vip)
+METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*,
+ private_attribute_manager_t *this, identification_t *id, host_t *vip)
{
initiator_enumerator_t *enumerator = malloc_thing(initiator_enumerator_t);
@@ -318,32 +295,24 @@ static enumerator_t* create_initiator_enumerator(
return &enumerator->public;
}
-/**
- * Implementation of attribute_manager_t.add_handler
- */
-static void add_handler(private_attribute_manager_t *this,
- attribute_handler_t *handler)
+METHOD(attribute_manager_t, add_handler, void,
+ private_attribute_manager_t *this, attribute_handler_t *handler)
{
this->lock->write_lock(this->lock);
this->handlers->insert_last(this->handlers, handler);
this->lock->unlock(this->lock);
}
-/**
- * Implementation of attribute_manager_t.remove_handler
- */
-static void remove_handler(private_attribute_manager_t *this,
- attribute_handler_t *handler)
+METHOD(attribute_manager_t, remove_handler, void,
+ private_attribute_manager_t *this, attribute_handler_t *handler)
{
this->lock->write_lock(this->lock);
this->handlers->remove(this->handlers, handler, NULL);
this->lock->unlock(this->lock);
}
-/**
- * Implementation of attribute_manager_t.destroy
- */
-static void destroy(private_attribute_manager_t *this)
+METHOD(attribute_manager_t, destroy, void,
+ private_attribute_manager_t *this)
{
this->providers->destroy(this->providers);
this->handlers->destroy(this->handlers);
@@ -356,23 +325,26 @@ static void destroy(private_attribute_manager_t *this)
*/
attribute_manager_t *attribute_manager_create()
{
- private_attribute_manager_t *this = malloc_thing(private_attribute_manager_t);
-
- this->public.acquire_address = (host_t*(*)(attribute_manager_t*, char*, identification_t*,host_t*))acquire_address;
- this->public.release_address = (void(*)(attribute_manager_t*, char *, host_t*, identification_t*))release_address;
- this->public.create_responder_enumerator = (enumerator_t*(*)(attribute_manager_t*, char *name, identification_t*, host_t*))create_responder_enumerator;
- this->public.add_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))add_provider;
- this->public.remove_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))remove_provider;
- this->public.handle = (attribute_handler_t*(*)(attribute_manager_t*,identification_t*, attribute_handler_t*, configuration_attribute_type_t, chunk_t))handle;
- this->public.release = (void(*)(attribute_manager_t*, attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))release;
- this->public.create_initiator_enumerator = (enumerator_t*(*)(attribute_manager_t*, identification_t*, host_t*))create_initiator_enumerator;
- this->public.add_handler = (void(*)(attribute_manager_t*, attribute_handler_t*))add_handler;
- this->public.remove_handler = (void(*)(attribute_manager_t*, attribute_handler_t*))remove_handler;
- this->public.destroy = (void(*)(attribute_manager_t*))destroy;
-
- this->providers = linked_list_create();
- this->handlers = linked_list_create();
- this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
+ private_attribute_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .acquire_address = _acquire_address,
+ .release_address = _release_address,
+ .create_responder_enumerator = _create_responder_enumerator,
+ .add_provider = _add_provider,
+ .remove_provider = _remove_provider,
+ .handle = _handle,
+ .release = _release,
+ .create_initiator_enumerator = _create_initiator_enumerator,
+ .add_handler = _add_handler,
+ .remove_handler = _remove_handler,
+ .destroy = _destroy,
+ },
+ .providers = linked_list_create(),
+ .handlers = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
return &this->public;
}
diff --git a/src/libhydra/attributes/attributes.c b/src/libhydra/attributes/attributes.c
index ea87109e2..d8490b7f5 100644
--- a/src/libhydra/attributes/attributes.c
+++ b/src/libhydra/attributes/attributes.c
@@ -17,7 +17,7 @@
#include "attributes.h"
-ENUM_BEGIN(configuration_attribute_type_names, INTERNAL_IP4_ADDRESS, INTERNAL_IP6_PREFIX,
+ENUM_BEGIN(configuration_attribute_type_names, INTERNAL_IP4_ADDRESS, HOME_AGENT_ADDRESS,
"INTERNAL_IP4_ADDRESS",
"INTERNAL_IP4_NETMASK",
"INTERNAL_IP4_DNS",
@@ -35,8 +35,9 @@ ENUM_BEGIN(configuration_attribute_type_names, INTERNAL_IP4_ADDRESS, INTERNAL_IP
"INTERNAL_IP6_SUBNET",
"MIP6_HOME_PREFIX",
"INTERNAL_IP6_LINK",
- "INTERNAL_IP6_PREFIX");
-ENUM_NEXT(configuration_attribute_type_names, XAUTH_TYPE, XAUTH_ANSWER, INTERNAL_IP6_PREFIX,
+ "INTERNAL_IP6_PREFIX",
+ "HOME_AGENT_ADDRESS");
+ENUM_NEXT(configuration_attribute_type_names, XAUTH_TYPE, XAUTH_ANSWER, HOME_AGENT_ADDRESS,
"XAUTH_TYPE",
"XAUTH_USER_NAME",
"XAUTH_USER_PASSWORD",
@@ -64,7 +65,7 @@ ENUM_NEXT(configuration_attribute_type_names, UNITY_BANNER, UNITY_DDNS_HOSTNAME,
"UNITY_DDNS_HOSTNAME");
ENUM_END(configuration_attribute_type_names, UNITY_DDNS_HOSTNAME);
-ENUM_BEGIN(configuration_attribute_type_short_names, INTERNAL_IP4_ADDRESS, INTERNAL_IP6_PREFIX,
+ENUM_BEGIN(configuration_attribute_type_short_names, INTERNAL_IP4_ADDRESS, HOME_AGENT_ADDRESS,
"ADDR",
"MASK",
"DNS",
@@ -78,35 +79,36 @@ ENUM_BEGIN(configuration_attribute_type_short_names, INTERNAL_IP4_ADDRESS, INTER
"NBNS6",
"DHCP6",
"SUBNET",
- "SUPPORTED",
+ "SUP",
"SUBNET6",
"MIP6HPFX",
"LINK6",
- "PFX6");
-ENUM_NEXT(configuration_attribute_type_short_names, XAUTH_TYPE, XAUTH_ANSWER, INTERNAL_IP6_PREFIX,
- "XAUTH_TYPE",
- "XAUTH_USER_NAME",
- "XAUTH_USER_PASSWORD",
- "XAUTH_PASSCODE",
- "XAUTH_MESSAGE",
- "XAUTH_CHALLENGE",
- "XAUTH_DOMAIN",
- "XAUTH_STATUS",
- "XAUTH_NEXT_PIN",
- "XAUTH_ANSWER");
+ "PFX6",
+ "HOA");
+ENUM_NEXT(configuration_attribute_type_short_names, XAUTH_TYPE, XAUTH_ANSWER, HOME_AGENT_ADDRESS,
+ "X_TYPE",
+ "X_USER_NAME",
+ "X_USER_PASSWORD",
+ "X_PASSCODE",
+ "X_MESSAGE",
+ "X_CHALLENGE",
+ "X_DOMAIN",
+ "X_STATUS",
+ "X_NEXT_PIN",
+ "X_ANSWER");
ENUM_NEXT(configuration_attribute_type_short_names, INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, XAUTH_ANSWER,
"SRV",
"SRV6");
ENUM_NEXT(configuration_attribute_type_short_names, UNITY_BANNER, UNITY_DDNS_HOSTNAME, INTERNAL_IP6_SERVER,
- "UNITY_BANNER",
- "UNITY_SAVE_PASSWD",
- "UNITY_DEF_DOMAIN",
- "UNITY_SPLITDNS_NAME",
- "UNITY_SPLIT_INCLUDE",
- "UNITY_NATT_PORT",
- "UNITY_LOCAL_LAN",
- "UNITY_PFS",
- "UNITY_FW_TYPE",
- "UNITY_BACKUP_SERVERS",
- "UNITY_DDNS_HOSTNAME");
+ "U_BANNER",
+ "U_SAVE_PASSWD",
+ "U_DEF_DOMAIN",
+ "U_SPLITDNS_NAME",
+ "U_SPLIT_INCLUDE",
+ "U_NATT_PORT",
+ "U_LOCAL_LAN",
+ "U_PFS",
+ "U_FW_TYPE",
+ "U_BACKUP_SERVERS",
+ "U_DDNS_HOSTNAME");
ENUM_END(configuration_attribute_type_short_names, UNITY_DDNS_HOSTNAME);
diff --git a/src/libhydra/attributes/attributes.h b/src/libhydra/attributes/attributes.h
index 3a40ba367..8ff774b64 100644
--- a/src/libhydra/attributes/attributes.h
+++ b/src/libhydra/attributes/attributes.h
@@ -48,6 +48,7 @@ enum configuration_attribute_type_t {
MIP6_HOME_PREFIX = 16,
INTERNAL_IP6_LINK = 17,
INTERNAL_IP6_PREFIX = 18,
+ HOME_AGENT_ADDRESS = 19,
/* XAUTH attributes */
XAUTH_TYPE = 16520,
XAUTH_USER_NAME = 16521,
diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c
index 4b5b41f2b..573557506 100644
--- a/src/libhydra/kernel/kernel_interface.c
+++ b/src/libhydra/kernel/kernel_interface.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2010 Tobias Brunner
+ * Copyright (C) 2008-2011 Tobias Brunner
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
@@ -34,6 +34,16 @@ struct private_kernel_interface_t {
kernel_interface_t public;
/**
+ * Registered IPsec constructor
+ */
+ kernel_ipsec_constructor_t ipsec_constructor;
+
+ /**
+ * Registered net constructor
+ */
+ kernel_net_constructor_t net_constructor;
+
+ /**
* ipsec interface
*/
kernel_ipsec_t *ipsec;
@@ -128,18 +138,28 @@ METHOD(kernel_interface_t, del_sa, status_t,
return this->ipsec->del_sa(this->ipsec, src, dst, spi, protocol, cpi, mark);
}
+METHOD(kernel_interface_t, flush_sas, status_t,
+ private_kernel_interface_t *this)
+{
+ if (!this->ipsec)
+ {
+ return NOT_SUPPORTED;
+ }
+ return this->ipsec->flush_sas(this->ipsec);
+}
+
METHOD(kernel_interface_t, add_policy, status_t,
private_kernel_interface_t *this, host_t *src, host_t *dst,
traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
- mark_t mark, bool routed)
+ mark_t mark, policy_priority_t priority)
{
if (!this->ipsec)
{
return NOT_SUPPORTED;
}
return this->ipsec->add_policy(this->ipsec, src, dst, src_ts, dst_ts,
- direction, type, sa, mark, routed);
+ direction, type, sa, mark, priority);
}
METHOD(kernel_interface_t, query_policy, status_t,
@@ -157,15 +177,25 @@ METHOD(kernel_interface_t, query_policy, status_t,
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)
+ traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+ mark_t mark, policy_priority_t priority)
{
if (!this->ipsec)
{
return NOT_SUPPORTED;
}
return this->ipsec->del_policy(this->ipsec, src_ts, dst_ts,
- direction, mark, unrouted);
+ direction, reqid, mark, priority);
+}
+
+METHOD(kernel_interface_t, flush_policies, status_t,
+ private_kernel_interface_t *this)
+{
+ if (!this->ipsec)
+ {
+ return NOT_SUPPORTED;
+ }
+ return this->ipsec->flush_policies(this->ipsec);
}
METHOD(kernel_interface_t, get_source_addr, host_t*,
@@ -310,7 +340,7 @@ METHOD(kernel_interface_t, get_address_by_ts, status_t,
if (!found)
{
- DBG1(DBG_KNL, "no local address found in traffic selector %R", ts);
+ DBG2(DBG_KNL, "no local address found in traffic selector %R", ts);
return FAILED;
}
@@ -324,6 +354,7 @@ METHOD(kernel_interface_t, add_ipsec_interface, void,
{
if (!this->ipsec)
{
+ this->ipsec_constructor = constructor;
this->ipsec = constructor();
}
}
@@ -331,7 +362,11 @@ METHOD(kernel_interface_t, add_ipsec_interface, void,
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 */
+ if (constructor == this->ipsec_constructor)
+ {
+ this->ipsec->destroy(this->ipsec);
+ this->ipsec = NULL;
+ }
}
METHOD(kernel_interface_t, add_net_interface, void,
@@ -339,6 +374,7 @@ METHOD(kernel_interface_t, add_net_interface, void,
{
if (!this->net)
{
+ this->net_constructor = constructor;
this->net = constructor();
}
}
@@ -346,7 +382,11 @@ METHOD(kernel_interface_t, add_net_interface, void,
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 */
+ if (constructor == this->net_constructor)
+ {
+ this->net->destroy(this->net);
+ this->net = NULL;
+ }
}
METHOD(kernel_interface_t, add_listener, void,
@@ -485,9 +525,11 @@ kernel_interface_t *kernel_interface_create()
.update_sa = _update_sa,
.query_sa = _query_sa,
.del_sa = _del_sa,
+ .flush_sas = _flush_sas,
.add_policy = _add_policy,
.query_policy = _query_policy,
.del_policy = _del_policy,
+ .flush_policies = _flush_policies,
.get_source_addr = _get_source_addr,
.get_nexthop = _get_nexthop,
.get_interface = _get_interface,
diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h
index 471a1d5d3..991cfafd0 100644
--- a/src/libhydra/kernel/kernel_interface.h
+++ b/src/libhydra/kernel/kernel_interface.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2010 Tobias Brunner
+ * Copyright (C) 2006-2011 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -175,6 +175,13 @@ struct kernel_interface_t {
mark_t mark);
/**
+ * Flush all SAs from the SAD.
+ *
+ * @return SUCCESS if operation completed
+ */
+ status_t (*flush_sas) (kernel_interface_t *this);
+
+ /**
* Add a policy to the SPD.
*
* A policy is always associated to an SA. Traffic which matches a
@@ -188,7 +195,7 @@ struct kernel_interface_t {
* @param type type of policy, POLICY_(IPSEC|PASS|DROP)
* @param sa details about the SA(s) tied to this policy
* @param mark mark for this policy
- * @param routed TRUE, if this policy is routed in the kernel
+ * @param priority priority of this policy
* @return SUCCESS if operation completed
*/
status_t (*add_policy) (kernel_interface_t *this,
@@ -196,7 +203,8 @@ struct kernel_interface_t {
traffic_selector_t *src_ts,
traffic_selector_t *dst_ts,
policy_dir_t direction, policy_type_t type,
- ipsec_sa_cfg_t *sa, mark_t mark, bool routed);
+ ipsec_sa_cfg_t *sa, mark_t mark,
+ policy_priority_t priority);
/**
* Query the use time of a policy.
@@ -228,15 +236,23 @@ struct kernel_interface_t {
* @param src_ts traffic selector to match traffic source
* @param dst_ts traffic selector to match traffic dest
* @param direction direction of traffic, POLICY_(IN|OUT|FWD)
+ * @param reqid unique ID of the associated SA
* @param mark optional mark
- * @param unrouted TRUE, if this policy is unrouted from the kernel
+ * @param priority priority of the policy
* @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);
+ policy_dir_t direction, u_int32_t reqid,
+ mark_t mark, policy_priority_t priority);
+
+ /**
+ * Flush all policies from the SPD.
+ *
+ * @return SUCCESS if operation completed
+ */
+ status_t (*flush_policies) (kernel_interface_t *this);
/**
* Get our outgoing source address for a destination.
diff --git a/src/libhydra/kernel/kernel_ipsec.c b/src/libhydra/kernel/kernel_ipsec.c
index 383685426..9b38297cc 100644
--- a/src/libhydra/kernel/kernel_ipsec.c
+++ b/src/libhydra/kernel/kernel_ipsec.c
@@ -15,10 +15,14 @@
#include "kernel_ipsec.h"
-ENUM(ipsec_mode_names, MODE_TRANSPORT, MODE_BEET,
+#include <hydra.h>
+
+ENUM(ipsec_mode_names, MODE_TRANSPORT, MODE_DROP,
"TRANSPORT",
"TUNNEL",
"BEET",
+ "PASS",
+ "DROP"
);
ENUM(policy_dir_names, POLICY_IN, POLICY_FWD,
@@ -35,3 +39,21 @@ ENUM(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_LZJH,
"IPCOMP_LZJH"
);
+/**
+ * See header
+ */
+bool kernel_ipsec_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data)
+{
+ if (reg)
+ {
+ hydra->kernel_interface->add_ipsec_interface(hydra->kernel_interface,
+ (kernel_ipsec_constructor_t)data);
+ }
+ else
+ {
+ hydra->kernel_interface->remove_ipsec_interface(hydra->kernel_interface,
+ (kernel_ipsec_constructor_t)data);
+ }
+ return TRUE;
+}
diff --git a/src/libhydra/kernel/kernel_ipsec.h b/src/libhydra/kernel/kernel_ipsec.h
index ef36efd11..ddb63283c 100644
--- a/src/libhydra/kernel/kernel_ipsec.h
+++ b/src/libhydra/kernel/kernel_ipsec.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2010 Tobias Brunner
+ * Copyright (C) 2006-2011 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -27,6 +27,7 @@
typedef enum ipsec_mode_t ipsec_mode_t;
typedef enum policy_dir_t policy_dir_t;
typedef enum policy_type_t policy_type_t;
+typedef enum policy_priority_t policy_priority_t;
typedef enum ipcomp_transform_t ipcomp_transform_t;
typedef struct kernel_ipsec_t kernel_ipsec_t;
typedef struct ipsec_sa_cfg_t ipsec_sa_cfg_t;
@@ -36,6 +37,7 @@ typedef struct mark_t mark_t;
#include <utils/host.h>
#include <crypto/prf_plus.h>
#include <selectors/traffic_selector.h>
+#include <plugins/plugin.h>
/**
* Mode of an IPsec SA.
@@ -47,6 +49,10 @@ enum ipsec_mode_t {
MODE_TUNNEL,
/** BEET mode, tunnel mode but fixed, bound inner addresses */
MODE_BEET,
+ /** passthrough policy for traffic without an IPsec SA */
+ MODE_PASS,
+ /** drop policy discarding traffic */
+ MODE_DROP
};
/**
@@ -86,6 +92,18 @@ enum policy_type_t {
};
/**
+ * High-level priority of a policy.
+ */
+enum policy_priority_t {
+ /** Default priority */
+ POLICY_PRIORITY_DEFAULT,
+ /** Priority for trap policies */
+ POLICY_PRIORITY_ROUTED,
+ /** Priority for fallback drop policies */
+ POLICY_PRIORITY_FALLBACK,
+};
+
+/**
* IPComp transform IDs, as in RFC 4306
*/
enum ipcomp_transform_t {
@@ -288,6 +306,13 @@ struct kernel_ipsec_t {
mark_t mark);
/**
+ * Flush all SAs from the SAD.
+ *
+ * @return SUCCESS if operation completed
+ */
+ status_t (*flush_sas) (kernel_ipsec_t *this);
+
+ /**
* Add a policy to the SPD.
*
* A policy is always associated to an SA. Traffic which matches a
@@ -301,7 +326,7 @@ struct kernel_ipsec_t {
* @param type type of policy, POLICY_(IPSEC|PASS|DROP)
* @param sa details about the SA(s) tied to this policy
* @param mark mark for this policy
- * @param routed TRUE, if this policy is routed in the kernel
+ * @param priority priority of this policy
* @return SUCCESS if operation completed
*/
status_t (*add_policy) (kernel_ipsec_t *this,
@@ -309,7 +334,8 @@ struct kernel_ipsec_t {
traffic_selector_t *src_ts,
traffic_selector_t *dst_ts,
policy_dir_t direction, policy_type_t type,
- ipsec_sa_cfg_t *sa, mark_t mark, bool routed);
+ ipsec_sa_cfg_t *sa, mark_t mark,
+ policy_priority_t priority);
/**
* Query the use time of a policy.
@@ -342,15 +368,23 @@ struct kernel_ipsec_t {
* @param src_ts traffic selector to match traffic source
* @param dst_ts traffic selector to match traffic dest
* @param direction direction of traffic, POLICY_(IN|OUT|FWD)
+ * @param reqid unique ID of the associated SA
* @param mark optional mark
- * @param unrouted TRUE, if this policy is unrouted from the kernel
+ * @param priority priority of the policy
* @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);
+ policy_dir_t direction, u_int32_t reqid,
+ mark_t mark, policy_priority_t priority);
+
+ /**
+ * Flush all policies from the SPD.
+ *
+ * @return SUCCESS if operation completed
+ */
+ status_t (*flush_policies) (kernel_ipsec_t *this);
/**
* Install a bypass policy for the given socket.
@@ -367,4 +401,18 @@ struct kernel_ipsec_t {
void (*destroy) (kernel_ipsec_t *this);
};
+/**
+ * Helper function to (un-)register IPsec kernel interfaces from plugin features.
+ *
+ * This function is a plugin_feature_callback_t and can be used with the
+ * PLUGIN_CALLBACK macro to register an IPsec kernel interface constructor.
+ *
+ * @param plugin plugin registering the kernel interface
+ * @param feature associated plugin feature
+ * @param reg TRUE to register, FALSE to unregister
+ * @param data data passed to callback, an kernel_ipsec_constructor_t
+ */
+bool kernel_ipsec_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data);
+
#endif /** KERNEL_IPSEC_H_ @}*/
diff --git a/src/libhydra/kernel/kernel_listener.h b/src/libhydra/kernel/kernel_listener.h
index 6f2dbd23b..5db297b6f 100644
--- a/src/libhydra/kernel/kernel_listener.h
+++ b/src/libhydra/kernel/kernel_listener.h
@@ -84,7 +84,7 @@ struct kernel_listener_t {
policy_dir_t direction, host_t *local, host_t *remote);
/**
- * Hook called if changes in the networking layer occured (interfaces
+ * Hook called if changes in the networking layer occurred (interfaces
* up/down, routes added/deleted etc.).
*
* @param address TRUE if address list, FALSE if routing changed
diff --git a/src/libhydra/kernel/kernel_net.c b/src/libhydra/kernel/kernel_net.c
new file mode 100644
index 000000000..0841ed803
--- /dev/null
+++ b/src/libhydra/kernel/kernel_net.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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_net.h"
+
+#include <hydra.h>
+
+/**
+ * See header
+ */
+bool kernel_net_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data)
+{
+ if (reg)
+ {
+ hydra->kernel_interface->add_net_interface(hydra->kernel_interface,
+ (kernel_net_constructor_t)data);
+ }
+ else
+ {
+ hydra->kernel_interface->remove_net_interface(hydra->kernel_interface,
+ (kernel_net_constructor_t)data);
+ }
+ return TRUE;
+}
diff --git a/src/libhydra/kernel/kernel_net.h b/src/libhydra/kernel/kernel_net.h
index 69e01f43f..a89e76804 100644
--- a/src/libhydra/kernel/kernel_net.h
+++ b/src/libhydra/kernel/kernel_net.h
@@ -26,6 +26,7 @@ typedef struct kernel_net_t kernel_net_t;
#include <utils/enumerator.h>
#include <utils/host.h>
+#include <plugins/plugin.h>
/**
* Interface to the network subsystem of the kernel.
@@ -142,4 +143,18 @@ struct kernel_net_t {
void (*destroy) (kernel_net_t *this);
};
+/**
+ * Helper function to (un-)register net kernel interfaces from plugin features.
+ *
+ * This function is a plugin_feature_callback_t and can be used with the
+ * PLUGIN_CALLBACK macro to register an net kernel interface constructor.
+ *
+ * @param plugin plugin registering the kernel interface
+ * @param feature associated plugin feature
+ * @param reg TRUE to register, FALSE to unregister
+ * @param data data passed to callback, an kernel_net_constructor_t
+ */
+bool kernel_net_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data);
+
#endif /** KERNEL_NET_H_ @}*/
diff --git a/src/libhydra/plugins/attr/Makefile.in b/src/libhydra/plugins/attr/Makefile.in
index 250ac9539..1ceb93ef3 100644
--- a/src/libhydra/plugins/attr/Makefile.in
+++ b/src/libhydra/plugins/attr/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libhydra/plugins/attr_sql/Makefile.in b/src/libhydra/plugins/attr_sql/Makefile.in
index 80d497f59..4fe577f3b 100644
--- a/src/libhydra/plugins/attr_sql/Makefile.in
+++ b/src/libhydra/plugins/attr_sql/Makefile.in
@@ -204,6 +204,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -212,6 +215,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -228,11 +232,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -276,6 +282,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libhydra/plugins/attr_sql/pool.c b/src/libhydra/plugins/attr_sql/pool.c
index e81a23ed9..a2000cffe 100644
--- a/src/libhydra/plugins/attr_sql/pool.c
+++ b/src/libhydra/plugins/attr_sql/pool.c
@@ -305,6 +305,11 @@ static void status(void)
lease->enumerate(lease, &size);
lease->destroy(lease);
}
+ if (!size)
+ { /* empty pool */
+ printf("%6d %11s %11s ", 0, "n/a", "n/a");
+ goto next_pool;
+ }
printf("%6d ", size);
/* get number of online hosts */
lease = db->query(db, "SELECT COUNT(*) FROM addresses "
@@ -316,7 +321,7 @@ static void status(void)
lease->destroy(lease);
}
printf("%5d (%2d%%) ", online, online*100/size);
- /* get number of online or valid lieases */
+ /* get number of online or valid leases */
lease = db->query(db, "SELECT COUNT(*) FROM addresses "
"WHERE addresses.pool = ? "
"AND ((? AND acquired != 0) "
@@ -330,6 +335,7 @@ static void status(void)
}
printf("%5d (%2d%%) ", used, used*100/size);
+next_pool:
printf("\n");
DESTROY_IF(start);
DESTROY_IF(end);
diff --git a/src/libhydra/plugins/attr_sql/sql_attribute.c b/src/libhydra/plugins/attr_sql/sql_attribute.c
index 7f7bb190c..714bbcd72 100644
--- a/src/libhydra/plugins/attr_sql/sql_attribute.c
+++ b/src/libhydra/plugins/attr_sql/sql_attribute.c
@@ -38,7 +38,7 @@ struct private_sql_attribute_t {
database_t *db;
/**
- * wheter to record lease history in lease table
+ * whether to record lease history in lease table
*/
bool history;
};
@@ -232,12 +232,9 @@ static host_t* get_lease(private_sql_attribute_t *this, char *name,
return NULL;
}
-/**
- * Implementation of attribute_provider_t.acquire_address
- */
-static host_t* acquire_address(private_sql_attribute_t *this,
- char *names, identification_t *id,
- host_t *requested)
+METHOD(attribute_provider_t, acquire_address, host_t*,
+ private_sql_attribute_t *this, char *names, identification_t *id,
+ host_t *requested)
{
host_t *address = NULL;
u_int identity, pool, timeout;
@@ -302,11 +299,9 @@ static host_t* acquire_address(private_sql_attribute_t *this,
return address;
}
-/**
- * Implementation of attribute_provider_t.release_address
- */
-static bool release_address(private_sql_attribute_t *this,
- char *name, host_t *address, identification_t *id)
+METHOD(attribute_provider_t, release_address, bool,
+ private_sql_attribute_t *this, char *name, host_t *address,
+ identification_t *id)
{
enumerator_t *enumerator;
bool found = FALSE;
@@ -343,11 +338,9 @@ static bool release_address(private_sql_attribute_t *this,
return found;
}
-/**
- * Implementation of sql_attribute_t.create_attribute_enumerator
- */
-static enumerator_t* create_attribute_enumerator(private_sql_attribute_t *this,
- char *names, identification_t *id, host_t *vip)
+METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
+ private_sql_attribute_t *this, char *names, identification_t *id,
+ host_t *vip)
{
enumerator_t *attr_enumerator = NULL;
@@ -444,10 +437,8 @@ static enumerator_t* create_attribute_enumerator(private_sql_attribute_t *this,
return (attr_enumerator ? attr_enumerator : enumerator_create_empty());
}
-/**
- * Implementation of sql_attribute_t.destroy
- */
-static void destroy(private_sql_attribute_t *this)
+METHOD(sql_attribute_t, destroy, void,
+ private_sql_attribute_t *this)
{
free(this);
}
@@ -457,17 +448,22 @@ static void destroy(private_sql_attribute_t *this)
*/
sql_attribute_t *sql_attribute_create(database_t *db)
{
- private_sql_attribute_t *this = malloc_thing(private_sql_attribute_t);
+ private_sql_attribute_t *this;
time_t now = time(NULL);
- this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *, host_t *))acquire_address;
- this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address;
- this->public.provider.create_attribute_enumerator = (enumerator_t*(*)(attribute_provider_t*, char *names, identification_t *id, host_t *host))create_attribute_enumerator;
- this->public.destroy = (void(*)(sql_attribute_t*))destroy;
-
- this->db = db;
- this->history = lib->settings->get_bool(lib->settings,
- "libhydra.plugins.attr-sql.lease_history", TRUE);
+ INIT(this,
+ .public = {
+ .provider = {
+ .acquire_address = _acquire_address,
+ .release_address = _release_address,
+ .create_attribute_enumerator = _create_attribute_enumerator,
+ },
+ .destroy = _destroy,
+ },
+ .db = db,
+ .history = lib->settings->get_bool(lib->settings,
+ "libhydra.plugins.attr-sql.lease_history", TRUE),
+ );
/* close any "online" leases in the case we crashed */
if (this->history)
diff --git a/src/libhydra/plugins/kernel_klips/Makefile.in b/src/libhydra/plugins/kernel_klips/Makefile.in
index 5f6512b44..63f3e045b 100644
--- a/src/libhydra/plugins/kernel_klips/Makefile.in
+++ b/src/libhydra/plugins/kernel_klips/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c
index ff4f0ed55..ceff8cdc9 100644
--- a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c
+++ b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c
@@ -1971,7 +1971,7 @@ 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, policy_type_t type, ipsec_sa_cfg_t *sa,
- mark_t mark, bool routed)
+ mark_t mark, policy_priority_t priority)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
@@ -2013,7 +2013,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
this->policies->insert_last(this->policies, policy);
}
- if (routed)
+ if (priority == POLICY_PRIORITY_ROUTED)
{
/* we install this as a %trap eroute in the kernel, later to be
* triggered by packets matching the policy (-> ACQUIRE). */
@@ -2049,9 +2049,11 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
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);
+ build_addflow(msg, satype, spi,
+ priority == POLICY_PRIORITY_ROUTED ? NULL : src,
+ priority == POLICY_PRIORITY_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);
@@ -2347,8 +2349,8 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
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)
+ traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+ mark_t mark, policy_priority_t priority)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg = (struct sadb_msg*)request, *out;
@@ -2382,7 +2384,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
policy_entry_destroy(policy);
/* decrease appropriate counter */
- unrouted ? found->trapcount-- : found->activecount--;
+ priority == POLICY_PRIORITY_ROUTED ? found->trapcount--
+ : found->activecount--;
if (found->trapcount == 0)
{
@@ -2507,7 +2510,7 @@ static void init_ipsec_devices(private_kernel_klips_ipsec_t *this)
}
/**
- * Register a socket for AQUIRE/EXPIRE messages
+ * Register a socket for ACQUIRE/EXPIRE messages
*/
static status_t register_pfkey_socket(private_kernel_klips_ipsec_t *this, u_int8_t satype)
{
@@ -2586,9 +2589,11 @@ kernel_klips_ipsec_t *kernel_klips_ipsec_create()
.update_sa = _update_sa,
.query_sa = _query_sa,
.del_sa = _del_sa,
+ .flush_sas = (void*)return_failed,
.add_policy = _add_policy,
.query_policy = _query_policy,
.del_policy = _del_policy,
+ .flush_policies = (void*)return_failed,
.bypass_socket = _bypass_socket,
.destroy = _destroy,
},
@@ -2634,8 +2639,8 @@ kernel_klips_ipsec_t *kernel_klips_ipsec_create()
return NULL;
}
- this->job = callback_job_create((callback_job_cb_t)receive_events,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive_events,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
diff --git a/src/libhydra/plugins/kernel_klips/kernel_klips_plugin.c b/src/libhydra/plugins/kernel_klips/kernel_klips_plugin.c
index 7fe47f630..ab02ba711 100644
--- a/src/libhydra/plugins/kernel_klips/kernel_klips_plugin.c
+++ b/src/libhydra/plugins/kernel_klips/kernel_klips_plugin.c
@@ -38,11 +38,20 @@ METHOD(plugin_t, get_name, char*,
return "kernel-klips";
}
+METHOD(plugin_t, get_features, int,
+ private_kernel_klips_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(kernel_ipsec_register, kernel_klips_ipsec_create),
+ PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_kernel_klips_plugin_t *this)
{
- hydra->kernel_interface->remove_ipsec_interface(hydra->kernel_interface,
- (kernel_ipsec_constructor_t)kernel_klips_ipsec_create);
free(this);
}
@@ -57,13 +66,11 @@ plugin_t *kernel_klips_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- hydra->kernel_interface->add_ipsec_interface(hydra->kernel_interface,
- (kernel_ipsec_constructor_t)kernel_klips_ipsec_create);
return &this->public.plugin;
}
diff --git a/src/libhydra/plugins/kernel_netlink/Makefile.in b/src/libhydra/plugins/kernel_netlink/Makefile.in
index 78dfb1b54..73dbdd0e3 100644
--- a/src/libhydra/plugins/kernel_netlink/Makefile.in
+++ b/src/libhydra/plugins/kernel_netlink/Makefile.in
@@ -196,6 +196,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -204,6 +207,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -220,11 +224,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -268,6 +274,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
index 8b2a1aa77..b2cf778be 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2010 Tobias Brunner
+ * Copyright (C) 2006-2011 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2008 Andreas Steffen
* Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
@@ -40,32 +40,32 @@
#include <threading/thread.h>
#include <threading/mutex.h>
#include <utils/hashtable.h>
+#include <utils/linked_list.h>
#include <processing/jobs/callback_job.h>
-/** required for Linux 2.6.26 kernel and later */
+/** Required for Linux 2.6.26 kernel and later */
#ifndef XFRM_STATE_AF_UNSPEC
-#define XFRM_STATE_AF_UNSPEC 32
+#define XFRM_STATE_AF_UNSPEC 32
#endif
-/** from linux/in.h */
+/** From linux/in.h */
#ifndef IP_XFRM_POLICY
#define IP_XFRM_POLICY 17
#endif
-/* missing on uclibc */
+/** Missing on uclibc */
#ifndef IPV6_XFRM_POLICY
#define IPV6_XFRM_POLICY 34
#endif /*IPV6_XFRM_POLICY*/
-/** default priority of installed policies */
-#define PRIO_LOW 1024
-#define PRIO_HIGH 512
+/** Default priority of installed policies */
+#define PRIO_BASE 512
-/** default replay window size, if not set using charon.replay_window */
+/** Default replay window size, if not set using charon.replay_window */
#define DEFAULT_REPLAY_WINDOW 32
/**
- * map the limit for bytes and packets to XFRM_INF per default
+ * Map the limit for bytes and packets to XFRM_INF by default
*/
#define XFRM_LIMIT(x) ((x) == 0 ? XFRM_INF : (x))
@@ -75,17 +75,19 @@
#define XFRMNLGRP(x) (1<<(XFRMNLGRP_##x-1))
/**
- * returns a pointer to the first rtattr following the nlmsghdr *nlh and the
+ * 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))))
+#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 !!!
+ * 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)))
+#define XFRM_RTA_NEXT(rta) ((struct rtattr*)(((char*)(rta)) + \
+ RTA_ALIGN((rta)->rta_len)))
/**
- * returns the total size of attached rta data
+ * 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))
@@ -133,7 +135,7 @@ ENUM(xfrm_msg_names, XFRM_MSG_NEWSA, XFRM_MSG_MAPPING,
"XFRM_MSG_MAPPING"
);
-ENUM(xfrm_attr_type_names, XFRMA_UNSPEC, XFRMA_KMADDRESS,
+ENUM(xfrm_attr_type_names, XFRMA_UNSPEC, XFRMA_REPLAY_ESN_VAL,
"XFRMA_UNSPEC",
"XFRMA_ALG_AUTH",
"XFRMA_ALG_CRYPT",
@@ -153,7 +155,11 @@ ENUM(xfrm_attr_type_names, XFRMA_UNSPEC, XFRMA_KMADDRESS,
"XFRMA_POLICY_TYPE",
"XFRMA_MIGRATE",
"XFRMA_ALG_AEAD",
- "XFRMA_KMADDRESS"
+ "XFRMA_KMADDRESS",
+ "XFRMA_ALG_AUTH_TRUNC",
+ "XFRMA_MARK",
+ "XFRMA_TFCPAD",
+ "XFRMA_REPLAY_ESN_VAL",
);
#define END_OF_LIST -1
@@ -196,7 +202,9 @@ static kernel_algorithm_t encryption_algs[] = {
*/
static kernel_algorithm_t integrity_algs[] = {
{AUTH_HMAC_MD5_96, "md5" },
+ {AUTH_HMAC_MD5_128, "hmac(md5)" },
{AUTH_HMAC_SHA1_96, "sha1" },
+ {AUTH_HMAC_SHA1_160, "hmac(sha1)" },
{AUTH_HMAC_SHA2_256_96, "sha256" },
{AUTH_HMAC_SHA2_256_128, "hmac(sha256)" },
{AUTH_HMAC_SHA2_384_192, "hmac(sha384)" },
@@ -234,10 +242,72 @@ static char* lookup_algorithm(kernel_algorithm_t *list, int ikev2)
return NULL;
}
+typedef struct private_kernel_netlink_ipsec_t private_kernel_netlink_ipsec_t;
+
+/**
+ * Private variables and functions of kernel_netlink class.
+ */
+struct private_kernel_netlink_ipsec_t {
+ /**
+ * Public part of the kernel_netlink_t object
+ */
+ kernel_netlink_ipsec_t public;
+
+ /**
+ * Mutex to lock access to installed policies
+ */
+ mutex_t *mutex;
+
+ /**
+ * Hash table of installed policies (policy_entry_t)
+ */
+ hashtable_t *policies;
+
+ /**
+ * Hash table of IPsec SAs using policies (ipsec_sa_t)
+ */
+ hashtable_t *sas;
+
+ /**
+ * 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;
+
+ /**
+ * Whether to track the history of a policy
+ */
+ bool policy_history;
+
+ /**
+ * Size of the replay window, in packets
+ */
+ u_int32_t replay_window;
+
+ /**
+ * Size of the replay window bitmap, in bytes
+ */
+ u_int32_t replay_bmp;
+};
+
typedef struct route_entry_t route_entry_t;
/**
- * installed routing entry
+ * Installed routing entry
*/
struct route_entry_t {
/** Name of the interface the route is bound to */
@@ -246,7 +316,7 @@ struct route_entry_t {
/** Source ip of the route */
host_t *src_ip;
- /** gateway for this route */
+ /** Gateway for this route */
host_t *gateway;
/** Destination net */
@@ -257,7 +327,7 @@ struct route_entry_t {
};
/**
- * destroy an route_entry_t object
+ * Destroy a route_entry_t object
*/
static void route_entry_destroy(route_entry_t *this)
{
@@ -268,30 +338,226 @@ static void route_entry_destroy(route_entry_t *this)
free(this);
}
+/**
+ * Compare two route_entry_t objects
+ */
+static bool route_entry_equals(route_entry_t *a, route_entry_t *b)
+{
+ return a->if_name && b->if_name && streq(a->if_name, b->if_name) &&
+ a->src_ip->equals(a->src_ip, b->src_ip) &&
+ a->gateway->equals(a->gateway, b->gateway) &&
+ chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen;
+}
+
+typedef struct ipsec_sa_t ipsec_sa_t;
+
+/**
+ * IPsec SA assigned to a policy.
+ */
+struct ipsec_sa_t {
+ /** Source address of this SA */
+ host_t *src;
+
+ /** Destination address of this SA */
+ host_t *dst;
+
+ /** Optional mark */
+ mark_t mark;
+
+ /** Description of this SA */
+ ipsec_sa_cfg_t cfg;
+
+ /** Reference count for this SA */
+ refcount_t refcount;
+};
+
+/**
+ * Hash function for ipsec_sa_t objects
+ */
+static u_int ipsec_sa_hash(ipsec_sa_t *sa)
+{
+ return chunk_hash_inc(sa->src->get_address(sa->src),
+ chunk_hash_inc(sa->dst->get_address(sa->dst),
+ chunk_hash_inc(chunk_from_thing(sa->mark),
+ chunk_hash(chunk_from_thing(sa->cfg)))));
+}
+
+/**
+ * Equality function for ipsec_sa_t objects
+ */
+static bool ipsec_sa_equals(ipsec_sa_t *sa, ipsec_sa_t *other_sa)
+{
+ return sa->src->ip_equals(sa->src, other_sa->src) &&
+ sa->dst->ip_equals(sa->dst, other_sa->dst) &&
+ memeq(&sa->mark, &other_sa->mark, sizeof(mark_t)) &&
+ memeq(&sa->cfg, &other_sa->cfg, sizeof(ipsec_sa_cfg_t));
+}
+
+/**
+ * Allocate or reference an IPsec SA object
+ */
+static ipsec_sa_t *ipsec_sa_create(private_kernel_netlink_ipsec_t *this,
+ host_t *src, host_t *dst, mark_t mark,
+ ipsec_sa_cfg_t *cfg)
+{
+ ipsec_sa_t *sa, *found;
+ INIT(sa,
+ .src = src,
+ .dst = dst,
+ .mark = mark,
+ .cfg = *cfg,
+ );
+ found = this->sas->get(this->sas, sa);
+ if (!found)
+ {
+ sa->src = src->clone(src);
+ sa->dst = dst->clone(dst);
+ this->sas->put(this->sas, sa, sa);
+ }
+ else
+ {
+ free(sa);
+ sa = found;
+ }
+ ref_get(&sa->refcount);
+ return sa;
+}
+
+/**
+ * Release and destroy an IPsec SA object
+ */
+static void ipsec_sa_destroy(private_kernel_netlink_ipsec_t *this,
+ ipsec_sa_t *sa)
+{
+ if (ref_put(&sa->refcount))
+ {
+ this->sas->remove(this->sas, sa);
+ DESTROY_IF(sa->src);
+ DESTROY_IF(sa->dst);
+ free(sa);
+ }
+}
+
+typedef struct policy_sa_t policy_sa_t;
+typedef struct policy_sa_fwd_t policy_sa_fwd_t;
+
+/**
+ * Mapping between a policy and an IPsec SA.
+ */
+struct policy_sa_t {
+ /** Priority assigned to the policy when installed with this SA */
+ u_int32_t priority;
+
+ /** Type of the policy */
+ policy_type_t type;
+
+ /** Assigned SA */
+ ipsec_sa_t *sa;
+};
+
+/**
+ * For forward policies we also cache the traffic selectors in order to install
+ * the route.
+ */
+struct policy_sa_fwd_t {
+ /** Generic interface */
+ policy_sa_t generic;
+
+ /** Source traffic selector of this policy */
+ traffic_selector_t *src_ts;
+
+ /** Destination traffic selector of this policy */
+ traffic_selector_t *dst_ts;
+};
+
+/**
+ * Create a policy_sa(_fwd)_t object
+ */
+static policy_sa_t *policy_sa_create(private_kernel_netlink_ipsec_t *this,
+ policy_dir_t dir, policy_type_t type, host_t *src, host_t *dst,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts, mark_t mark,
+ ipsec_sa_cfg_t *cfg)
+{
+ policy_sa_t *policy;
+
+ if (dir == POLICY_FWD)
+ {
+ policy_sa_fwd_t *fwd;
+ INIT(fwd,
+ .src_ts = src_ts->clone(src_ts),
+ .dst_ts = dst_ts->clone(dst_ts),
+ );
+ policy = &fwd->generic;
+ }
+ else
+ {
+ INIT(policy, .priority = 0);
+ }
+ policy->type = type;
+ policy->sa = ipsec_sa_create(this, src, dst, mark, cfg);
+ return policy;
+}
+
+/**
+ * Destroy a policy_sa(_fwd)_t object
+ */
+static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir,
+ private_kernel_netlink_ipsec_t *this)
+{
+ if (*dir == POLICY_FWD)
+ {
+ policy_sa_fwd_t *fwd = (policy_sa_fwd_t*)policy;
+ fwd->src_ts->destroy(fwd->src_ts);
+ fwd->dst_ts->destroy(fwd->dst_ts);
+ }
+ ipsec_sa_destroy(this, policy->sa);
+ free(policy);
+}
+
typedef struct policy_entry_t policy_entry_t;
/**
- * installed kernel policy.
+ * Installed kernel policy.
*/
struct policy_entry_t {
- /** direction of this policy: in, out, forward */
+ /** Direction of this policy: in, out, forward */
u_int8_t direction;
- /** parameters of installed policy */
+ /** Parameters of installed policy */
struct xfrm_selector sel;
- /** optional mark */
+ /** Optional mark */
u_int32_t mark;
- /** associated route installed for this policy */
+ /** Associated route installed for this policy */
route_entry_t *route;
- /** by how many CHILD_SA's this policy is used */
- u_int refcount;
+ /** List of SAs this policy is used by, ordered by priority */
+ linked_list_t *used_by;
};
/**
+ * Destroy a policy_entry_t object
+ */
+static void policy_entry_destroy(private_kernel_netlink_ipsec_t *this,
+ policy_entry_t *policy)
+{
+ if (policy->route)
+ {
+ route_entry_destroy(policy->route);
+ }
+ if (policy->used_by)
+ {
+ policy->used_by->invoke_function(policy->used_by,
+ (linked_list_invoke_t)policy_sa_destroy,
+ &policy->direction, this);
+ policy->used_by->destroy(policy->used_by);
+ }
+ free(policy);
+}
+
+/**
* Hash function for policy_entry_t objects
*/
static u_int policy_hash(policy_entry_t *key)
@@ -311,60 +577,35 @@ static bool policy_equals(policy_entry_t *key, policy_entry_t *other_key)
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.
+ * Calculate the priority of a policy
*/
-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;
-
- /**
- * Size of the replay window, in packets
- */
- u_int32_t replay_window;
-
- /**
- * Size of the replay window bitmap, in bytes
- */
- u_int32_t replay_bmp;
-};
+static inline u_int32_t get_priority(policy_entry_t *policy,
+ policy_priority_t prio)
+{
+ u_int32_t priority = PRIO_BASE;
+ switch (prio)
+ {
+ case POLICY_PRIORITY_FALLBACK:
+ priority <<= 1;
+ /* fall-through */
+ case POLICY_PRIORITY_ROUTED:
+ priority <<= 1;
+ /* fall-through */
+ case POLICY_PRIORITY_DEFAULT:
+ break;
+ }
+ /* calculate priority based on selector size, small size = high prio */
+ priority -= policy->sel.prefixlen_s;
+ priority -= policy->sel.prefixlen_d;
+ priority <<= 2; /* make some room for the two flags */
+ priority += policy->sel.sport_mask || policy->sel.dport_mask ? 0 : 2;
+ priority += policy->sel.proto ? 0 : 1;
+ return priority;
+}
/**
- * convert the general ipsec mode to the one defined in xfrm.h
+ * Convert the general ipsec mode to the one defined in xfrm.h
*/
static u_int8_t mode2kernel(ipsec_mode_t mode)
{
@@ -382,7 +623,7 @@ static u_int8_t mode2kernel(ipsec_mode_t mode)
}
/**
- * convert a host_t to a struct xfrm_address
+ * Convert a host_t to a struct xfrm_address
*/
static void host2xfrm(host_t *host, xfrm_address_t *xfrm)
{
@@ -391,7 +632,7 @@ static void host2xfrm(host_t *host, xfrm_address_t *xfrm)
}
/**
- * convert a struct xfrm_address to a host_t
+ * Convert a struct xfrm_address to a host_t
*/
static host_t* xfrm2host(int family, xfrm_address_t *xfrm, u_int16_t port)
{
@@ -412,7 +653,7 @@ static host_t* xfrm2host(int family, xfrm_address_t *xfrm, u_int16_t port)
}
/**
- * convert a traffic selector address range to subnet and its mask.
+ * 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)
@@ -427,12 +668,12 @@ static void ts2subnet(traffic_selector_t* ts,
}
/**
- * convert a traffic selector port range to port/portmask
+ * 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
+ /* 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.
*/
@@ -454,7 +695,7 @@ static void ts2ports(traffic_selector_t* ts,
}
/**
- * convert a pair of traffic_selectors to a xfrm_selector
+ * Convert a pair of traffic_selectors to an xfrm_selector
*/
static struct xfrm_selector ts2selector(traffic_selector_t *src,
traffic_selector_t *dst)
@@ -476,7 +717,7 @@ static struct xfrm_selector ts2selector(traffic_selector_t *src,
}
/**
- * convert a xfrm_selector to a src|dst traffic_selector
+ * Convert an xfrm_selector to a src|dst traffic_selector
*/
static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src)
{
@@ -525,16 +766,17 @@ static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src)
}
/**
- * process a XFRM_MSG_ACQUIRE from kernel
+ * Process a XFRM_MSG_ACQUIRE from kernel
*/
-static void process_acquire(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr)
+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;
+ traffic_selector_t *src_ts, *dst_ts;
+ u_int32_t reqid = 0;
+ int proto = 0;
acquire = (struct xfrm_user_acquire*)NLMSG_DATA(hdr);
rta = XFRM_RTA(hdr, struct xfrm_user_acquire);
@@ -549,7 +791,6 @@ static void process_acquire(private_kernel_netlink_ipsec_t *this, struct nlmsghd
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;
@@ -574,13 +815,14 @@ static void process_acquire(private_kernel_netlink_ipsec_t *this, struct nlmsghd
}
/**
- * process a XFRM_MSG_EXPIRE from kernel
+ * Process a XFRM_MSG_EXPIRE from kernel
*/
-static void process_expire(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr)
+static void process_expire(private_kernel_netlink_ipsec_t *this,
+ struct nlmsghdr *hdr)
{
- u_int8_t protocol;
- u_int32_t spi, reqid;
struct xfrm_user_expire *expire;
+ u_int32_t spi, reqid;
+ u_int8_t protocol;
expire = (struct xfrm_user_expire*)NLMSG_DATA(hdr);
protocol = expire->state.id.proto;
@@ -601,17 +843,18 @@ static void process_expire(private_kernel_netlink_ipsec_t *this, struct nlmsghdr
}
/**
- * process a XFRM_MSG_MIGRATE from kernel
+ * Process a XFRM_MSG_MIGRATE from kernel
*/
-static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr)
+static void process_migrate(private_kernel_netlink_ipsec_t *this,
+ struct nlmsghdr *hdr)
{
+ struct xfrm_userpolicy_id *policy_id;
+ struct rtattr *rta;
+ size_t rtasize;
traffic_selector_t *src_ts, *dst_ts;
host_t *local = NULL, *remote = NULL;
host_t *old_src = NULL, *old_dst = NULL;
host_t *new_src = NULL, *new_dst = NULL;
- struct xfrm_userpolicy_id *policy_id;
- struct rtattr *rta;
- size_t rtasize;
u_int32_t reqid = 0;
policy_dir_t dir;
@@ -650,7 +893,7 @@ static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghd
new_dst = xfrm2host(migrate->new_family, &migrate->new_daddr, 0);
reqid = migrate->reqid;
DBG2(DBG_KNL, " migrate %H...%H to %H...%H, reqid {%u}",
- old_src, old_dst, new_src, new_dst, reqid);
+ old_src, old_dst, new_src, new_dst, reqid);
DESTROY_IF(old_src);
DESTROY_IF(old_dst);
DESTROY_IF(new_src);
@@ -674,14 +917,13 @@ static void process_migrate(private_kernel_netlink_ipsec_t *this, struct nlmsghd
}
/**
- * process a XFRM_MSG_MAPPING from kernel
+ * Process a XFRM_MSG_MAPPING from kernel
*/
static void process_mapping(private_kernel_netlink_ipsec_t *this,
struct nlmsghdr *hdr)
{
- u_int32_t spi, reqid;
struct xfrm_user_mapping *mapping;
- host_t *host;
+ u_int32_t spi, reqid;
mapping = (struct xfrm_user_mapping*)NLMSG_DATA(hdr);
spi = mapping->id.spi;
@@ -691,6 +933,7 @@ static void process_mapping(private_kernel_netlink_ipsec_t *this,
if (mapping->id.proto == IPPROTO_ESP)
{
+ host_t *host;
host = xfrm2host(mapping->id.family, &mapping->new_saddr,
mapping->new_sport);
if (host)
@@ -757,7 +1000,8 @@ static job_requeue_t receive_events(private_kernel_netlink_ipsec_t *this)
process_mapping(this, hdr);
break;
default:
- DBG1(DBG_KNL, "received unknown event from xfrm event socket: %d", hdr->nlmsg_type);
+ DBG1(DBG_KNL, "received unknown event from xfrm event "
+ "socket: %d", hdr->nlmsg_type);
break;
}
hdr = NLMSG_NEXT(hdr, len);
@@ -769,8 +1013,8 @@ static job_requeue_t receive_events(private_kernel_netlink_ipsec_t *this)
* 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)
+ 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;
@@ -811,7 +1055,6 @@ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this,
case NLMSG_ERROR:
{
struct nlmsgerr *err = NLMSG_DATA(hdr);
-
DBG1(DBG_KNL, "allocating SPI failed: %s (%d)",
strerror(-err->error), -err->error);
break;
@@ -843,14 +1086,13 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
DBG2(DBG_KNL, "getting SPI for reqid {%u}", reqid);
if (get_spi_internal(this, src, dst, protocol,
- 0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS)
+ 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;
}
@@ -862,8 +1104,8 @@ METHOD(kernel_ipsec_t, get_cpi, status_t,
DBG2(DBG_KNL, "getting CPI for reqid {%u}", reqid);
- if (get_spi_internal(this, src, dst,
- IPPROTO_COMP, 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS)
+ 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;
@@ -872,7 +1114,6 @@ METHOD(kernel_ipsec_t, get_cpi, status_t,
*cpi = htons((u_int16_t)ntohl(received_spi));
DBG2(DBG_KNL, "got CPI %.4x for reqid {%u}", ntohs(*cpi), reqid);
-
return SUCCESS;
}
@@ -896,9 +1137,9 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
if (ipcomp != IPCOMP_NONE && cpi != 0)
{
lifetime_cfg_t lft = {{0,0,0},{0,0,0},{0,0,0}};
- add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark, tfc,
- &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, chunk_empty,
- mode, ipcomp, 0, FALSE, FALSE, inbound, NULL, NULL);
+ add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
+ tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED,
+ chunk_empty, mode, ipcomp, 0, FALSE, FALSE, inbound, NULL, NULL);
ipcomp = IPCOMP_NONE;
/* use transport mode ESP SA, IPComp uses tunnel mode */
mode = MODE_TRANSPORT;
@@ -908,8 +1149,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
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);
+ DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u} (mark "
+ "%u/0x%8x)", ntohl(spi), reqid, mark.value, mark.mask);
}
else
{
@@ -990,7 +1231,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
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);
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo_aead) +
+ enc_key.len);
hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
@@ -1039,6 +1281,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
if (int_alg != AUTH_UNDEFINED)
{
+ u_int trunc_len = 0;
+
alg_name = lookup_algorithm(integrity_algs, int_alg);
if (alg_name == NULL)
{
@@ -1049,14 +1293,29 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
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)
+ switch (int_alg)
+ {
+ case AUTH_HMAC_MD5_128:
+ case AUTH_HMAC_SHA2_256_128:
+ trunc_len = 128;
+ break;
+ case AUTH_HMAC_SHA1_160:
+ trunc_len = 160;
+ break;
+ default:
+ break;
+ }
+
+ if (trunc_len)
{
struct xfrm_algo_auth* algo;
/* the kernel uses SHA256 with 96 bit truncation by default,
- * use specified truncation size supported by newer kernels */
+ * use specified truncation size supported by newer kernels.
+ * also use this for untruncated MD5 and SHA1. */
rthdr->rta_type = XFRMA_ALG_AUTH_TRUNC;
- rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo_auth) + int_key.len);
+ rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_algo_auth) +
+ int_key.len);
hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
@@ -1066,7 +1325,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
algo = (struct xfrm_algo_auth*)RTA_DATA(rthdr);
algo->alg_key_len = int_key.len * 8;
- algo->alg_trunc_len = 128;
+ algo->alg_trunc_len = trunc_len;
strcpy(algo->alg_name, alg_name);
memcpy(algo->alg_key, int_key.ptr, int_key.len);
}
@@ -1137,14 +1396,15 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
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
+ * 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. */
+ * (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);
}
@@ -1207,10 +1467,13 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
/* bmp_len contains number uf __u32's */
replay->bmp_len = this->replay_bmp;
replay->replay_window = this->replay_window;
+ DBG2(DBG_KNL, " using replay window of %u bytes",
+ this->replay_window);
rthdr = XFRM_RTA_NEXT(rthdr);
if (esn)
{
+ DBG2(DBG_KNL, " using extended sequence numbers (ESN)");
sa->flags |= XFRM_STATE_ESN;
}
}
@@ -1261,7 +1524,7 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
memset(&request, 0, sizeof(request));
DBG2(DBG_KNL, "querying replay state from SAD entry with SPI %.8x",
- ntohl(spi));
+ ntohl(spi));
hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST;
@@ -1291,8 +1554,9 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
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);
+ DBG1(DBG_KNL, "querying replay state from SAD entry "
+ "failed: %s (%d)", strerror(-err->error),
+ -err->error);
break;
}
default:
@@ -1500,7 +1764,8 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
}
else
{
- DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi));
+ DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x",
+ ntohl(spi));
}
return FAILED;
}
@@ -1596,12 +1861,13 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
/* 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));
+ DBG1(DBG_KNL, "unable to delete old SAD entry with SPI %.8x",
+ ntohl(spi));
goto failed;
}
DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H",
- ntohl(spi), src, dst, new_src, new_dst);
+ 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)));
@@ -1695,7 +1961,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
else
{
DBG1(DBG_KNL, "unable to copy replay state from old SAD entry "
- "with SPI %.8x", ntohl(spi));
+ "with SPI %.8x", ntohl(spi));
}
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
@@ -1709,77 +1975,62 @@ failed:
free(replay);
free(replay_esn);
memwipe(out, len);
+ memwipe(request, sizeof(request));
free(out);
return status;
}
-METHOD(kernel_ipsec_t, add_policy, status_t,
- private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
- policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
- mark_t mark, bool routed)
+METHOD(kernel_ipsec_t, flush_sas, status_t,
+ private_kernel_netlink_ipsec_t *this)
{
- policy_entry_t *current, *policy;
- bool found = FALSE;
netlink_buf_t request;
- struct xfrm_userpolicy_info *policy_info;
struct nlmsghdr *hdr;
- int i;
+ struct xfrm_usersa_flush *flush;
- /* 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;
+ memset(&request, 0, sizeof(request));
- /* 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;
- }
+ DBG2(DBG_KNL, "flushing all SAD entries");
- 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
+ hdr = (struct nlmsghdr*)request;
+ hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+ hdr->nlmsg_type = XFRM_MSG_FLUSHSA;
+ hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_flush));
+
+ flush = (struct xfrm_usersa_flush*)NLMSG_DATA(hdr);
+ flush->proto = IPSEC_PROTO_ANY;
+
+ if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
{
- DBG2(DBG_KNL, "adding policy %R === %R %N",
- src_ts, dst_ts, policy_dir_names, direction);
+ DBG1(DBG_KNL, "unable to flush SAD entries");
+ return FAILED;
}
+ return SUCCESS;
+}
+
+/**
+ * Add or update a policy in the kernel.
+ *
+ * Note: The mutex has to be locked when entering this function
+ * and is unlocked here in any case.
+ */
+static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
+ policy_entry_t *policy, policy_sa_t *mapping, bool update)
+{
+ netlink_buf_t request;
+ policy_entry_t clone;
+ ipsec_sa_t *ipsec = mapping->sa;
+ struct xfrm_userpolicy_info *policy_info;
+ struct nlmsghdr *hdr;
+ int i;
+
+ /* clone the policy so we are able to check it out again later */
+ memcpy(&clone, policy, sizeof(policy_entry_t));
memset(&request, 0, sizeof(request));
hdr = (struct nlmsghdr*)request;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- hdr->nlmsg_type = found ? XFRM_MSG_UPDPOLICY : XFRM_MSG_NEWPOLICY;
+ hdr->nlmsg_type = update ? 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);
@@ -1787,18 +2038,10 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
policy_info->dir = policy->direction;
/* calculate priority based on selector size, small size = high prio */
- policy_info->priority = routed ? PRIO_LOW : PRIO_HIGH;
- policy_info->priority -= policy->sel.prefixlen_s;
- policy_info->priority -= policy->sel.prefixlen_d;
- policy_info->priority <<= 2; /* make some room for the two flags */
- policy_info->priority += policy->sel.sport_mask ||
- policy->sel.dport_mask ? 0 : 2;
- policy_info->priority += policy->sel.proto ? 0 : 1;
-
- policy_info->action = type != POLICY_DROP ? XFRM_POLICY_ALLOW
- : XFRM_POLICY_BLOCK;
+ policy_info->priority = mapping->priority;
+ policy_info->action = mapping->type != POLICY_DROP ? XFRM_POLICY_ALLOW
+ : XFRM_POLICY_BLOCK;
policy_info->share = XFRM_SHARE_ANY;
- this->mutex->unlock(this->mutex);
/* policies don't expire */
policy_info->lft.soft_byte_limit = XFRM_INF;
@@ -1812,18 +2055,18 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_info);
- if (type == POLICY_IPSEC)
+ if (mapping->type == POLICY_IPSEC)
{
struct xfrm_user_tmpl *tmpl = (struct xfrm_user_tmpl*)RTA_DATA(rthdr);
struct {
u_int8_t proto;
bool use;
} protos[] = {
- { IPPROTO_COMP, sa->ipcomp.transform != IPCOMP_NONE },
- { IPPROTO_ESP, sa->esp.use },
- { IPPROTO_AH, sa->ah.use },
+ { IPPROTO_COMP, ipsec->cfg.ipcomp.transform != IPCOMP_NONE },
+ { IPPROTO_ESP, ipsec->cfg.esp.use },
+ { IPPROTO_AH, ipsec->cfg.ah.use },
};
- ipsec_mode_t proto_mode = sa->mode;
+ ipsec_mode_t proto_mode = ipsec->cfg.mode;
rthdr->rta_type = XFRMA_TMPL;
rthdr->rta_len = 0; /* actual length is set below */
@@ -1839,21 +2082,22 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
hdr->nlmsg_len += RTA_ALIGN(RTA_LENGTH(sizeof(struct xfrm_user_tmpl)));
if (hdr->nlmsg_len > sizeof(request))
{
+ this->mutex->unlock(this->mutex);
return FAILED;
}
- tmpl->reqid = sa->reqid;
+ tmpl->reqid = ipsec->cfg.reqid;
tmpl->id.proto = protos[i].proto;
tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
tmpl->mode = mode2kernel(proto_mode);
tmpl->optional = protos[i].proto == IPPROTO_COMP &&
- direction != POLICY_OUT;
- tmpl->family = src->get_family(src);
+ policy->direction != POLICY_OUT;
+ tmpl->family = ipsec->src->get_family(ipsec->src);
if (proto_mode == MODE_TUNNEL)
{ /* only for tunnel mode */
- host2xfrm(src, &tmpl->saddr);
- host2xfrm(dst, &tmpl->id.daddr);
+ host2xfrm(ipsec->src, &tmpl->saddr);
+ host2xfrm(ipsec->dst, &tmpl->id.daddr);
}
tmpl++;
@@ -1865,7 +2109,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
rthdr = XFRM_RTA_NEXT(rthdr);
}
- if (mark.value)
+ if (ipsec->mark.value)
{
struct xfrm_mark *mrk;
@@ -1875,71 +2119,110 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
+ this->mutex->unlock(this->mutex);
return FAILED;
}
mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
- mrk->v = mark.value;
- mrk->m = mark.mask;
+ mrk->v = ipsec->mark.value;
+ mrk->m = ipsec->mark.mask;
}
+ this->mutex->unlock(this->mutex);
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;
}
+ /* find the policy again */
+ this->mutex->lock(this->mutex);
+ policy = this->policies->get(this->policies, &clone);
+ if (!policy ||
+ policy->used_by->find_first(policy->used_by,
+ NULL, (void**)&mapping) != SUCCESS)
+ { /* policy or mapping is already gone, ignore */
+ this->mutex->unlock(this->mutex);
+ return SUCCESS;
+ }
+
/* install a route, if:
- * - 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 &&
- sa->mode != MODE_TRANSPORT && this->install_routes)
+ if (policy->direction == POLICY_FWD &&
+ ipsec->cfg.mode != MODE_TRANSPORT && this->install_routes)
{
route_entry_t *route = malloc_thing(route_entry_t);
+ policy_sa_fwd_t *fwd = (policy_sa_fwd_t*)mapping;
if (hydra->kernel_interface->get_address_by_ts(hydra->kernel_interface,
- dst_ts, &route->src_ip) == SUCCESS)
+ fwd->dst_ts, &route->src_ip) == SUCCESS)
{
- /* get the nexthop to src (src as we are in POLICY_FWD).*/
+ /* get the nexthop to src (src as we are in POLICY_FWD) */
route->gateway = hydra->kernel_interface->get_nexthop(
- hydra->kernel_interface, src);
+ hydra->kernel_interface, ipsec->src);
/* install route via outgoing interface */
route->if_name = hydra->kernel_interface->get_interface(
- hydra->kernel_interface, dst);
+ hydra->kernel_interface, ipsec->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)
+ if (!route->if_name)
+ {
+ this->mutex->unlock(this->mutex);
+ route_entry_destroy(route);
+ return SUCCESS;
+ }
+
+ if (policy->route)
{
- DBG2(DBG_KNL, "installing route: %R via %H src %H dev %s",
- src_ts, route->gateway, route->src_ip, route->if_name);
- switch (hydra->kernel_interface->add_route(
- hydra->kernel_interface, route->dst_net,
- route->prefixlen, route->gateway,
- route->src_ip, route->if_name))
+ route_entry_t *old = policy->route;
+ if (route_entry_equals(old, route))
+ { /* keep previously installed route. since it might have
+ * still been removed by an address change, we install it
+ * again but ignore the result */
+ hydra->kernel_interface->add_route(hydra->kernel_interface,
+ route->dst_net, route->prefixlen, route->gateway,
+ route->src_ip, route->if_name);
+ this->mutex->unlock(this->mutex);
+ route_entry_destroy(route);
+ return SUCCESS;
+ }
+ /* uninstall previously installed route */
+ if (hydra->kernel_interface->del_route(hydra->kernel_interface,
+ old->dst_net, old->prefixlen, old->gateway,
+ old->src_ip, old->if_name) != SUCCESS)
{
- 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;
+ DBG1(DBG_KNL, "error uninstalling route installed with "
+ "policy %R === %R %N", fwd->src_ts,
+ fwd->dst_ts, policy_dir_names,
+ policy->direction);
}
+ route_entry_destroy(old);
+ policy->route = NULL;
}
- else
+
+ DBG2(DBG_KNL, "installing route: %R via %H src %H dev %s",
+ fwd->src_ts, route->gateway, route->src_ip, route->if_name);
+ switch (hydra->kernel_interface->add_route(
+ hydra->kernel_interface, route->dst_net,
+ route->prefixlen, route->gateway,
+ route->src_ip, route->if_name))
{
- route_entry_destroy(route);
+ 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
@@ -1947,6 +2230,110 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
free(route);
}
}
+ this->mutex->unlock(this->mutex);
+ return SUCCESS;
+}
+
+METHOD(kernel_ipsec_t, add_policy, status_t,
+ private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+ policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
+ mark_t mark, policy_priority_t priority)
+{
+ policy_entry_t *policy, *current;
+ policy_sa_t *assigned_sa, *current_sa;
+ enumerator_t *enumerator;
+ bool found = FALSE, update = TRUE;
+
+ /* create a policy */
+ INIT(policy,
+ .sel = ts2selector(src_ts, dst_ts),
+ .mark = mark.value & mark.mask,
+ .direction = direction,
+ );
+
+ /* find the policy, which matches EXACTLY */
+ this->mutex->lock(this->mutex);
+ current = this->policies->get(this->policies, policy);
+ if (current)
+ {
+ /* use existing policy */
+ 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);
+ }
+ policy_entry_destroy(this, policy);
+ policy = current;
+ found = TRUE;
+ }
+ else
+ { /* use the new one, if we have no such policy */
+ policy->used_by = linked_list_create();
+ this->policies->put(this->policies, policy, policy);
+ }
+
+ /* cache the assigned IPsec SA */
+ assigned_sa = policy_sa_create(this, direction, type, src, dst, src_ts,
+ dst_ts, mark, sa);
+ assigned_sa->priority = get_priority(policy, priority);
+
+ if (this->policy_history)
+ { /* insert the SA according to its priority */
+ enumerator = policy->used_by->create_enumerator(policy->used_by);
+ while (enumerator->enumerate(enumerator, (void**)&current_sa))
+ {
+ if (current_sa->priority >= assigned_sa->priority)
+ {
+ break;
+ }
+ update = FALSE;
+ }
+ policy->used_by->insert_before(policy->used_by, enumerator,
+ assigned_sa);
+ enumerator->destroy(enumerator);
+ }
+ else
+ { /* simply insert it last and only update if it is not installed yet */
+ policy->used_by->insert_last(policy->used_by, assigned_sa);
+ update = !found;
+ }
+
+ if (!update)
+ { /* we don't update the policy if the priority is lower than that of
+ * the currently installed one */
+ this->mutex->unlock(this->mutex);
+ return SUCCESS;
+ }
+
+ if (mark.value)
+ {
+ DBG2(DBG_KNL, "%s policy %R === %R %N (mark %u/0x%8x)",
+ found ? "updating" : "adding", src_ts, dst_ts,
+ policy_dir_names, direction, mark.value, mark.mask);
+ }
+ else
+ {
+ DBG2(DBG_KNL, "%s policy %R === %R %N",
+ found ? "updating" : "adding", src_ts, dst_ts,
+ policy_dir_names, direction);
+ }
+
+ if (add_policy_internal(this, policy, assigned_sa, found) != SUCCESS)
+ {
+ DBG1(DBG_KNL, "unable to %s policy %R === %R %N",
+ found ? "update" : "add", src_ts, dst_ts,
+ policy_dir_names, direction);
+ return FAILED;
+ }
return SUCCESS;
}
@@ -2018,7 +2405,7 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
{
struct nlmsgerr *err = NLMSG_DATA(hdr);
DBG1(DBG_KNL, "querying policy failed: %s (%d)",
- strerror(-err->error), -err->error);
+ strerror(-err->error), -err->error);
break;
}
default:
@@ -2055,14 +2442,17 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
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)
+ traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+ mark_t mark, policy_priority_t prio)
{
- policy_entry_t *current, policy, *to_delete = NULL;
- route_entry_t *route;
+ policy_entry_t *current, policy;
+ enumerator_t *enumerator;
+ policy_sa_t *mapping;
netlink_buf_t request;
struct nlmsghdr *hdr;
struct xfrm_userpolicy_id *policy_id;
+ bool is_installed = TRUE;
+ u_int32_t priority;
if (mark.value)
{
@@ -2085,21 +2475,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
/* 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 (!current)
{
if (mark.value)
{
@@ -2112,9 +2488,65 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found",
src_ts, dst_ts, policy_dir_names, direction);
}
+ this->mutex->unlock(this->mutex);
return NOT_FOUND;
}
+ if (this->policy_history)
+ { /* remove mapping to SA by reqid and priority */
+ priority = get_priority(current, prio);
+ enumerator = current->used_by->create_enumerator(current->used_by);
+ while (enumerator->enumerate(enumerator, (void**)&mapping))
+ {
+ if (reqid == mapping->sa->cfg.reqid &&
+ priority == mapping->priority)
+ {
+ current->used_by->remove_at(current->used_by, enumerator);
+ policy_sa_destroy(mapping, &direction, this);
+ break;
+ }
+ is_installed = FALSE;
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ { /* remove one of the SAs but don't update the policy */
+ current->used_by->remove_last(current->used_by, (void**)&mapping);
+ policy_sa_destroy(mapping, &direction, this);
+ is_installed = FALSE;
+ }
+
+ if (current->used_by->get_count(current->used_by) > 0)
+ { /* policy is used by more SAs, keep in kernel */
+ DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed");
+ if (!is_installed)
+ { /* no need to update as the policy was not installed for this SA */
+ this->mutex->unlock(this->mutex);
+ return SUCCESS;
+ }
+
+ if (mark.value)
+ {
+ DBG2(DBG_KNL, "updating policy %R === %R %N (mark %u/0x%8x)",
+ src_ts, dst_ts, policy_dir_names, direction,
+ mark.value, mark.mask);
+ }
+ else
+ {
+ DBG2(DBG_KNL, "updating policy %R === %R %N",
+ src_ts, dst_ts, policy_dir_names, direction);
+ }
+
+ current->used_by->get_first(current->used_by, (void**)&mapping);
+ if (add_policy_internal(this, current, mapping, TRUE) != SUCCESS)
+ {
+ DBG1(DBG_KNL, "unable to update policy %R === %R %N",
+ src_ts, dst_ts, policy_dir_names, direction);
+ return FAILED;
+ }
+ return SUCCESS;
+ }
+
memset(&request, 0, sizeof(request));
hdr = (struct nlmsghdr*)request;
@@ -2123,7 +2555,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
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->sel = current->sel;
policy_id->dir = direction;
if (mark.value)
@@ -2136,6 +2568,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
hdr->nlmsg_len += RTA_ALIGN(rthdr->rta_len);
if (hdr->nlmsg_len > sizeof(request))
{
+ this->mutex->unlock(this->mutex);
return FAILED;
}
@@ -2144,15 +2577,29 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
mrk->m = mark.mask;
}
- route = to_delete->route;
- free(to_delete);
+ if (current->route)
+ {
+ route_entry_t *route = current->route;
+ if (hydra->kernel_interface->del_route(hydra->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);
+ }
+ }
+
+ this->policies->remove(this->policies, current);
+ policy_entry_destroy(this, current);
+ this->mutex->unlock(this->mutex);
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
{
if (mark.value)
{
DBG1(DBG_KNL, "unable to delete policy %R === %R %N "
- "(mark %u/0x%8x)", src_ts, dst_ts, policy_dir_names,
+ "(mark %u/0x%8x)", src_ts, dst_ts, policy_dir_names,
direction, mark.value, mark.mask);
}
else
@@ -2162,22 +2609,36 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
}
return FAILED;
}
+ return SUCCESS;
+}
+
+METHOD(kernel_ipsec_t, flush_policies, status_t,
+ private_kernel_netlink_ipsec_t *this)
+{
+ netlink_buf_t request;
+ struct nlmsghdr *hdr;
+
+ memset(&request, 0, sizeof(request));
- if (route)
+ DBG2(DBG_KNL, "flushing all policies from SPD");
+
+ hdr = (struct nlmsghdr*)request;
+ hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+ hdr->nlmsg_type = XFRM_MSG_FLUSHPOLICY;
+ hdr->nlmsg_len = NLMSG_LENGTH(0); /* no data associated */
+
+ /* by adding an rtattr of type XFRMA_POLICY_TYPE we could restrict this
+ * to main or sub policies (default is main) */
+
+ if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
{
- if (hydra->kernel_interface->del_route(hydra->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);
+ DBG1(DBG_KNL, "unable to flush SPD entries");
+ return FAILED;
}
return SUCCESS;
}
+
METHOD(kernel_ipsec_t, bypass_socket, bool,
private_kernel_netlink_ipsec_t *this, int fd, int family)
{
@@ -2206,14 +2667,14 @@ METHOD(kernel_ipsec_t, bypass_socket, bool,
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
{
DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
- strerror(errno));
+ 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));
+ strerror(errno));
return FALSE;
}
return TRUE;
@@ -2237,10 +2698,11 @@ METHOD(kernel_ipsec_t, destroy, void,
enumerator = this->policies->create_enumerator(this->policies);
while (enumerator->enumerate(enumerator, &policy, &policy))
{
- free(policy);
+ policy_entry_destroy(this, policy);
}
enumerator->destroy(enumerator);
this->policies->destroy(this->policies);
+ this->sas->destroy(this->sas);
this->mutex->destroy(this->mutex);
free(this);
}
@@ -2263,16 +2725,21 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
.update_sa = _update_sa,
.query_sa = _query_sa,
.del_sa = _del_sa,
+ .flush_sas = _flush_sas,
.add_policy = _add_policy,
.query_policy = _query_policy,
.del_policy = _del_policy,
+ .flush_policies = _flush_policies,
.bypass_socket = _bypass_socket,
.destroy = _destroy,
},
},
.policies = hashtable_create((hashtable_hash_t)policy_hash,
(hashtable_equals_t)policy_equals, 32),
+ .sas = hashtable_create((hashtable_hash_t)ipsec_sa_hash,
+ (hashtable_equals_t)ipsec_sa_equals, 32),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .policy_history = TRUE,
.install_routes = lib->settings->get_bool(lib->settings,
"%s.install_routes", TRUE, hydra->daemon),
.replay_window = lib->settings->get_int(lib->settings,
@@ -2285,6 +2752,8 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
if (streq(hydra->daemon, "pluto"))
{ /* no routes for pluto, they are installed via updown script */
this->install_routes = FALSE;
+ /* no policy history for pluto */
+ this->policy_history = FALSE;
}
/* disable lifetimes for allocated SPIs in kernel */
@@ -2321,8 +2790,8 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
destroy(this);
return NULL;
}
- this->job = callback_job_create((callback_job_cb_t)receive_events,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive_events,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
index 8315ed310..cce0ff402 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c
@@ -193,16 +193,16 @@ struct private_kernel_netlink_net_t {
*/
static int get_vip_refcount(private_kernel_netlink_net_t *this, host_t* ip)
{
- iterator_t *ifaces, *addrs;
+ enumerator_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))
+ ifaces = this->ifaces->create_enumerator(this->ifaces);
+ while (ifaces->enumerate(ifaces, (void**)&iface))
{
- addrs = iface->addrs->create_iterator(iface->addrs, TRUE);
- while (addrs->iterate(addrs, (void**)&addr))
+ addrs = iface->addrs->create_enumerator(iface->addrs);
+ while (addrs->enumerate(addrs, (void**)&addr))
{
if (addr->virtual && (iface->flags & IFF_UP) &&
ip->ip_equals(ip, addr->ip))
@@ -375,9 +375,13 @@ static void process_link(private_kernel_netlink_net_t *this,
{
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;
+ if (event)
+ {
+ update = TRUE;
+ DBG1(DBG_KNL, "interface %s deleted", current->ifname);
+ }
+ this->ifaces->remove_at(this->ifaces, enumerator);
+ iface_entry_destroy(current);
break;
}
}
@@ -904,7 +908,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
struct rtattr *rta;
size_t rtasize;
chunk_t rta_gtw, rta_src, rta_dst;
- u_int32_t rta_oif = 0;
+ u_int32_t rta_oif = 0, rta_table;
host_t *new_src, *new_gtw;
bool cont = FALSE;
uintptr_t table;
@@ -913,6 +917,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
msg = (struct rtmsg*)(NLMSG_DATA(current));
rta = RTM_RTA(msg);
rtasize = RTM_PAYLOAD(current);
+ rta_table = msg->rtm_table;
while (RTA_OK(rta, rtasize))
{
switch (rta->rta_type)
@@ -932,6 +937,14 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
rta_oif = *(u_int32_t*)RTA_DATA(rta);
}
break;
+#ifdef HAVE_RTA_TABLE
+ case RTA_TABLE:
+ if (RTA_PAYLOAD(rta) == sizeof(rta_table))
+ {
+ rta_table = *(u_int32_t*)RTA_DATA(rta);
+ }
+ break;
+#endif /* HAVE_RTA_TABLE*/
}
rta = RTA_NEXT(rta, rtasize);
}
@@ -942,7 +955,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
enumerator = this->rt_exclude->create_enumerator(this->rt_exclude);
while (enumerator->enumerate(enumerator, &table))
{
- if (table == msg->rtm_table)
+ if (table == rta_table)
{
cont = TRUE;
break;
@@ -954,7 +967,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest,
continue;
}
if (this->routing_table != 0 &&
- msg->rtm_table == this->routing_table)
+ rta_table == this->routing_table)
{ /* route is from our own ipsec routing table */
continue;
}
@@ -1529,7 +1542,7 @@ kernel_netlink_net_t *kernel_netlink_net_create()
return NULL;
}
addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR |
- RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_ROUTE | RTMGRP_LINK;
+ RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_LINK;
if (bind(this->socket_events, (struct sockaddr*)&addr, sizeof(addr)))
{
DBG1(DBG_KNL, "unable to bind RT event socket");
@@ -1537,8 +1550,8 @@ kernel_netlink_net_t *kernel_netlink_net_create()
return NULL;
}
- this->job = callback_job_create((callback_job_cb_t)receive_events,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive_events,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
if (init_address_list(this) != SUCCESS)
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_plugin.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_plugin.c
index 779466472..0eb00dadf 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_plugin.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_plugin.c
@@ -39,13 +39,22 @@ METHOD(plugin_t, get_name, char*,
return "kernel-netlink";
}
+METHOD(plugin_t, get_features, int,
+ private_kernel_netlink_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(kernel_ipsec_register, kernel_netlink_ipsec_create),
+ PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"),
+ PLUGIN_CALLBACK(kernel_net_register, kernel_netlink_net_create),
+ PLUGIN_PROVIDE(CUSTOM, "kernel-net"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_kernel_netlink_plugin_t *this)
{
- hydra->kernel_interface->remove_ipsec_interface(hydra->kernel_interface,
- (kernel_ipsec_constructor_t)kernel_netlink_ipsec_create);
- hydra->kernel_interface->remove_net_interface(hydra->kernel_interface,
- (kernel_net_constructor_t)kernel_netlink_net_create);
free(this);
}
@@ -60,15 +69,11 @@ plugin_t *kernel_netlink_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- hydra->kernel_interface->add_ipsec_interface(hydra->kernel_interface,
- (kernel_ipsec_constructor_t)kernel_netlink_ipsec_create);
- hydra->kernel_interface->add_net_interface(hydra->kernel_interface,
- (kernel_net_constructor_t)kernel_netlink_net_create);
return &this->public.plugin;
}
diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c
index c26fd2e51..dad3fb68e 100644
--- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c
+++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c
@@ -61,11 +61,9 @@ struct private_netlink_socket_t {
*/
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)
+METHOD(netlink_socket_t, netlink_send, status_t,
+ private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out,
+ size_t *out_len)
{
int len, addr_len;
struct sockaddr_nl addr;
@@ -182,10 +180,8 @@ static status_t netlink_send(private_netlink_socket_t *this, struct nlmsghdr *in
return SUCCESS;
}
-/**
- * Implementation of netlink_socket_t.send_ack.
- */
-static status_t netlink_send_ack(private_netlink_socket_t *this, struct nlmsghdr *in)
+METHOD(netlink_socket_t, netlink_send_ack, status_t,
+ private_netlink_socket_t *this, struct nlmsghdr *in)
{
struct nlmsghdr *out, *hdr;
size_t len;
@@ -231,10 +227,8 @@ static status_t netlink_send_ack(private_netlink_socket_t *this, struct nlmsghdr
return FAILED;
}
-/**
- * Implementation of netlink_socket_t.destroy.
- */
-static void destroy(private_netlink_socket_t *this)
+METHOD(netlink_socket_t, destroy, void,
+ private_netlink_socket_t *this)
{
if (this->socket > 0)
{
@@ -249,22 +243,23 @@ static void destroy(private_netlink_socket_t *this)
*/
netlink_socket_t *netlink_socket_create(int protocol)
{
- private_netlink_socket_t *this = malloc_thing(private_netlink_socket_t);
+ private_netlink_socket_t *this;
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);
+ INIT(this,
+ .public = {
+ .send = _netlink_send,
+ .send_ack = _netlink_send_ack,
+ .destroy = _destroy,
+ },
+ .seq = 200,
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .protocol = protocol,
+ );
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)
{
diff --git a/src/libhydra/plugins/kernel_pfkey/Makefile.in b/src/libhydra/plugins/kernel_pfkey/Makefile.in
index 251483017..14c924b6f 100644
--- a/src/libhydra/plugins/kernel_pfkey/Makefile.in
+++ b/src/libhydra/plugins/kernel_pfkey/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index b252b7092..da10edffe 100644
--- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2010 Tobias Brunner
+ * Copyright (C) 2008-2011 Tobias Brunner
* Copyright (C) 2008 Andreas Steffen
* Hochschule fuer Technik Rapperswil
*
@@ -58,6 +58,7 @@
#include <debug.h>
#include <utils/host.h>
#include <utils/linked_list.h>
+#include <utils/hashtable.h>
#include <threading/thread.h>
#include <threading/mutex.h>
#include <processing/jobs/callback_job.h>
@@ -99,8 +100,7 @@
#endif
/** default priority of installed policies */
-#define PRIO_LOW 1024
-#define PRIO_HIGH 512
+#define PRIO_BASE 512
#ifdef __APPLE__
/** from xnu/bsd/net/pfkeyv2.h */
@@ -163,6 +163,11 @@ struct private_kernel_pfkey_ipsec_t
linked_list_t *policies;
/**
+ * Hash table of IPsec SAs using policies (ipsec_sa_t)
+ */
+ hashtable_t *sas;
+
+ /**
* whether to install routes along policies
*/
bool install_routes;
@@ -199,19 +204,19 @@ typedef struct route_entry_t route_entry_t;
* installed routing entry
*/
struct route_entry_t {
- /** Name of the interface the route is bound to */
+ /** name of the interface the route is bound to */
char *if_name;
- /** Source ip of the route */
+ /** source ip of the route */
host_t *src_ip;
/** gateway for this route */
host_t *gateway;
- /** Destination net */
+ /** destination net */
chunk_t dst_net;
- /** Destination net prefixlen */
+ /** destination net prefixlen */
u_int8_t prefixlen;
};
@@ -227,57 +232,222 @@ static void route_entry_destroy(route_entry_t *this)
free(this);
}
+/**
+ * compare two route_entry_t objects
+ */
+static bool route_entry_equals(route_entry_t *a, route_entry_t *b)
+{
+ return a->if_name && b->if_name && streq(a->if_name, b->if_name) &&
+ a->src_ip->equals(a->src_ip, b->src_ip) &&
+ a->gateway->equals(a->gateway, b->gateway) &&
+ chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen;
+}
+
+typedef struct ipsec_sa_t ipsec_sa_t;
+
+/**
+ * IPsec SA assigned to a policy.
+ */
+struct ipsec_sa_t {
+ /** Source address of this SA */
+ host_t *src;
+
+ /** Destination address of this SA */
+ host_t *dst;
+
+ /** Description of this SA */
+ ipsec_sa_cfg_t cfg;
+
+ /** Reference count for this SA */
+ refcount_t refcount;
+};
+
+/**
+ * Hash function for ipsec_sa_t objects
+ */
+static u_int ipsec_sa_hash(ipsec_sa_t *sa)
+{
+ return chunk_hash_inc(sa->src->get_address(sa->src),
+ chunk_hash_inc(sa->dst->get_address(sa->dst),
+ chunk_hash(chunk_from_thing(sa->cfg))));
+}
+
+/**
+ * Equality function for ipsec_sa_t objects
+ */
+static bool ipsec_sa_equals(ipsec_sa_t *sa, ipsec_sa_t *other_sa)
+{
+ return sa->src->ip_equals(sa->src, other_sa->src) &&
+ sa->dst->ip_equals(sa->dst, other_sa->dst) &&
+ memeq(&sa->cfg, &other_sa->cfg, sizeof(ipsec_sa_cfg_t));
+}
+
+/**
+ * Allocate or reference an IPsec SA object
+ */
+static ipsec_sa_t *ipsec_sa_create(private_kernel_pfkey_ipsec_t *this,
+ host_t *src, host_t *dst,
+ ipsec_sa_cfg_t *cfg)
+{
+ ipsec_sa_t *sa, *found;
+ INIT(sa,
+ .src = src,
+ .dst = dst,
+ .cfg = *cfg,
+ );
+ found = this->sas->get(this->sas, sa);
+ if (!found)
+ {
+ sa->src = src->clone(src);
+ sa->dst = dst->clone(dst);
+ this->sas->put(this->sas, sa, sa);
+ }
+ else
+ {
+ free(sa);
+ sa = found;
+ }
+ ref_get(&sa->refcount);
+ return sa;
+}
+
+/**
+ * Release and destroy an IPsec SA object
+ */
+static void ipsec_sa_destroy(private_kernel_pfkey_ipsec_t *this,
+ ipsec_sa_t *sa)
+{
+ if (ref_put(&sa->refcount))
+ {
+ this->sas->remove(this->sas, sa);
+ DESTROY_IF(sa->src);
+ DESTROY_IF(sa->dst);
+ free(sa);
+ }
+}
+
+typedef struct policy_sa_t policy_sa_t;
+typedef struct policy_sa_fwd_t policy_sa_fwd_t;
+
+/**
+ * Mapping between a policy and an IPsec SA.
+ */
+struct policy_sa_t {
+ /** Priority assigned to the policy when installed with this SA */
+ u_int32_t priority;
+
+ /** Type of the policy */
+ policy_type_t type;
+
+ /** Assigned SA */
+ ipsec_sa_t *sa;
+};
+
+/**
+ * For forward policies we also cache the traffic selectors in order to install
+ * the route.
+ */
+struct policy_sa_fwd_t {
+ /** Generic interface */
+ policy_sa_t generic;
+
+ /** Source traffic selector of this policy */
+ traffic_selector_t *src_ts;
+
+ /** Destination traffic selector of this policy */
+ traffic_selector_t *dst_ts;
+};
+
+/**
+ * Create a policy_sa(_fwd)_t object
+ */
+static policy_sa_t *policy_sa_create(private_kernel_pfkey_ipsec_t *this,
+ policy_dir_t dir, policy_type_t type, host_t *src, host_t *dst,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts, ipsec_sa_cfg_t *cfg)
+{
+ policy_sa_t *policy;
+
+ if (dir == POLICY_FWD)
+ {
+ policy_sa_fwd_t *fwd;
+ INIT(fwd,
+ .src_ts = src_ts->clone(src_ts),
+ .dst_ts = dst_ts->clone(dst_ts),
+ );
+ policy = &fwd->generic;
+ }
+ else
+ {
+ INIT(policy, .priority = 0);
+ }
+ policy->type = type;
+ policy->sa = ipsec_sa_create(this, src, dst, cfg);
+ return policy;
+}
+
+/**
+ * Destroy a policy_sa(_fwd)_t object
+ */
+static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir,
+ private_kernel_pfkey_ipsec_t *this)
+{
+ if (*dir == POLICY_FWD)
+ {
+ policy_sa_fwd_t *fwd = (policy_sa_fwd_t*)policy;
+ fwd->src_ts->destroy(fwd->src_ts);
+ fwd->dst_ts->destroy(fwd->dst_ts);
+ }
+ ipsec_sa_destroy(this, policy->sa);
+ free(policy);
+}
+
typedef struct policy_entry_t policy_entry_t;
/**
* installed kernel policy.
*/
struct policy_entry_t {
-
- /** reqid of this policy */
- u_int32_t reqid;
-
- /** index assigned by the kernel */
+ /** Index assigned by the kernel */
u_int32_t index;
- /** direction of this policy: in, out, forward */
+ /** Direction of this policy: in, out, forward */
u_int8_t direction;
- /** parameters of installed policy */
+ /** Parameters of installed policy */
struct {
- /** subnet and port */
+ /** Subnet and port */
host_t *net;
- /** subnet mask */
+ /** Subnet mask */
u_int8_t mask;
- /** protocol */
+ /** Protocol */
u_int8_t proto;
} src, dst;
- /** associated route installed for this policy */
+ /** Associated route installed for this policy */
route_entry_t *route;
- /** by how many CHILD_SA's this policy is used */
- u_int refcount;
+ /** List of SAs this policy is used by, ordered by priority */
+ linked_list_t *used_by;
};
/**
- * create a policy_entry_t object
+ * 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)
+ traffic_selector_t *dst_ts,
+ policy_dir_t dir)
{
- policy_entry_t *policy = malloc_thing(policy_entry_t);
- policy->reqid = reqid;
- policy->index = 0;
- policy->direction = dir;
- policy->route = NULL;
- policy->refcount = 0;
+ policy_entry_t *policy;
+ INIT(policy,
+ .direction = dir,
+ );
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 = 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;
@@ -285,23 +455,32 @@ static policy_entry_t *create_policy_entry(traffic_selector_t *src_ts,
}
/**
- * destroy a policy_entry_t object
+ * Destroy a policy_entry_t object
*/
-static void policy_entry_destroy(policy_entry_t *this)
+static void policy_entry_destroy(policy_entry_t *policy,
+ private_kernel_pfkey_ipsec_t *this)
{
- DESTROY_IF(this->src.net);
- DESTROY_IF(this->dst.net);
- if (this->route)
+ if (policy->route)
{
- route_entry_destroy(this->route);
+ route_entry_destroy(policy->route);
}
- free(this);
+ if (policy->used_by)
+ {
+ policy->used_by->invoke_function(policy->used_by,
+ (linked_list_invoke_t)policy_sa_destroy,
+ &policy->direction, this);
+ policy->used_by->destroy(policy->used_by);
+ }
+ DESTROY_IF(policy->src.net);
+ DESTROY_IF(policy->dst.net);
+ free(policy);
}
/**
* compares two policy_entry_t
*/
-static inline bool policy_entry_equals(policy_entry_t *current, policy_entry_t *policy)
+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 &&
@@ -315,11 +494,41 @@ static inline bool policy_entry_equals(policy_entry_t *current, policy_entry_t *
/**
* 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)
+static inline bool policy_entry_match_byindex(policy_entry_t *current,
+ u_int32_t *index)
{
return current->index == *index;
}
+/**
+ * Calculate the priority of a policy
+ */
+static inline u_int32_t get_priority(policy_entry_t *policy,
+ policy_priority_t prio)
+{
+ u_int32_t priority = PRIO_BASE;
+ switch (prio)
+ {
+ case POLICY_PRIORITY_FALLBACK:
+ priority <<= 1;
+ /* fall-through */
+ case POLICY_PRIORITY_ROUTED:
+ priority <<= 1;
+ /* fall-through */
+ case POLICY_PRIORITY_DEFAULT:
+ break;
+ }
+ /* calculate priority based on selector size, small size = high prio */
+ priority -= policy->src.mask;
+ priority -= policy->dst.mask;
+ priority <<= 2; /* make some room for the two flags */
+ priority += policy->src.net->get_port(policy->src.net) ||
+ policy->dst.net->get_port(policy->dst.net) ?
+ 0 : 2;
+ priority += policy->src.proto != IPSEC_PROTO_ANY ? 0 : 1;
+ return priority;
+}
+
typedef struct pfkey_msg_t pfkey_msg_t;
struct pfkey_msg_t
@@ -470,6 +679,23 @@ static u_int8_t dir2kernel(policy_dir_t dir)
}
}
+/**
+ * convert the policy type to the one defined in ipsec.h
+ */
+static inline u_int16_t type2kernel(policy_type_t type)
+{
+ switch (type)
+ {
+ case POLICY_IPSEC:
+ return IPSEC_POLICY_IPSEC;
+ case POLICY_PASS:
+ return IPSEC_POLICY_NONE;
+ case POLICY_DROP:
+ return IPSEC_POLICY_DISCARD;
+ }
+ return type;
+}
+
#ifdef SADB_X_MIGRATE
/**
* convert the policy direction in ipsec.h to the general one.
@@ -665,19 +891,19 @@ static void add_encap_ext(struct sadb_msg *msg, host_t *src, host_t *dst)
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_len = PFKEY_LEN(sizeof(*nat_type));
nat_type->sadb_x_nat_t_type_type = UDP_ENCAP_ESPINUDP;
PFKEY_EXT_ADD(msg, nat_type);
nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg);
nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT;
- nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port));
+ nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(*nat_port));
nat_port->sadb_x_nat_t_port_port = htons(src->get_port(src));
PFKEY_EXT_ADD(msg, nat_port);
nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg);
nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT;
- nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port));
+ nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(*nat_port));
nat_port->sadb_x_nat_t_port_port = htons(dst->get_port(dst));
PFKEY_EXT_ADD(msg, nat_port);
}
@@ -694,9 +920,11 @@ static traffic_selector_t* sadb_address2ts(struct sadb_address *address)
/* 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));
+ 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;
}
@@ -729,7 +957,8 @@ static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out)
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);
+ DBG1(DBG_KNL, "type of PF_KEY extension (%d) is invalid",
+ ext->sadb_ext_type);
break;
}
@@ -784,7 +1013,8 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket
continue;
}
this->mutex_pfkey->unlock(this->mutex_pfkey);
- DBG1(DBG_KNL, "error sending to PF_KEY socket: %s", strerror(errno));
+ DBG1(DBG_KNL, "error sending to PF_KEY socket: %s",
+ strerror(errno));
return FAILED;
}
break;
@@ -804,7 +1034,8 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket
/* interrupted, try again */
continue;
}
- DBG1(DBG_KNL, "error reading from PF_KEY socket: %s", strerror(errno));
+ DBG1(DBG_KNL, "error reading from PF_KEY socket: %s",
+ strerror(errno));
this->mutex_pfkey->unlock(this->mutex_pfkey);
return FAILED;
}
@@ -817,7 +1048,8 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket
}
if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT)
{
- DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message");
+ DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY "
+ "message");
this->mutex_pfkey->unlock(this->mutex_pfkey);
return FAILED;
}
@@ -829,7 +1061,8 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket
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);
+ "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
@@ -849,8 +1082,8 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket
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);
+ "was %d expected %d, ignoring", msg->sadb_msg_type,
+ in->sadb_msg_type);
}
break;
}
@@ -860,7 +1093,6 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket
memcpy(*out, buf, len);
this->mutex_pfkey->unlock(this->mutex_pfkey);
-
return SUCCESS;
}
@@ -868,7 +1100,8 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket
* 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)
+ struct sadb_msg *in, struct sadb_msg **out,
+ size_t *out_len)
{
return pfkey_send_socket(this, this->socket, in, out, out_len);
}
@@ -876,12 +1109,14 @@ static status_t pfkey_send(private_kernel_pfkey_ipsec_t *this,
/**
* Process a SADB_ACQUIRE message from the kernel
*/
-static void process_acquire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
+static void process_acquire(private_kernel_pfkey_ipsec_t *this,
+ struct sadb_msg* msg)
{
pfkey_msg_t response;
u_int32_t index, reqid = 0;
traffic_selector_t *src_ts, *dst_ts;
policy_entry_t *policy;
+ policy_sa_t *sa;
switch (msg->sadb_msg_satype)
{
@@ -904,18 +1139,21 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
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)
+ (linked_list_match_t)policy_entry_match_byindex,
+ (void**)&policy, &index) == SUCCESS &&
+ policy->used_by->get_first(policy->used_by, (void**)&sa) == SUCCESS)
{
- reqid = policy->reqid;
+ reqid = sa->sa->cfg.reqid;
}
else
{
- DBG1(DBG_KNL, "received an SADB_ACQUIRE with policy id %d but no"
- " matching policy found", index);
+ DBG1(DBG_KNL, "received an SADB_ACQUIRE with policy id %d but no "
+ "matching policy found", index);
}
+ this->mutex->unlock(this->mutex);
+
src_ts = sadb_address2ts(response.src);
dst_ts = sadb_address2ts(response.dst);
- this->mutex->unlock(this->mutex);
hydra->kernel_interface->acquire(hydra->kernel_interface, reqid, src_ts,
dst_ts);
@@ -924,7 +1162,8 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
/**
* Process a SADB_EXPIRE message from the kernel
*/
-static void process_expire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
+static void process_expire(private_kernel_pfkey_ipsec_t *this,
+ struct sadb_msg* msg)
{
pfkey_msg_t response;
u_int8_t protocol;
@@ -946,8 +1185,8 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
if (protocol != IPPROTO_ESP && protocol != IPPROTO_AH)
{
- DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and reqid {%u} "
- "which is not a CHILD_SA", ntohl(spi), reqid);
+ DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and "
+ "reqid {%u} which is not a CHILD_SA", ntohl(spi), reqid);
return;
}
@@ -959,7 +1198,8 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
/**
* Process a SADB_X_MIGRATE message from the kernel
*/
-static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg)
+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;
@@ -1014,10 +1254,12 @@ static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
/**
* 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)
+static void process_mapping(private_kernel_pfkey_ipsec_t *this,
+ struct sadb_msg* msg)
{
pfkey_msg_t response;
u_int32_t spi, reqid;
+ sockaddr_t *sa;
host_t *host;
DBG2(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING");
@@ -1038,30 +1280,33 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this, struct sadb_msg*
spi = response.sa->sadb_sa_spi;
reqid = response.x_sa2->sadb_x_sa2_reqid;
- if (satype2proto(msg->sadb_msg_satype) == IPPROTO_ESP)
+ if (satype2proto(msg->sadb_msg_satype) != IPPROTO_ESP)
+ {
+ return;
+ }
+
+ sa = (sockaddr_t*)(response.dst + 1);
+ switch (sa->sa_family)
{
- sockaddr_t *sa = (sockaddr_t*)(response.dst + 1);
- switch (sa->sa_family)
+ case AF_INET:
{
- 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;
+ struct sockaddr_in *sin = (struct sockaddr_in*)sa;
+ sin->sin_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port);
}
- host = host_create_from_sockaddr(sa);
- if (host)
+ case AF_INET6:
{
- hydra->kernel_interface->mapping(hydra->kernel_interface, reqid,
- spi, host);
+ 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)
+ {
+ hydra->kernel_interface->mapping(hydra->kernel_interface, reqid,
+ spi, host);
}
}
#endif /*SADB_X_NAT_T_NEW_MAPPING*/
@@ -1073,8 +1318,8 @@ 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;
+ int len;
oldstate = thread_cancelability(TRUE);
len = recvfrom(this->socket_events, buf, sizeof(buf), 0, NULL, 0);
@@ -1109,7 +1354,8 @@ static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this)
}
if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT)
{
- DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message");
+ DBG1(DBG_KNL, "buffer was too small to receive the complete "
+ "PF_KEY message");
return JOB_REQUEUE_DIRECT;
}
@@ -1179,7 +1425,7 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
if (out->sadb_msg_errno)
{
DBG1(DBG_KNL, "allocating SPI failed: %s (%d)",
- strerror(out->sadb_msg_errno), out->sadb_msg_errno);
+ strerror(out->sadb_msg_errno), out->sadb_msg_errno);
}
else if (parse_pfkey_message(out, &response) == SUCCESS)
{
@@ -1222,7 +1468,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
memset(&request, 0, sizeof(request));
- DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}", ntohl(spi), reqid);
+ 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;
@@ -1287,11 +1534,11 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
if (!sa->sadb_sa_encrypt)
{
DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- encryption_algorithm_names, enc_alg);
+ 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);
+ 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;
@@ -1307,11 +1554,11 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
if (!sa->sadb_sa_auth)
{
DBG1(DBG_KNL, "algorithm %N not supported by kernel!",
- integrity_algorithm_names, int_alg);
+ 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);
+ 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;
@@ -1368,8 +1615,8 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
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));
+ DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x: address "
+ "changes are not supported", ntohl(spi));
return NOT_SUPPORTED;
}
@@ -1396,27 +1643,27 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
if (pfkey_send(this, msg, &out, &len) != SUCCESS)
{
- DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x",
- ntohl(spi));
+ 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);
+ 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));
+ 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);
+ ntohl(spi), src, dst, new_src, new_dst);
memset(&request, 0, sizeof(request));
@@ -1476,7 +1723,8 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
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);
+ ntohl(spi), strerror(out->sadb_msg_errno),
+ out->sadb_msg_errno);
free(out);
return FAILED;
}
@@ -1525,7 +1773,8 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
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);
+ ntohl(spi), strerror(out->sadb_msg_errno),
+ out->sadb_msg_errno);
free(out);
return FAILED;
}
@@ -1580,7 +1829,8 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
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);
+ ntohl(spi), strerror(out->sadb_msg_errno),
+ out->sadb_msg_errno);
free(out);
return FAILED;
}
@@ -1590,57 +1840,60 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
return SUCCESS;
}
-METHOD(kernel_ipsec_t, add_policy, status_t,
- private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
- policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
- mark_t mark, bool routed)
+METHOD(kernel_ipsec_t, flush_sas, status_t,
+ private_kernel_pfkey_ipsec_t *this)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
- struct 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;
- }
+ memset(&request, 0, sizeof(request));
- /* create a policy */
- policy = create_policy_entry(src_ts, dst_ts, direction, sa->reqid);
+ DBG2(DBG_KNL, "flushing all SAD entries");
- /* 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)
+ msg = (struct sadb_msg*)request;
+ msg->sadb_msg_version = PF_KEY_V2;
+ msg->sadb_msg_type = SADB_FLUSH;
+ msg->sadb_msg_satype = SADB_SATYPE_UNSPEC;
+ msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
+
+ if (pfkey_send(this, msg, &out, &len) != SUCCESS)
{
- /* 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;
+ DBG1(DBG_KNL, "unable to flush SAD entries");
+ return FAILED;
}
- else
+ else if (out->sadb_msg_errno)
{
- /* apply the new one, if we have no such policy */
- this->policies->insert_last(this->policies, policy);
- policy->refcount = 1;
+ DBG1(DBG_KNL, "unable to flush SAD entries: %s (%d)",
+ strerror(out->sadb_msg_errno), out->sadb_msg_errno);
+ free(out);
+ return FAILED;
}
+ free(out);
+ return SUCCESS;
+}
- memset(&request, 0, sizeof(request));
+/**
+ * Add or update a policy in the kernel.
+ *
+ * Note: The mutex has to be locked when entering this function.
+ */
+static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this,
+ policy_entry_t *policy, policy_sa_t *mapping, bool update)
+{
+ unsigned char request[PFKEY_BUFFER_SIZE];
+ struct sadb_msg *msg, *out;
+ struct sadb_x_policy *pol;
+ struct sadb_x_ipsecrequest *req;
+ ipsec_sa_t *ipsec = mapping->sa;
+ pfkey_msg_t response;
+ size_t len;
- 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;
msg->sadb_msg_version = PF_KEY_V2;
- msg->sadb_msg_type = found ? SADB_X_SPDUPDATE : SADB_X_SPDADD;
+ msg->sadb_msg_type = update ? SADB_X_SPDUPDATE : SADB_X_SPDADD;
msg->sadb_msg_satype = 0;
msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
@@ -1648,32 +1901,27 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
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;
+ pol->sadb_x_policy_dir = dir2kernel(policy->direction);
+ pol->sadb_x_policy_type = type2kernel(mapping->type);
#ifdef HAVE_STRUCT_SADB_X_POLICY_SADB_X_POLICY_PRIORITY
- /* calculate priority based on selector size, small size = high prio */
- pol->sadb_x_policy_priority = routed ? PRIO_LOW : PRIO_HIGH;
- pol->sadb_x_policy_priority -= policy->src.mask;
- pol->sadb_x_policy_priority -= policy->dst.mask;
- pol->sadb_x_policy_priority <<= 2; /* make some room for the flags */
- pol->sadb_x_policy_priority += policy->src.net->get_port(policy->src.net) ||
- policy->dst.net->get_port(policy->dst.net) ? 0 : 2;
- pol->sadb_x_policy_priority += policy->src.proto != IPSEC_PROTO_ANY ? 0 : 1;
+ pol->sadb_x_policy_priority = mapping->priority;
#endif
- /* one or more sadb_x_ipsecrequest extensions are added to the sadb_x_policy extension */
+ /* 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 = sa->esp.use ? IPPROTO_ESP : IPPROTO_AH;
- /* !!! the length of this struct MUST be in octets instead of 64 bit words */
+ req->sadb_x_ipsecrequest_proto = ipsec->cfg.esp.use ? IPPROTO_ESP
+ : IPPROTO_AH;
+ /* !!! the length here MUST be in octets instead of 64 bit words */
req->sadb_x_ipsecrequest_len = sizeof(struct sadb_x_ipsecrequest);
- req->sadb_x_ipsecrequest_mode = mode2kernel(sa->mode);
- req->sadb_x_ipsecrequest_reqid = sa->reqid;
+ req->sadb_x_ipsecrequest_mode = mode2kernel(ipsec->cfg.mode);
+ req->sadb_x_ipsecrequest_reqid = ipsec->cfg.reqid;
req->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE;
- if (sa->mode == MODE_TUNNEL)
+ if (ipsec->cfg.mode == MODE_TUNNEL)
{
- len = hostcpy(req + 1, src);
+ len = hostcpy(req + 1, ipsec->src);
req->sadb_x_ipsecrequest_len += len;
- len = hostcpy((char*)(req + 1) + len, dst);
+ len = hostcpy((char*)(req + 1) + len, ipsec->dst);
req->sadb_x_ipsecrequest_len += len;
}
@@ -1701,33 +1949,31 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
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);
+ DBG1(DBG_KNL, "unable to %s policy: %s (%d)",
+ update ? "update" : "add", strerror(out->sadb_msg_errno),
+ out->sadb_msg_errno);
free(out);
return FAILED;
}
else if (parse_pfkey_message(out, &response) != SUCCESS)
{
- DBG1(DBG_KNL, "unable to add policy %R === %R %N: parsing response "
- "from kernel failed", src_ts, dst_ts, policy_dir_names, direction);
+ DBG1(DBG_KNL, "unable to %s policy: parsing response from kernel "
+ "failed", update ? "update" : "add");
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)
+ this->mutex->lock(this->mutex);
+ 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);
+ DBG2(DBG_KNL, "unable to update index, the policy is already gone, "
+ "ignoring");
this->mutex->unlock(this->mutex);
free(out);
return SUCCESS;
@@ -1736,53 +1982,83 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
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 &&
- sa->mode != MODE_TRANSPORT && src->get_family(src) != AF_INET6 &&
- this->install_routes)
+ if (policy->direction == POLICY_FWD &&
+ ipsec->cfg.mode != MODE_TRANSPORT && this->install_routes)
{
route_entry_t *route = malloc_thing(route_entry_t);
+ policy_sa_fwd_t *fwd = (policy_sa_fwd_t*)mapping;
if (hydra->kernel_interface->get_address_by_ts(hydra->kernel_interface,
- dst_ts, &route->src_ip) == SUCCESS)
+ fwd->dst_ts, &route->src_ip) == SUCCESS)
{
/* get the nexthop to src (src as we are in POLICY_FWD).*/
route->gateway = hydra->kernel_interface->get_nexthop(
- hydra->kernel_interface, src);
+ hydra->kernel_interface, ipsec->src);
+ /* install route via outgoing interface */
route->if_name = hydra->kernel_interface->get_interface(
- hydra->kernel_interface, dst);
- route->dst_net = chunk_clone(policy->src.net->get_address(policy->src.net));
+ hydra->kernel_interface, ipsec->dst);
+ route->dst_net = chunk_clone(policy->src.net->get_address(
+ policy->src.net));
route->prefixlen = policy->src.mask;
- if (route->if_name)
+ if (!route->if_name)
{
- switch (hydra->kernel_interface->add_route(
- hydra->kernel_interface, route->dst_net,
- route->prefixlen, route->gateway,
- route->src_ip, route->if_name))
+ this->mutex->unlock(this->mutex);
+ route_entry_destroy(route);
+ return SUCCESS;
+ }
+
+ if (policy->route)
+ {
+ route_entry_t *old = policy->route;
+ if (route_entry_equals(old, route))
+ { /* keep previously installed route. since it might have
+ * still been removed by an address change, we install it
+ * again but ignore the result */
+ hydra->kernel_interface->add_route(hydra->kernel_interface,
+ route->dst_net, route->prefixlen, route->gateway,
+ route->src_ip, route->if_name);
+ this->mutex->unlock(this->mutex);
+ route_entry_destroy(route);
+ return SUCCESS;
+ }
+ /* uninstall previously installed route */
+ if (hydra->kernel_interface->del_route(hydra->kernel_interface,
+ old->dst_net, old->prefixlen, old->gateway,
+ old->src_ip, old->if_name) != SUCCESS)
{
- 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;
+ DBG1(DBG_KNL, "error uninstalling route installed with "
+ "policy %R === %R %N", fwd->src_ts,
+ fwd->dst_ts, policy_dir_names,
+ policy->direction);
}
+ route_entry_destroy(old);
+ policy->route = NULL;
}
- else
+
+ DBG2(DBG_KNL, "installing route: %R via %H src %H dev %s",
+ fwd->src_ts, route->gateway, route->src_ip, route->if_name);
+ switch (hydra->kernel_interface->add_route(
+ hydra->kernel_interface, route->dst_net,
+ route->prefixlen, route->gateway,
+ route->src_ip, route->if_name))
{
- route_entry_destroy(route);
+ 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
@@ -1790,9 +2066,82 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
free(route);
}
}
-
this->mutex->unlock(this->mutex);
+ return SUCCESS;
+}
+
+METHOD(kernel_ipsec_t, add_policy, status_t,
+ private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+ policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
+ mark_t mark, policy_priority_t priority)
+{
+ policy_entry_t *policy, *found = NULL;
+ policy_sa_t *assigned_sa, *current_sa;
+ enumerator_t *enumerator;
+ bool update = TRUE;
+
+ if (dir2kernel(direction) == IPSEC_DIR_INVALID)
+ { /* FWD policies are not supported on all platforms */
+ return SUCCESS;
+ }
+
+ /* create a policy */
+ policy = create_policy_entry(src_ts, dst_ts, direction);
+
+ /* find a matching policy */
+ this->mutex->lock(this->mutex);
+ if (this->policies->find_first(this->policies,
+ (linked_list_match_t)policy_entry_equals,
+ (void**)&found, policy) == SUCCESS)
+ { /* use existing policy */
+ DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing "
+ "refcount", src_ts, dst_ts, policy_dir_names, direction);
+ policy_entry_destroy(policy, this);
+ policy = found;
+ }
+ else
+ { /* use the new one, if we have no such policy */
+ this->policies->insert_last(this->policies, policy);
+ policy->used_by = linked_list_create();
+ }
+ /* cache the assigned IPsec SA */
+ assigned_sa = policy_sa_create(this, direction, type, src, dst, src_ts,
+ dst_ts, sa);
+ assigned_sa->priority = get_priority(policy, priority);
+
+ /* insert the SA according to its priority */
+ enumerator = policy->used_by->create_enumerator(policy->used_by);
+ while (enumerator->enumerate(enumerator, (void**)&current_sa))
+ {
+ if (current_sa->priority >= assigned_sa->priority)
+ {
+ break;
+ }
+ update = FALSE;
+ }
+ policy->used_by->insert_before(policy->used_by, enumerator, assigned_sa);
+ enumerator->destroy(enumerator);
+
+ if (!update)
+ { /* we don't update the policy if the priority is lower than that of the
+ * currently installed one */
+ this->mutex->unlock(this->mutex);
+ return SUCCESS;
+ }
+
+ DBG2(DBG_KNL, "%s policy %R === %R %N",
+ found ? "updating" : "adding", src_ts, dst_ts,
+ policy_dir_names, direction);
+
+ if (add_policy_internal(this, policy, assigned_sa, found) != SUCCESS)
+ {
+ DBG1(DBG_KNL, "unable to %s policy %R === %R %N",
+ found ? "update" : "add", src_ts, dst_ts,
+ policy_dir_names, direction);
+ return FAILED;
+ }
return SUCCESS;
}
@@ -1809,8 +2158,7 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
size_t len;
if (dir2kernel(direction) == IPSEC_DIR_INVALID)
- {
- /* FWD policies are not supported on all platforms */
+ { /* FWD policies are not supported on all platforms */
return NOT_FOUND;
}
@@ -1818,20 +2166,21 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
policy_dir_names, direction);
/* create a policy */
- policy = create_policy_entry(src_ts, dst_ts, direction, 0);
+ 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)
+ (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);
+ policy_entry_destroy(policy, this);
this->mutex->unlock(this->mutex);
return NOT_FOUND;
}
- policy_entry_destroy(policy);
+ policy_entry_destroy(policy, this);
policy = found;
memset(&request, 0, sizeof(request));
@@ -1874,17 +2223,19 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
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);
+ "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);
+ "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)
{
@@ -1896,25 +2247,26 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
*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)
+ traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+ mark_t mark, policy_priority_t prio)
{
unsigned char request[PFKEY_BUFFER_SIZE];
struct sadb_msg *msg, *out;
struct sadb_x_policy *pol;
policy_entry_t *policy, *found = NULL;
- route_entry_t *route;
+ policy_sa_t *mapping;
+ enumerator_t *enumerator;
+ bool is_installed = TRUE;
+ u_int32_t priority;
size_t len;
if (dir2kernel(direction) == IPSEC_DIR_INVALID)
- {
- /* FWD policies are not supported on all platforms */
+ { /* FWD policies are not supported on all platforms */
return SUCCESS;
}
@@ -1922,35 +2274,59 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
policy_dir_names, direction);
/* create a policy */
- policy = create_policy_entry(src_ts, dst_ts, direction, 0);
+ 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)
- {
- 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
+ (linked_list_match_t)policy_entry_equals,
+ (void**)&found, policy) != SUCCESS)
{
DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", src_ts,
dst_ts, policy_dir_names, direction);
- policy_entry_destroy(policy);
+ policy_entry_destroy(policy, this);
this->mutex->unlock(this->mutex);
return NOT_FOUND;
}
- this->mutex->unlock(this->mutex);
+ policy_entry_destroy(policy, this);
+ policy = found;
+
+ /* remove mapping to SA by reqid and priority */
+ priority = get_priority(policy, prio);
+ enumerator = policy->used_by->create_enumerator(policy->used_by);
+ while (enumerator->enumerate(enumerator, (void**)&mapping))
+ {
+ if (reqid == mapping->sa->cfg.reqid && priority == mapping->priority)
+ {
+ policy->used_by->remove_at(policy->used_by, enumerator);
+ break;
+ }
+ is_installed = FALSE;
+ }
+ enumerator->destroy(enumerator);
+
+ if (policy->used_by->get_count(policy->used_by) > 0)
+ { /* policy is used by more SAs, keep in kernel */
+ DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed");
+ policy_sa_destroy(mapping, &direction, this);
+
+ if (!is_installed)
+ { /* no need to update as the policy was not installed for this SA */
+ this->mutex->unlock(this->mutex);
+ return SUCCESS;
+ }
+
+ DBG2(DBG_KNL, "updating policy %R === %R %N", src_ts, dst_ts,
+ policy_dir_names, direction);
+ policy->used_by->get_first(policy->used_by, (void**)&mapping);
+ if (add_policy_internal(this, policy, mapping, TRUE) != SUCCESS)
+ {
+ DBG1(DBG_KNL, "unable to update policy %R === %R %N",
+ src_ts, dst_ts, policy_dir_names, direction);
+ return FAILED;
+ }
+ return SUCCESS;
+ }
memset(&request, 0, sizeof(request));
@@ -1964,7 +2340,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
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;
+ pol->sadb_x_policy_type = type2kernel(mapping->type);
PFKEY_EXT_ADD(msg, pol);
add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto,
@@ -1972,9 +2348,23 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
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 (policy->route)
+ {
+ route_entry_t *route = policy->route;
+ if (hydra->kernel_interface->del_route(hydra->kernel_interface,
+ route->dst_net, route->prefixlen, route->gateway,
+ route->src_ip, route->if_name) != SUCCESS)
+ {
+ DBG1(DBG_KNL, "error uninstalling route installed with "
+ "policy %R === %R %N", src_ts, dst_ts,
+ policy_dir_names, direction);
+ }
+ }
+
+ this->policies->remove(this->policies, found, NULL);
+ policy_sa_destroy(mapping, &direction, this);
+ policy_entry_destroy(policy, this);
+ this->mutex->unlock(this->mutex);
if (pfkey_send(this, msg, &out, &len) != SUCCESS)
{
@@ -1991,25 +2381,44 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
return FAILED;
}
free(out);
+ return SUCCESS;
+}
+
+METHOD(kernel_ipsec_t, flush_policies, status_t,
+ private_kernel_pfkey_ipsec_t *this)
+{
+ unsigned char request[PFKEY_BUFFER_SIZE];
+ struct sadb_msg *msg, *out;
+ size_t len;
+
+ memset(&request, 0, sizeof(request));
+
+ DBG2(DBG_KNL, "flushing all policies from SPD");
- if (route)
+ msg = (struct sadb_msg*)request;
+ msg->sadb_msg_version = PF_KEY_V2;
+ msg->sadb_msg_type = SADB_X_SPDFLUSH;
+ msg->sadb_msg_satype = SADB_SATYPE_UNSPEC;
+ msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg));
+
+ if (pfkey_send(this, msg, &out, &len) != SUCCESS)
{
- if (hydra->kernel_interface->del_route(hydra->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);
+ DBG1(DBG_KNL, "unable to flush SPD entries");
+ return FAILED;
}
-
+ else if (out->sadb_msg_errno)
+ {
+ DBG1(DBG_KNL, "unable to flush SPD entries: %s (%d)",
+ strerror(out->sadb_msg_errno), out->sadb_msg_errno);
+ free(out);
+ return FAILED;
+ }
+ free(out);
return SUCCESS;
}
/**
- * Register a socket for AQUIRE/EXPIRE messages
+ * Register a socket for ACQUIRE/EXPIRE messages
*/
static status_t register_pfkey_socket(private_kernel_pfkey_ipsec_t *this,
u_int8_t satype)
@@ -2075,14 +2484,14 @@ METHOD(kernel_ipsec_t, bypass_socket, bool,
if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
{
DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
- strerror(errno));
+ 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));
+ strerror(errno));
return FALSE;
}
return TRUE;
@@ -2103,7 +2512,11 @@ METHOD(kernel_ipsec_t, destroy, void,
{
close(this->socket_events);
}
- this->policies->destroy_function(this->policies, (void*)policy_entry_destroy);
+ this->policies->invoke_function(this->policies,
+ (linked_list_invoke_t)policy_entry_destroy,
+ this);
+ this->policies->destroy(this->policies);
+ this->sas->destroy(this->sas);
this->mutex->destroy(this->mutex);
this->mutex_pfkey->destroy(this->mutex_pfkey);
free(this);
@@ -2125,14 +2538,18 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
.update_sa = _update_sa,
.query_sa = _query_sa,
.del_sa = _del_sa,
+ .flush_sas = _flush_sas,
.add_policy = _add_policy,
.query_policy = _query_policy,
.del_policy = _del_policy,
+ .flush_policies = _flush_policies,
.bypass_socket = _bypass_socket,
.destroy = _destroy,
},
},
.policies = linked_list_create(),
+ .sas = hashtable_create((hashtable_hash_t)ipsec_sa_hash,
+ (hashtable_equals_t)ipsec_sa_equals, 32),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.mutex_pfkey = mutex_create(MUTEX_TYPE_DEFAULT),
.install_routes = lib->settings->get_bool(lib->settings,
@@ -2172,8 +2589,8 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
return NULL;
}
- this->job = callback_job_create((callback_job_cb_t)receive_events,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive_events,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c
index 842511181..894175402 100644
--- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c
+++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c
@@ -38,11 +38,20 @@ METHOD(plugin_t, get_name, char*,
return "kernel-pfkey";
}
+METHOD(plugin_t, get_features, int,
+ private_kernel_pfkey_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(kernel_ipsec_register, kernel_pfkey_ipsec_create),
+ PLUGIN_PROVIDE(CUSTOM, "kernel-ipsec"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_kernel_pfkey_plugin_t *this)
{
- hydra->kernel_interface->remove_ipsec_interface(hydra->kernel_interface,
- (kernel_ipsec_constructor_t)kernel_pfkey_ipsec_create);
free(this);
}
@@ -57,13 +66,11 @@ plugin_t *kernel_pfkey_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- hydra->kernel_interface->add_ipsec_interface(hydra->kernel_interface,
- (kernel_ipsec_constructor_t)kernel_pfkey_ipsec_create);
return &this->public.plugin;
}
diff --git a/src/libhydra/plugins/kernel_pfroute/Makefile.in b/src/libhydra/plugins/kernel_pfroute/Makefile.in
index b7e12561d..1412db0ec 100644
--- a/src/libhydra/plugins/kernel_pfroute/Makefile.in
+++ b/src/libhydra/plugins/kernel_pfroute/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
index fca46bfd2..5464568df 100644
--- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
+++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c
@@ -710,8 +710,8 @@ kernel_pfroute_net_t *kernel_pfroute_net_create()
return NULL;
}
- this->job = callback_job_create((callback_job_cb_t)receive_events,
- this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)receive_events,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
if (init_address_list(this) != SUCCESS)
diff --git a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_plugin.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_plugin.c
index 680caa5d0..09068b33e 100644
--- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_plugin.c
+++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_plugin.c
@@ -38,11 +38,20 @@ METHOD(plugin_t, get_name, char*,
return "kernel-pfroute";
}
+METHOD(plugin_t, get_features, int,
+ private_kernel_pfroute_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_CALLBACK(kernel_net_register, kernel_pfroute_net_create),
+ PLUGIN_PROVIDE(CUSTOM, "kernel-net"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_kernel_pfroute_plugin_t *this)
{
- hydra->kernel_interface->remove_net_interface(hydra->kernel_interface,
- (kernel_net_constructor_t)kernel_pfroute_net_create);
free(this);
}
@@ -57,13 +66,11 @@ plugin_t *kernel_pfroute_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- hydra->kernel_interface->add_net_interface(hydra->kernel_interface,
- (kernel_net_constructor_t)kernel_pfroute_net_create);
return &this->public.plugin;
}
diff --git a/src/libhydra/plugins/resolve/Makefile.in b/src/libhydra/plugins/resolve/Makefile.in
index d3cda309a..41846ffe0 100644
--- a/src/libhydra/plugins/resolve/Makefile.in
+++ b/src/libhydra/plugins/resolve/Makefile.in
@@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +205,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +222,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libhydra/plugins/resolve/resolve_handler.c b/src/libhydra/plugins/resolve/resolve_handler.c
index feb2fd05a..011ebbaaf 100644
--- a/src/libhydra/plugins/resolve/resolve_handler.c
+++ b/src/libhydra/plugins/resolve/resolve_handler.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -15,12 +16,20 @@
#include "resolve_handler.h"
+#include <sys/types.h>
+#include <sys/stat.h>
#include <unistd.h>
#include <hydra.h>
#include <debug.h>
#include <threading/mutex.h>
+/* path to resolvconf executable */
+#define RESOLVCONF_EXEC "/sbin/resolvconf"
+
+/* default prefix used for resolvconf interfaces (should have high prio) */
+#define RESOLVCONF_PREFIX "lo.inet.ipsec."
+
typedef struct private_resolve_handler_t private_resolve_handler_t;
/**
@@ -39,49 +48,40 @@ struct private_resolve_handler_t {
char *file;
/**
+ * use resolvconf instead of writing directly to resolv.conf
+ */
+ bool use_resolvconf;
+
+ /**
+ * prefix to be used for interface names sent to resolvconf
+ */
+ char *iface_prefix;
+
+ /**
* Mutex to access file exclusively
*/
mutex_t *mutex;
};
/**
- * Implementation of attribute_handler_t.handle
+ * Writes the given nameserver to resolv.conf
*/
-static bool handle(private_resolve_handler_t *this, identification_t *server,
- configuration_attribute_type_t type, chunk_t data)
+static bool write_nameserver(private_resolve_handler_t *this,
+ identification_t *server, host_t *addr)
{
FILE *in, *out;
char buf[1024];
- host_t *addr;
size_t len;
bool handled = FALSE;
- switch (type)
- {
- case INTERNAL_IP4_DNS:
- addr = host_create_from_chunk(AF_INET, data, 0);
- break;
- case INTERNAL_IP6_DNS:
- addr = host_create_from_chunk(AF_INET6, data, 0);
- break;
- default:
- return FALSE;
- }
-
- if (!addr || addr->is_anyaddr(addr))
- {
- DESTROY_IF(addr);
- return FALSE;
- }
- this->mutex->lock(this->mutex);
-
in = fopen(this->file, "r");
/* allows us to stream from in to out */
unlink(this->file);
out = fopen(this->file, "w");
if (out)
{
- fprintf(out, "nameserver %H # by strongSwan, from %Y\n", addr, server);
+ fprintf(out, "nameserver %H # by strongSwan, from %Y\n", addr,
+ server);
DBG1(DBG_IKE, "installing DNS server %H to %s", addr, this->file);
handled = TRUE;
@@ -99,40 +99,17 @@ static bool handle(private_resolve_handler_t *this, identification_t *server,
{
fclose(in);
}
- this->mutex->unlock(this->mutex);
- addr->destroy(addr);
-
- if (!handled)
- {
- DBG1(DBG_IKE, "adding DNS server failed", this->file);
- }
return handled;
}
/**
- * Implementation of attribute_handler_t.release
+ * Removes the given nameserver from resolv.conf
*/
-static void release(private_resolve_handler_t *this, identification_t *server,
- configuration_attribute_type_t type, chunk_t data)
+static void remove_nameserver(private_resolve_handler_t *this,
+ identification_t *server, host_t *addr)
{
FILE *in, *out;
char line[1024], matcher[512];
- host_t *addr;
- int family;
-
- switch (type)
- {
- case INTERNAL_IP4_DNS:
- family = AF_INET;
- break;
- case INTERNAL_IP6_DNS:
- family = AF_INET6;
- break;
- default:
- return;
- }
-
- this->mutex->lock(this->mutex);
in = fopen(this->file, "r");
if (in)
@@ -142,7 +119,6 @@ static void release(private_resolve_handler_t *this, identification_t *server,
out = fopen(this->file, "w");
if (out)
{
- addr = host_create_from_chunk(family, data, 0);
snprintf(matcher, sizeof(matcher),
"nameserver %H # by strongSwan, from %Y\n",
addr, server);
@@ -160,13 +136,129 @@ static void release(private_resolve_handler_t *this, identification_t *server,
fputs(line, out);
}
}
- addr->destroy(addr);
fclose(out);
}
fclose(in);
}
+}
+/**
+ * Add or remove the given nameserver by invoking resolvconf.
+ */
+static bool invoke_resolvconf(private_resolve_handler_t *this,
+ identification_t *server, host_t *addr,
+ bool install)
+{
+ char cmd[128];
+
+ /* we use the nameserver's IP address as part of the interface name to
+ * make them unique */
+ if (snprintf(cmd, sizeof(cmd), "%s %s %s%H", RESOLVCONF_EXEC,
+ install ? "-a" : "-d", this->iface_prefix, addr) >= sizeof(cmd))
+ {
+ return FALSE;
+ }
+
+ if (install)
+ {
+ FILE *out;
+
+ out = popen(cmd, "w");
+ if (!out)
+ {
+ return FALSE;
+ }
+ DBG1(DBG_IKE, "installing DNS server %H via resolvconf", addr);
+ fprintf(out, "nameserver %H # by strongSwan, from %Y\n", addr,
+ server);
+ if (ferror(out) || pclose(out))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ ignore_result(system(cmd));
+ }
+ return TRUE;
+}
+
+METHOD(attribute_handler_t, handle, bool,
+ private_resolve_handler_t *this, identification_t *server,
+ configuration_attribute_type_t type, chunk_t data)
+{
+ host_t *addr;
+ bool handled;
+
+ switch (type)
+ {
+ case INTERNAL_IP4_DNS:
+ addr = host_create_from_chunk(AF_INET, data, 0);
+ break;
+ case INTERNAL_IP6_DNS:
+ addr = host_create_from_chunk(AF_INET6, data, 0);
+ break;
+ default:
+ return FALSE;
+ }
+
+ if (!addr || addr->is_anyaddr(addr))
+ {
+ DESTROY_IF(addr);
+ return FALSE;
+ }
+
+ this->mutex->lock(this->mutex);
+ if (this->use_resolvconf)
+ {
+ handled = invoke_resolvconf(this, server, addr, TRUE);
+ }
+ else
+ {
+ handled = write_nameserver(this, server, addr);
+ }
this->mutex->unlock(this->mutex);
+ addr->destroy(addr);
+
+ if (!handled)
+ {
+ DBG1(DBG_IKE, "adding DNS server failed");
+ }
+ return handled;
+}
+
+METHOD(attribute_handler_t, release, void,
+ private_resolve_handler_t *this, identification_t *server,
+ configuration_attribute_type_t type, chunk_t data)
+{
+ host_t *addr;
+ int family;
+
+ switch (type)
+ {
+ case INTERNAL_IP4_DNS:
+ family = AF_INET;
+ break;
+ case INTERNAL_IP6_DNS:
+ family = AF_INET6;
+ break;
+ default:
+ return;
+ }
+ addr = host_create_from_chunk(family, data, 0);
+
+ this->mutex->lock(this->mutex);
+ if (this->use_resolvconf)
+ {
+ invoke_resolvconf(this, server, addr, FALSE);
+ }
+ else
+ {
+ remove_nameserver(this, server, addr);
+ }
+ this->mutex->unlock(this->mutex);
+
+ addr->destroy(addr);
}
/**
@@ -179,11 +271,9 @@ typedef struct {
host_t *vip;
} attribute_enumerator_t;
-/**
- * Implementation of create_attribute_enumerator().enumerate()
- */
static bool attribute_enumerate(attribute_enumerator_t *this,
- configuration_attribute_type_t *type, chunk_t *data)
+ configuration_attribute_type_t *type,
+ chunk_t *data)
{
switch (this->vip->get_family(this->vip))
{
@@ -202,11 +292,8 @@ static bool attribute_enumerate(attribute_enumerator_t *this,
return TRUE;
}
-/**
- * Implementation of attribute_handler_t.create_attribute_enumerator
- */
-static enumerator_t* create_attribute_enumerator(private_resolve_handler_t *this,
- identification_t *server, host_t *vip)
+METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
+ private_resolve_handler_t *this, identification_t *server, host_t *vip)
{
if (vip)
{
@@ -222,10 +309,8 @@ static enumerator_t* create_attribute_enumerator(private_resolve_handler_t *this
return enumerator_create_empty();
}
-/**
- * Implementation of resolve_handler_t.destroy.
- */
-static void destroy(private_resolve_handler_t *this)
+METHOD(resolve_handler_t, destroy, void,
+ private_resolve_handler_t *this)
{
this->mutex->destroy(this->mutex);
free(this);
@@ -236,16 +321,30 @@ static void destroy(private_resolve_handler_t *this)
*/
resolve_handler_t *resolve_handler_create()
{
- private_resolve_handler_t *this = malloc_thing(private_resolve_handler_t);
+ private_resolve_handler_t *this;
+ struct stat st;
- this->public.handler.handle = (bool(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))handle;
- this->public.handler.release = (void(*)(attribute_handler_t*, identification_t*, configuration_attribute_type_t, chunk_t))release;
- this->public.handler.create_attribute_enumerator = (enumerator_t*(*)(attribute_handler_t*, identification_t *server, host_t *vip))create_attribute_enumerator;
- this->public.destroy = (void(*)(resolve_handler_t*))destroy;
+ INIT(this,
+ .public = {
+ .handler = {
+ .handle = _handle,
+ .release = _release,
+ .create_attribute_enumerator = _create_attribute_enumerator,
+ },
+ .destroy = _destroy,
+ },
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .file = lib->settings->get_str(lib->settings, "%s.plugins.resolve.file",
+ RESOLV_CONF, hydra->daemon),
+ );
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
- this->file = lib->settings->get_str(lib->settings,
- "%s.plugins.resolve.file", RESOLV_CONF, hydra->daemon);
+ if (stat(RESOLVCONF_EXEC, &st) == 0)
+ {
+ this->use_resolvconf = TRUE;
+ this->iface_prefix = lib->settings->get_str(lib->settings,
+ "%s.plugins.resolve.resolvconf.iface_prefix",
+ RESOLVCONF_PREFIX, hydra->daemon);
+ }
return &this->public;
}
diff --git a/src/libhydra/plugins/resolve/resolve_plugin.c b/src/libhydra/plugins/resolve/resolve_plugin.c
index d23d36127..f95827ed9 100644
--- a/src/libhydra/plugins/resolve/resolve_plugin.c
+++ b/src/libhydra/plugins/resolve/resolve_plugin.c
@@ -31,7 +31,7 @@ struct private_resolve_plugin_t {
resolve_plugin_t public;
/**
- * The registerd DNS attribute handler
+ * The registered DNS attribute handler
*/
resolve_handler_t *handler;
};
diff --git a/src/libimcv/Makefile.am b/src/libimcv/Makefile.am
new file mode 100644
index 000000000..fae9fd662
--- /dev/null
+++ b/src/libimcv/Makefile.am
@@ -0,0 +1,38 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libtncif
+
+ipseclib_LTLIBRARIES = libimcv.la
+
+libimcv_la_LIBADD = $(top_builddir)/src/libtncif/libtncif.la
+
+libimcv_la_SOURCES = \
+ imcv.h imcv.c \
+ imc/imc_agent.h imc/imc_agent.c imc/imc_state.h \
+ imv/imv_agent.h imv/imv_agent.c imv/imv_state.h \
+ ietf/ietf_attr.h ietf/ietf_attr.c \
+ ietf/ietf_attr_pa_tnc_error.h ietf/ietf_attr_pa_tnc_error.c \
+ ietf/ietf_attr_port_filter.h ietf/ietf_attr_port_filter.c \
+ ietf/ietf_attr_product_info.h ietf/ietf_attr_product_info.c \
+ ita/ita_attr.h ita/ita_attr.c \
+ ita/ita_attr_command.h ita/ita_attr_command.c \
+ pa_tnc/pa_tnc_attr.h \
+ pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \
+ pa_tnc/pa_tnc_attr_manager.h pa_tnc/pa_tnc_attr_manager.c
+
+SUBDIRS = .
+
+if USE_IMC_TEST
+ SUBDIRS += plugins/imc_test
+endif
+
+if USE_IMV_TEST
+ SUBDIRS += plugins/imv_test
+endif
+
+if USE_IMC_SCANNER
+ SUBDIRS += plugins/imc_scanner
+endif
+
+if USE_IMV_SCANNER
+ SUBDIRS += plugins/imv_scanner
+endif
diff --git a/src/libimcv/Makefile.in b/src/libimcv/Makefile.in
new file mode 100644
index 000000000..7e90a7aca
--- /dev/null
+++ b/src/libimcv/Makefile.in
@@ -0,0 +1,845 @@
+# 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@
+@USE_IMC_TEST_TRUE@am__append_1 = plugins/imc_test
+@USE_IMV_TEST_TRUE@am__append_2 = plugins/imv_test
+@USE_IMC_SCANNER_TRUE@am__append_3 = plugins/imc_scanner
+@USE_IMV_SCANNER_TRUE@am__append_4 = plugins/imv_scanner
+subdir = src/libimcv
+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)$(ipseclibdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
+libimcv_la_DEPENDENCIES = $(top_builddir)/src/libtncif/libtncif.la
+am_libimcv_la_OBJECTS = imcv.lo imc_agent.lo imv_agent.lo ietf_attr.lo \
+ ietf_attr_pa_tnc_error.lo ietf_attr_port_filter.lo \
+ ietf_attr_product_info.lo ita_attr.lo ita_attr_command.lo \
+ pa_tnc_msg.lo pa_tnc_attr_manager.lo
+libimcv_la_OBJECTS = $(am_libimcv_la_OBJECTS)
+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 = $(libimcv_la_SOURCES)
+DIST_SOURCES = $(libimcv_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = . plugins/imc_test plugins/imv_test plugins/imc_scanner \
+ plugins/imv_scanner
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libtncif
+ipseclib_LTLIBRARIES = libimcv.la
+libimcv_la_LIBADD = $(top_builddir)/src/libtncif/libtncif.la
+libimcv_la_SOURCES = \
+ imcv.h imcv.c \
+ imc/imc_agent.h imc/imc_agent.c imc/imc_state.h \
+ imv/imv_agent.h imv/imv_agent.c imv/imv_state.h \
+ ietf/ietf_attr.h ietf/ietf_attr.c \
+ ietf/ietf_attr_pa_tnc_error.h ietf/ietf_attr_pa_tnc_error.c \
+ ietf/ietf_attr_port_filter.h ietf/ietf_attr_port_filter.c \
+ ietf/ietf_attr_product_info.h ietf/ietf_attr_product_info.c \
+ ita/ita_attr.h ita/ita_attr.c \
+ ita/ita_attr_command.h ita/ita_attr_command.c \
+ pa_tnc/pa_tnc_attr.h \
+ pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \
+ pa_tnc/pa_tnc_attr_manager.h pa_tnc/pa_tnc_attr_manager.c
+
+SUBDIRS = . $(am__append_1) $(am__append_2) $(am__append_3) \
+ $(am__append_4)
+all: all-recursive
+
+.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/libimcv/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libimcv/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):
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
+ }
+
+uninstall-ipseclibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
+ done
+
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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
+libimcv.la: $(libimcv_la_OBJECTS) $(libimcv_la_DEPENDENCIES)
+ $(LINK) -rpath $(ipseclibdir) $(libimcv_la_OBJECTS) $(libimcv_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ietf_attr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ietf_attr_pa_tnc_error.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ietf_attr_port_filter.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ietf_attr_product_info.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imc_agent.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imcv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_agent.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ita_attr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ita_attr_command.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pa_tnc_attr_manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pa_tnc_msg.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 $@ $<
+
+imc_agent.lo: imc/imc_agent.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imc_agent.lo -MD -MP -MF $(DEPDIR)/imc_agent.Tpo -c -o imc_agent.lo `test -f 'imc/imc_agent.c' || echo '$(srcdir)/'`imc/imc_agent.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/imc_agent.Tpo $(DEPDIR)/imc_agent.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='imc/imc_agent.c' object='imc_agent.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 imc_agent.lo `test -f 'imc/imc_agent.c' || echo '$(srcdir)/'`imc/imc_agent.c
+
+imv_agent.lo: imv/imv_agent.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imv_agent.lo -MD -MP -MF $(DEPDIR)/imv_agent.Tpo -c -o imv_agent.lo `test -f 'imv/imv_agent.c' || echo '$(srcdir)/'`imv/imv_agent.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/imv_agent.Tpo $(DEPDIR)/imv_agent.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='imv/imv_agent.c' object='imv_agent.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 imv_agent.lo `test -f 'imv/imv_agent.c' || echo '$(srcdir)/'`imv/imv_agent.c
+
+ietf_attr.lo: ietf/ietf_attr.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ietf_attr.lo -MD -MP -MF $(DEPDIR)/ietf_attr.Tpo -c -o ietf_attr.lo `test -f 'ietf/ietf_attr.c' || echo '$(srcdir)/'`ietf/ietf_attr.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ietf_attr.Tpo $(DEPDIR)/ietf_attr.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ietf/ietf_attr.c' object='ietf_attr.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 ietf_attr.lo `test -f 'ietf/ietf_attr.c' || echo '$(srcdir)/'`ietf/ietf_attr.c
+
+ietf_attr_pa_tnc_error.lo: ietf/ietf_attr_pa_tnc_error.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ietf_attr_pa_tnc_error.lo -MD -MP -MF $(DEPDIR)/ietf_attr_pa_tnc_error.Tpo -c -o ietf_attr_pa_tnc_error.lo `test -f 'ietf/ietf_attr_pa_tnc_error.c' || echo '$(srcdir)/'`ietf/ietf_attr_pa_tnc_error.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ietf_attr_pa_tnc_error.Tpo $(DEPDIR)/ietf_attr_pa_tnc_error.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ietf/ietf_attr_pa_tnc_error.c' object='ietf_attr_pa_tnc_error.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 ietf_attr_pa_tnc_error.lo `test -f 'ietf/ietf_attr_pa_tnc_error.c' || echo '$(srcdir)/'`ietf/ietf_attr_pa_tnc_error.c
+
+ietf_attr_port_filter.lo: ietf/ietf_attr_port_filter.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ietf_attr_port_filter.lo -MD -MP -MF $(DEPDIR)/ietf_attr_port_filter.Tpo -c -o ietf_attr_port_filter.lo `test -f 'ietf/ietf_attr_port_filter.c' || echo '$(srcdir)/'`ietf/ietf_attr_port_filter.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ietf_attr_port_filter.Tpo $(DEPDIR)/ietf_attr_port_filter.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ietf/ietf_attr_port_filter.c' object='ietf_attr_port_filter.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 ietf_attr_port_filter.lo `test -f 'ietf/ietf_attr_port_filter.c' || echo '$(srcdir)/'`ietf/ietf_attr_port_filter.c
+
+ietf_attr_product_info.lo: ietf/ietf_attr_product_info.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ietf_attr_product_info.lo -MD -MP -MF $(DEPDIR)/ietf_attr_product_info.Tpo -c -o ietf_attr_product_info.lo `test -f 'ietf/ietf_attr_product_info.c' || echo '$(srcdir)/'`ietf/ietf_attr_product_info.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ietf_attr_product_info.Tpo $(DEPDIR)/ietf_attr_product_info.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ietf/ietf_attr_product_info.c' object='ietf_attr_product_info.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 ietf_attr_product_info.lo `test -f 'ietf/ietf_attr_product_info.c' || echo '$(srcdir)/'`ietf/ietf_attr_product_info.c
+
+ita_attr.lo: ita/ita_attr.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ita_attr.lo -MD -MP -MF $(DEPDIR)/ita_attr.Tpo -c -o ita_attr.lo `test -f 'ita/ita_attr.c' || echo '$(srcdir)/'`ita/ita_attr.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ita_attr.Tpo $(DEPDIR)/ita_attr.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ita/ita_attr.c' object='ita_attr.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 ita_attr.lo `test -f 'ita/ita_attr.c' || echo '$(srcdir)/'`ita/ita_attr.c
+
+ita_attr_command.lo: ita/ita_attr_command.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ita_attr_command.lo -MD -MP -MF $(DEPDIR)/ita_attr_command.Tpo -c -o ita_attr_command.lo `test -f 'ita/ita_attr_command.c' || echo '$(srcdir)/'`ita/ita_attr_command.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ita_attr_command.Tpo $(DEPDIR)/ita_attr_command.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ita/ita_attr_command.c' object='ita_attr_command.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 ita_attr_command.lo `test -f 'ita/ita_attr_command.c' || echo '$(srcdir)/'`ita/ita_attr_command.c
+
+pa_tnc_msg.lo: pa_tnc/pa_tnc_msg.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pa_tnc_msg.lo -MD -MP -MF $(DEPDIR)/pa_tnc_msg.Tpo -c -o pa_tnc_msg.lo `test -f 'pa_tnc/pa_tnc_msg.c' || echo '$(srcdir)/'`pa_tnc/pa_tnc_msg.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pa_tnc_msg.Tpo $(DEPDIR)/pa_tnc_msg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pa_tnc/pa_tnc_msg.c' object='pa_tnc_msg.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 pa_tnc_msg.lo `test -f 'pa_tnc/pa_tnc_msg.c' || echo '$(srcdir)/'`pa_tnc/pa_tnc_msg.c
+
+pa_tnc_attr_manager.lo: pa_tnc/pa_tnc_attr_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 pa_tnc_attr_manager.lo -MD -MP -MF $(DEPDIR)/pa_tnc_attr_manager.Tpo -c -o pa_tnc_attr_manager.lo `test -f 'pa_tnc/pa_tnc_attr_manager.c' || echo '$(srcdir)/'`pa_tnc/pa_tnc_attr_manager.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pa_tnc_attr_manager.Tpo $(DEPDIR)/pa_tnc_attr_manager.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pa_tnc/pa_tnc_attr_manager.c' object='pa_tnc_attr_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 pa_tnc_attr_manager.lo `test -f 'pa_tnc/pa_tnc_attr_manager.c' || echo '$(srcdir)/'`pa_tnc/pa_tnc_attr_manager.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+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: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ 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: ctags-recursive $(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
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(ipseclibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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-recursive
+
+clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-ipseclibLTLIBRARIES
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-ipseclibLTLIBRARIES
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic \
+ clean-ipseclibLTLIBRARIES clean-libtool ctags ctags-recursive \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-ipseclibLTLIBRARIES install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-ipseclibLTLIBRARIES
+
+
+# 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/libimcv/ietf/ietf_attr.c b/src/libimcv/ietf/ietf_attr.c
new file mode 100644
index 000000000..89c6fc8db
--- /dev/null
+++ b/src/libimcv/ietf/ietf_attr.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 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 "ietf_attr.h"
+#include "ietf/ietf_attr_pa_tnc_error.h"
+#include "ietf/ietf_attr_port_filter.h"
+#include "ietf/ietf_attr_product_info.h"
+
+ENUM(ietf_attr_names, IETF_ATTR_TESTING, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED,
+ "Testing",
+ "Attribute Request",
+ "Product Information",
+ "Numeric Version",
+ "String Version",
+ "Operational Status",
+ "Port Filter",
+ "Installed Packages",
+ "PA-TNC Error",
+ "Assessment Result",
+ "Remediation Instructions",
+ "Forwarding Enabled",
+ "Factory Default Password Enabled",
+);
+
+/**
+ * See header
+ */
+pa_tnc_attr_t* ietf_attr_create_from_data(u_int32_t type, chunk_t value)
+{
+ switch (type)
+ {
+ case IETF_ATTR_PORT_FILTER:
+ return ietf_attr_port_filter_create_from_data(value);
+ case IETF_ATTR_PA_TNC_ERROR:
+ return ietf_attr_pa_tnc_error_create_from_data(value);
+ case IETF_ATTR_PRODUCT_INFORMATION:
+ return ietf_attr_product_info_create_from_data(value);
+ case IETF_ATTR_TESTING:
+ case IETF_ATTR_ATTRIBUTE_REQUEST:
+ case IETF_ATTR_NUMERIC_VERSION:
+ case IETF_ATTR_STRING_VERSION:
+ case IETF_ATTR_OPERATIONAL_STATUS:
+ case IETF_ATTR_INSTALLED_PACKAGES:
+ case IETF_ATTR_ASSESSMENT_RESULT:
+ case IETF_ATTR_REMEDIATION_INSTRUCTIONS:
+ case IETF_ATTR_FORWARDING_ENABLED:
+ case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED:
+ case IETF_ATTR_RESERVED:
+ default:
+ return NULL;
+ }
+}
diff --git a/src/libimcv/ietf/ietf_attr.h b/src/libimcv/ietf/ietf_attr.h
new file mode 100644
index 000000000..a1ba42565
--- /dev/null
+++ b/src/libimcv/ietf/ietf_attr.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 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 ietf_attrt ietf_attr
+ * @{ @ingroup ietf_attr
+ */
+
+#ifndef IETF_ATTR_H_
+#define IETF_ATTR_H_
+
+#include "pa_tnc/pa_tnc_attr.h"
+
+#include <library.h>
+
+typedef enum ietf_attr_t ietf_attr_t;
+
+/**
+ * IETF standard PA-TNC attribute types defined by RFC 5792
+ */
+enum ietf_attr_t {
+ IETF_ATTR_TESTING = 0,
+ IETF_ATTR_ATTRIBUTE_REQUEST = 1,
+ IETF_ATTR_PRODUCT_INFORMATION = 2,
+ IETF_ATTR_NUMERIC_VERSION = 3,
+ IETF_ATTR_STRING_VERSION = 4,
+ IETF_ATTR_OPERATIONAL_STATUS = 5,
+ IETF_ATTR_PORT_FILTER = 6,
+ IETF_ATTR_INSTALLED_PACKAGES = 7,
+ IETF_ATTR_PA_TNC_ERROR = 8,
+ IETF_ATTR_ASSESSMENT_RESULT = 9,
+ IETF_ATTR_REMEDIATION_INSTRUCTIONS = 10,
+ IETF_ATTR_FORWARDING_ENABLED = 11,
+ IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED = 12,
+ IETF_ATTR_RESERVED = 0xffffffff,
+};
+
+/**
+ * enum name for ietf_attr_t.
+ */
+extern enum_name_t *ietf_attr_names;
+
+/**
+ * Create an IETF PA-TNC attribute from data
+ *
+ * @param type attribute type
+ * @param value attribute value
+ */
+pa_tnc_attr_t* ietf_attr_create_from_data(u_int32_t type, chunk_t value);
+
+#endif /** IETF_ATTR_H_ @}*/
diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c
new file mode 100644
index 000000000..6daee1a77
--- /dev/null
+++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2011 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 "ietf_attr_pa_tnc_error.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+ENUM(pa_tnc_error_code_names, PA_ERROR_RESERVED,
+ PA_ERROR_ATTR_TYPE_NOT_SUPPORTED,
+ "Reserved",
+ "Invalid Parameter",
+ "Version Not Supported",
+ "Attribute Type Not Supported"
+);
+
+typedef struct private_ietf_attr_pa_tnc_error_t private_ietf_attr_pa_tnc_error_t;
+
+/**
+ * PA-TNC Error Attribute Type (see section 4.2.8 of RFC 5792)
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | PA-TNC Error Code Vendor ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | PA-TNC Error Code |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Error Information (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PA_ERROR_HEADER_SIZE 8
+#define PA_ERROR_RESERVED 0x00
+
+/**
+ * All IETF Error Types return the first 8 bytes of the erroneous PA-TNC message
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version | Copy of Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Message Identifier |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PA_ERROR_MSG_INFO_SIZE 8
+#define PA_ERROR_MSG_INFO_MAX_SIZE 1024
+
+/**
+ * "Invalid Parameter" Error Code
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Offset |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * "Version Not Supported" Error Code
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Max Version | Min Version | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PA_ERROR_VERSION_RESERVED 0x0000
+
+/**
+ * "Attribute Type Not Supported" Error Code
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | PA-TNC Attribute Vendor ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | PA-TNC Attribute Type |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PA_ERROR_ATTR_INFO_SIZE 8
+
+/**
+ * Private data of an ietf_attr_pa_tnc_error_t object.
+ */
+struct private_ietf_attr_pa_tnc_error_t {
+
+ /**
+ * Public members of ietf_attr_pa_tnc_error_t
+ */
+ ietf_attr_pa_tnc_error_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Error code vendor ID
+ */
+ pen_t error_vendor_id;
+
+ /**
+ * Error code
+ */
+ u_int32_t error_code;
+
+ /**
+ * First 8 bytes of erroneous PA-TNC message
+ */
+ chunk_t msg_info;
+
+ /**
+ * First 8 bytes of unsupported PA-TNC attribute
+ */
+ chunk_t attr_info;
+
+ /**
+ * PA-TNC error offset
+ */
+ u_int32_t error_offset;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_ietf_attr_pa_tnc_error_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ bio_writer_t *writer;
+
+ writer = bio_writer_create(PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE);
+ writer->write_uint8 (writer, PA_ERROR_RESERVED);
+ writer->write_uint24(writer, this->error_vendor_id);
+ writer->write_uint32(writer, this->error_code);
+ writer->write_data (writer, this->msg_info);
+
+ if (this->error_vendor_id == PEN_IETF)
+ {
+ switch (this->error_code)
+ {
+ case PA_ERROR_INVALID_PARAMETER:
+ writer->write_uint32(writer, this->error_offset);
+ break;
+ case PA_ERROR_VERSION_NOT_SUPPORTED:
+ writer->write_uint8 (writer, PA_TNC_VERSION);
+ writer->write_uint8 (writer, PA_TNC_VERSION);
+ writer->write_uint16(writer, PA_ERROR_VERSION_RESERVED);
+ break;
+ case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
+ writer->write_data(writer, this->attr_info);
+ break;
+ default:
+ break;
+ }
+ }
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_ietf_attr_pa_tnc_error_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t reserved;
+
+ if (this->value.len < PA_ERROR_HEADER_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PA-TNC error header");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &reserved);
+ reader->read_uint24(reader, &this->error_vendor_id);
+ reader->read_uint32(reader, &this->error_code);
+
+ if (this->error_vendor_id == PEN_IETF)
+ {
+ if (!reader->read_data(reader, PA_ERROR_MSG_INFO_SIZE, &this->msg_info))
+ {
+ reader->destroy(reader);
+ DBG1(DBG_TNC, "insufficient data for IETF error information");
+ *offset = PA_ERROR_HEADER_SIZE;
+ return FAILED;
+ }
+ this->msg_info = chunk_clone(this->msg_info);
+
+ switch (this->error_code)
+ {
+ case PA_ERROR_INVALID_PARAMETER:
+ if (!reader->read_uint32(reader, &this->error_offset))
+ {
+ reader->destroy(reader);
+ DBG1(DBG_TNC, "insufficient data for error offset field");
+ *offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE;
+ return FAILED;
+ }
+ break;
+ case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
+ if (!reader->read_data(reader, PA_ERROR_ATTR_INFO_SIZE,
+ &this->attr_info))
+ {
+ reader->destroy(reader);
+ DBG1(DBG_TNC, "insufficient data for unsupported attribute "
+ "information");
+ *offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE;
+ return FAILED;
+ }
+ this->attr_info = chunk_clone(this->attr_info);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ reader->read_data(reader, reader->remaining(reader), &this->msg_info);
+ this->msg_info = chunk_clone(this->msg_info);
+ }
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this->msg_info.ptr);
+ free(this->attr_info.ptr);
+ free(this);
+ }
+}
+
+METHOD(ietf_attr_pa_tnc_error_t, get_error_vendor_id, pen_t,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ return this->error_vendor_id;
+}
+
+METHOD(ietf_attr_pa_tnc_error_t, get_error_code, u_int32_t,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ return this->error_code;
+}
+
+METHOD(ietf_attr_pa_tnc_error_t, get_msg_info, chunk_t,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ return this->msg_info;
+}
+
+METHOD(ietf_attr_pa_tnc_error_t, get_attr_info, chunk_t,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ return this->attr_info;
+}
+
+METHOD(ietf_attr_pa_tnc_error_t, set_attr_info, void,
+ private_ietf_attr_pa_tnc_error_t *this, chunk_t attr_info)
+{
+ this->attr_info = chunk_clone(attr_info);
+}
+
+METHOD(ietf_attr_pa_tnc_error_t, get_offset, u_int32_t,
+ private_ietf_attr_pa_tnc_error_t *this)
+{
+ return this->error_offset;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ietf_attr_pa_tnc_error_create(pen_t vendor_id,
+ u_int32_t error_code,
+ chunk_t msg_info)
+{
+ private_ietf_attr_pa_tnc_error_t *this;
+
+ if (vendor_id == PEN_IETF)
+ {
+ msg_info.len = PA_ERROR_MSG_INFO_SIZE;
+ }
+ else if (msg_info.len > PA_ERROR_MSG_INFO_MAX_SIZE)
+ {
+ msg_info.len = PA_ERROR_MSG_INFO_MAX_SIZE;
+ }
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_vendor_id = _get_error_vendor_id,
+ .get_error_code = _get_error_code,
+ .get_msg_info = _get_msg_info,
+ .get_attr_info = _get_attr_info,
+ .set_attr_info = _set_attr_info,
+ .get_offset = _get_offset,
+ },
+ .vendor_id = PEN_IETF,
+ .type = IETF_ATTR_PA_TNC_ERROR,
+ .error_vendor_id = vendor_id,
+ .error_code = error_code,
+ .msg_info = chunk_clone(msg_info),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_with_offset(pen_t vendor_id,
+ u_int32_t error_code,
+ chunk_t msg_info,
+ u_int32_t error_offset)
+{
+ private_ietf_attr_pa_tnc_error_t *this;
+
+ /* the first 8 bytes of the erroneous PA-TNC message are sent back */
+ msg_info.len = PA_ERROR_MSG_INFO_SIZE;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_vendor_id = _get_error_vendor_id,
+ .get_error_code = _get_error_code,
+ .get_msg_info = _get_msg_info,
+ .get_attr_info = _get_attr_info,
+ .set_attr_info = _set_attr_info,
+ .get_offset = _get_offset,
+ },
+ .vendor_id = PEN_IETF,
+ .type = IETF_ATTR_PA_TNC_ERROR,
+ .error_vendor_id = vendor_id,
+ .error_code = error_code,
+ .msg_info = chunk_clone(msg_info),
+ .error_offset = error_offset,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_from_data(chunk_t data)
+{
+ private_ietf_attr_pa_tnc_error_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_vendor_id = _get_error_vendor_id,
+ .get_error_code = _get_error_code,
+ .get_msg_info = _get_msg_info,
+ .get_attr_info = _get_attr_info,
+ .set_attr_info = _set_attr_info,
+ .get_offset = _get_offset,
+ },
+ .vendor_id = PEN_IETF,
+ .type = IETF_ATTR_PA_TNC_ERROR,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.h b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h
new file mode 100644
index 000000000..945e06c62
--- /dev/null
+++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2011 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 ietf_attr_pa_tnc_errort ietf_attr_pa_tnc_error
+ * @{ @ingroup ietf_attr_pa_tnc_error
+ */
+
+#ifndef IETF_ATTR_PA_TNC_ERROR_H_
+#define IETF_ATTR_PA_TNC_ERROR_H_
+
+typedef struct ietf_attr_pa_tnc_error_t ietf_attr_pa_tnc_error_t;
+typedef enum pa_tnc_error_code_t pa_tnc_error_code_t;
+
+#include "ietf_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+
+/**
+ * IETF Standard PA-TNC Error Codes as defined in section 4.2.8 of RFC 5792
+ */
+enum pa_tnc_error_code_t {
+ PA_ERROR_RESERVED = 0,
+ PA_ERROR_INVALID_PARAMETER = 1,
+ PA_ERROR_VERSION_NOT_SUPPORTED = 2,
+ PA_ERROR_ATTR_TYPE_NOT_SUPPORTED = 3,
+};
+
+/**
+ * enum name for pa_tnc_error_code_t.
+ */
+extern enum_name_t *pa_tnc_error_code_names;
+
+/**
+ * Class implementing the IETF PA-TNC Error attribute.
+ *
+ */
+struct ietf_attr_pa_tnc_error_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get PA-TNC error code vendor ID
+ *
+ * @return error code vendor ID
+ */
+ pen_t (*get_vendor_id)(ietf_attr_pa_tnc_error_t *this);
+
+ /**
+ * Get PA-TNC error code
+ *
+ * @return error code
+ */
+ pa_tnc_error_code_t (*get_error_code)(ietf_attr_pa_tnc_error_t *this);
+
+ /**
+ * Get first 8 bytes of erroneous PA-TNC message
+ *
+ * @return PA-TNC message info
+ */
+ chunk_t (*get_msg_info)(ietf_attr_pa_tnc_error_t *this);
+
+ /**
+ * Get first 8 bytes of unsupported PA-TNC attribute
+ *
+ * @return PA-TNC attribute info
+ */
+ chunk_t (*get_attr_info)(ietf_attr_pa_tnc_error_t *this);
+
+ /**
+ * Set first 8 bytes of unsupported PA-TNC attribute
+ *
+ * @param attr_info PA-TNC message info
+ */
+ void (*set_attr_info)(ietf_attr_pa_tnc_error_t *this, chunk_t attr_info);
+
+ /**
+ * Get the PA-TNC error offset
+ *
+ * @return PA-TNC error offset
+ */
+ u_int32_t (*get_offset)(ietf_attr_pa_tnc_error_t *this);
+
+};
+
+/**
+ * Creates an ietf_attr_pa_tnc_error_t object from an error code
+ *
+ * @param vendor_id PA-TNC error code vendor ID
+ * @param error_code PA-TNC error code
+ * @param header PA-TNC message header (first 8 bytes)
+ *
+ */
+pa_tnc_attr_t* ietf_attr_pa_tnc_error_create(pen_t vendor_id,
+ u_int32_t error_code,
+ chunk_t header);
+
+/**
+ * Creates an ietf_attr_pa_tnc_error_t object from an error code with offset
+ *
+ * @param vendor_id PA-TNC error code vendor ID
+ * @param error_code PA-TNC error code
+ * @param header PA-TNC message header (first 8 bytes)
+ * @param error_offset PA-TNC error offset in bytes
+ *
+ */
+pa_tnc_attr_t* ietf_attr_pa_tnc_error_create_with_offset(pen_t vendor_id,
+ u_int32_t error_code,
+ chunk_t header,
+ u_int32_t error_offset);
+
+/**
+ * Creates an ietf_attr_pa_tnc_error_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* ietf_attr_pa_tnc_error_create_from_data(chunk_t value);
+
+#endif /** IETF_ATTR_PA_TNC_ERROR_H_ @}*/
diff --git a/src/libimcv/ietf/ietf_attr_port_filter.c b/src/libimcv/ietf/ietf_attr_port_filter.c
new file mode 100644
index 000000000..b53019657
--- /dev/null
+++ b/src/libimcv/ietf/ietf_attr_port_filter.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2011 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 "ietf_attr_port_filter.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
+
+typedef struct private_ietf_attr_port_filter_t private_ietf_attr_port_filter_t;
+typedef struct port_entry_t port_entry_t;
+
+/**
+ * Port Filter entry
+ */
+struct port_entry_t {
+ bool blocked;
+ u_int8_t protocol;
+ u_int16_t port;
+};
+
+/**
+ * PA-TNC Port Filter Type (see section 4.2.6 of RFC 5792)
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved |B| Protocol | Port Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved |B| Protocol | Port Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PORT_FILTER_ENTRY_SIZE 4
+
+/**
+ * Private data of an ietf_attr_port_filter_t object.
+ */
+struct private_ietf_attr_port_filter_t {
+
+ /**
+ * Public members of ietf_attr_port_filter_t
+ */
+ ietf_attr_port_filter_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * List of Port Filter entries
+ */
+ linked_list_t *ports;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_ietf_attr_port_filter_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_ietf_attr_port_filter_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_ietf_attr_port_filter_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_ietf_attr_port_filter_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_ietf_attr_port_filter_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_ietf_attr_port_filter_t *this)
+{
+ bio_writer_t *writer;
+ enumerator_t *enumerator;
+ port_entry_t *entry;
+
+ writer = bio_writer_create(this->ports->get_count(this->ports) *
+ PORT_FILTER_ENTRY_SIZE);
+
+ enumerator = this->ports->create_enumerator(this->ports);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ writer->write_uint8 (writer, entry->blocked ? 0x01 : 0x00);
+ writer->write_uint8 (writer, entry->protocol);
+ writer->write_uint16(writer, entry->port);
+ }
+ enumerator->destroy(enumerator);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_ietf_attr_port_filter_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ port_entry_t *entry;
+ u_int8_t blocked;
+
+ if (this->value.len % PORT_FILTER_ENTRY_SIZE)
+ {
+ DBG1(DBG_TNC, "ietf port filter attribute value is not a multiple of %d",
+ PORT_FILTER_ENTRY_SIZE);
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+
+ while (reader->remaining(reader))
+ {
+ entry = malloc_thing(port_entry_t);
+ reader->read_uint8 (reader, &blocked);
+ entry->blocked = blocked & 0x01;
+ reader->read_uint8 (reader, &entry->protocol);
+ reader->read_uint16(reader, &entry->port);
+ this->ports->insert_last(this->ports, entry);
+ }
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_ietf_attr_port_filter_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_ietf_attr_port_filter_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->ports->destroy_function(this->ports, free);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(ietf_attr_port_filter_t, add_port, void,
+ private_ietf_attr_port_filter_t *this, bool blocked, u_int8_t protocol,
+ u_int16_t port)
+{
+ port_entry_t *entry;
+
+ entry = malloc_thing(port_entry_t);
+ entry->blocked = blocked;
+ entry->protocol = protocol;
+ entry->port = port;
+ this->ports->insert_last(this->ports, entry);
+}
+
+/**
+ * Enumerate port filter entries
+ */
+static bool port_filter(void *null, port_entry_t **entry,
+ bool *blocked, void *i2, u_int8_t *protocol, void *i3,
+ u_int16_t *port)
+{
+ *blocked = (*entry)->blocked;
+ *protocol = (*entry)->protocol;
+ *port = (*entry)->port;
+ return TRUE;
+}
+
+METHOD(ietf_attr_port_filter_t, create_port_enumerator, enumerator_t*,
+ private_ietf_attr_port_filter_t *this)
+{
+ return enumerator_create_filter(this->ports->create_enumerator(this->ports),
+ (void*)port_filter, NULL, NULL);
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ietf_attr_port_filter_create(void)
+{
+ private_ietf_attr_port_filter_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .add_port = _add_port,
+ .create_port_enumerator = _create_port_enumerator,
+ },
+ .vendor_id = PEN_IETF,
+ .type = IETF_ATTR_PORT_FILTER,
+ .ports = linked_list_create(),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ietf_attr_port_filter_create_from_data(chunk_t data)
+{
+ private_ietf_attr_port_filter_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .add_port = _add_port,
+ .create_port_enumerator = _create_port_enumerator,
+ },
+ .vendor_id = PEN_IETF,
+ .type = IETF_ATTR_PORT_FILTER,
+ .value = chunk_clone(data),
+ .ports = linked_list_create(),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
diff --git a/src/libimcv/ietf/ietf_attr_port_filter.h b/src/libimcv/ietf/ietf_attr_port_filter.h
new file mode 100644
index 000000000..ad5553417
--- /dev/null
+++ b/src/libimcv/ietf/ietf_attr_port_filter.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 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 ietf_attr_port_filtert ietf_attr_port_filter
+ * @{ @ingroup ietf_attr_port_filter
+ */
+
+#ifndef IETF_ATTR_PORT_FILTER_H_
+#define IETF_ATTR_PORT_FILTER_H_
+
+typedef struct ietf_attr_port_filter_t ietf_attr_port_filter_t;
+
+#include "ietf_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+
+/**
+ * Class implementing the IETF PA-TNC Port Filter attribute.
+ *
+ */
+struct ietf_attr_port_filter_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Add a port entry
+ *
+ * @param blocked TRUE if blocked, FALSE if allowed
+ * @param protocol IP protocol type
+ * @param port TCP/UDP port number
+ */
+ void (*add_port)(ietf_attr_port_filter_t *this, bool blocked,
+ u_int8_t protocol, u_int16_t port);
+
+ /**
+ * Enumerates over all ports
+ * Format: bool *blocked, u_int8_t *protocol, u_int16_t *port
+ *
+ * @return enumerator
+ */
+ enumerator_t* (*create_port_enumerator)(ietf_attr_port_filter_t *this);
+
+};
+
+/**
+ * Creates an ietf_attr_port_filter_t object
+ *
+ */
+pa_tnc_attr_t* ietf_attr_port_filter_create(void);
+
+/**
+ * Creates an ietf_attr_port_filter_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* ietf_attr_port_filter_create_from_data(chunk_t value);
+
+#endif /** IETF_ATTR_PORT_FILTER_H_ @}*/
diff --git a/src/libimcv/ietf/ietf_attr_product_info.c b/src/libimcv/ietf/ietf_attr_product_info.c
new file mode 100644
index 000000000..548793547
--- /dev/null
+++ b/src/libimcv/ietf/ietf_attr_product_info.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2011 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 "ietf_attr_product_info.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_ietf_attr_product_info_t private_ietf_attr_product_info_t;
+
+/**
+ * PA-TNC Product Information type (see section 4.2.2 of RFC 5792)
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Product Vendor ID | Product ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Product ID | Product Name (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PRODUCT_INFO_MIN_SIZE 5
+
+/**
+ * Private data of an ietf_attr_product_info_t object.
+ */
+struct private_ietf_attr_product_info_t {
+
+ /**
+ * Public members of ietf_attr_product_info_t
+ */
+ ietf_attr_product_info_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Product vendor ID
+ */
+ pen_t product_vendor_id;
+
+ /**
+ * Product ID
+ */
+ u_int16_t product_id;
+
+ /**
+ * Product Name
+ */
+ char *product_name;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_ietf_attr_product_info_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_ietf_attr_product_info_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_ietf_attr_product_info_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_ietf_attr_product_info_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_ietf_attr_product_info_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_ietf_attr_product_info_t *this)
+{
+ bio_writer_t *writer;
+ chunk_t product_name;
+
+ product_name = chunk_create(this->product_name, strlen(this->product_name));
+
+ writer = bio_writer_create(PRODUCT_INFO_MIN_SIZE);
+ writer->write_uint24(writer, this->product_vendor_id);
+ writer->write_uint16(writer, this->product_id);
+ writer->write_data (writer, product_name);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_ietf_attr_product_info_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ chunk_t product_name;
+
+ if (this->value.len < PRODUCT_INFO_MIN_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for IETF product information");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint24(reader, &this->product_vendor_id);
+ reader->read_uint16(reader, &this->product_id);
+ reader->read_data (reader, reader->remaining(reader), &product_name);
+ reader->destroy(reader);
+
+ this->product_name = malloc(product_name.len + 1);
+ memcpy(this->product_name, product_name.ptr, product_name.len);
+ this->product_name[product_name.len] = '\0';
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_ietf_attr_product_info_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_ietf_attr_product_info_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->product_name);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(ietf_attr_product_info_t, get_info, char*,
+ private_ietf_attr_product_info_t *this, pen_t *vendor_id, u_int16_t *id)
+{
+ if (vendor_id)
+ {
+ *vendor_id = this->product_vendor_id;
+ }
+ if (id)
+ {
+ *id = this->product_id;
+ }
+ return this->product_name;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id,
+ char *name)
+{
+ private_ietf_attr_product_info_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_info = _get_info,
+ },
+ .vendor_id = PEN_IETF,
+ .type = IETF_ATTR_PRODUCT_INFORMATION,
+ .product_vendor_id = vendor_id,
+ .product_id = id,
+ .product_name = strdup(name),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ietf_attr_product_info_create_from_data(chunk_t data)
+{
+ private_ietf_attr_product_info_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_info = _get_info,
+ },
+ .vendor_id = PEN_IETF,
+ .type = IETF_ATTR_PRODUCT_INFORMATION,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
diff --git a/src/libimcv/ietf/ietf_attr_product_info.h b/src/libimcv/ietf/ietf_attr_product_info.h
new file mode 100644
index 000000000..f1dfc3e83
--- /dev/null
+++ b/src/libimcv/ietf/ietf_attr_product_info.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 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 ietf_attr_product_infot ietf_attr_product_info
+ * @{ @ingroup ietf
+ */
+
+#ifndef IETF_ATTR_PRODUCT_INFO_H_
+#define IETF_ATTR_PRODUCT_INFO_H_
+
+typedef struct ietf_attr_product_info_t ietf_attr_product_info_t;
+
+#include "ietf_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+
+/**
+ * Class implementing the IETF PA-TNC Product Information attribute.
+ *
+ */
+struct ietf_attr_product_info_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Gets all product info
+ *
+ * @param vendor_id Product vendor ID
+ * @param id Product ID
+ * @return Product Name
+ */
+ char* (*get_info)(ietf_attr_product_info_t *this,
+ pen_t *vendor_id, u_int16_t *id);
+
+};
+
+/**
+ * Creates an ietf_attr_product_info_t object
+ *
+ */
+pa_tnc_attr_t* ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id,
+ char *name);
+
+/**
+ * Creates an ietf_attr_product_info_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* ietf_attr_product_info_create_from_data(chunk_t value);
+
+#endif /** IETF_ATTR_PRODUCT_INFO_H_ @}*/
diff --git a/src/libimcv/imc/imc_agent.c b/src/libimcv/imc/imc_agent.c
new file mode 100644
index 000000000..de2f959a4
--- /dev/null
+++ b/src/libimcv/imc/imc_agent.c
@@ -0,0 +1,693 @@
+/*
+ * Copyright (C) 2011 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 "imcv.h"
+#include "imc_agent.h"
+
+#include <tncif_names.h>
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <threading/rwlock.h>
+
+typedef struct private_imc_agent_t private_imc_agent_t;
+
+/**
+ * Private data of an imc_agent_t object.
+ */
+struct private_imc_agent_t {
+
+ /**
+ * Public members of imc_agent_t
+ */
+ imc_agent_t public;
+
+ /**
+ * name of IMC
+ */
+ const char *name;
+
+ /**
+ * message vendor ID of IMC
+ */
+ TNC_VendorID vendor_id;
+
+ /**
+ * message subtype of IMC
+ */
+ TNC_MessageSubtype subtype;
+
+ /**
+ * ID of IMC as assigned by TNCC
+ */
+ TNC_IMCID id;
+
+ /**
+ * List of additional IMC IDs assigned by TNCC
+ */
+ linked_list_t *additional_ids;
+
+ /**
+ * list of TNCC connection entries
+ */
+ linked_list_t *connections;
+
+ /**
+ * rwlock to lock TNCC connection entries
+ */
+ rwlock_t *connection_lock;
+
+ /**
+ * Inform a TNCC about the set of message types the IMC is able to receive
+ *
+ * @param imc_id IMC ID assigned by TNCC
+ * @param supported_types list of supported message types
+ * @param type_count number of list elements
+ * @return TNC result code
+ */
+ TNC_Result (*report_message_types)(TNC_IMCID imc_id,
+ TNC_MessageTypeList supported_types,
+ TNC_UInt32 type_count);
+
+ /**
+ * Inform a TNCC about the set of message types the IMC is able to receive
+ *
+ * @param imc_id IMC ID assigned by TNCC
+ * @param supported_vids list of supported message vendor IDs
+ * @param supported_subtypes list of supported message subtypes
+ * @param type_count number of list elements
+ * @return TNC result code
+ */
+ TNC_Result (*report_message_types_long)(TNC_IMCID imc_id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count);
+
+ /**
+ * Call when an IMC-IMC message is to be sent
+ *
+ * @param imc_id IMC ID assigned by TNCC
+ * @param connection_id network connection ID assigned by TNCC
+ * @param msg message to send
+ * @param msg_len message length in bytes
+ * @param msg_type message type
+ * @return TNC result code
+ */
+ TNC_Result (*send_message)(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type);
+
+
+ /**
+ * Call when an IMC-IMC message is to be sent with long message types
+ *
+ * @param imc_id IMC ID assigned by TNCC
+ * @param connection_id network connection ID assigned by TNCC
+ * @param msg_flags message flags
+ * @param msg message to send
+ * @param msg_len message length in bytes
+ * @param msg_vid message vendor ID
+ * @param msg_subtype message subtype
+ * @param dst_imc_id destination IMV ID
+ * @return TNC result code
+ */
+ TNC_Result (*send_message_long)(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 dst_imv_id);
+
+ /**
+ * Get the value of an attribute associated with a connection
+ * or with the TNCC as a whole.
+ *
+ * @param imc_id IMC ID assigned by TNCC
+ * @param connection_id network connection ID assigned by TNCC
+ * @param attribute_id attribute ID
+ * @param buffer_len length of buffer in bytes
+ * @param buffer buffer
+ * @param out_value_len size in bytes of attribute stored in buffer
+ * @return TNC result code
+ */
+ TNC_Result (*get_attribute)(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer,
+ TNC_UInt32 *out_value_len);
+
+ /**
+ * Set the value of an attribute associated with a connection
+ * or with the TNCC as a whole.
+ *
+ * @param imc_id IMV ID assigned by TNCC
+ * @param connection_id network connection ID assigned by TNCC
+ * @param attribute_id attribute ID
+ * @param buffer_len length of buffer in bytes
+ * @param buffer buffer
+ * @return TNC result code
+ */
+ TNC_Result (*set_attribute)(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer);
+
+ /**
+ * Reserve an additional IMC ID
+ *
+ * @param imc_id primary IMC ID assigned by TNCC
+ * @param out_imc_id additional IMC ID assigned by TNCC
+ * @return TNC result code
+ */
+ TNC_Result (*reserve_additional_id)(TNC_IMCID imc_id,
+ TNC_UInt32 *out_imc_id);
+
+};
+
+METHOD(imc_agent_t, bind_functions, TNC_Result,
+ private_imc_agent_t *this, TNC_TNCC_BindFunctionPointer bind_function)
+{
+ if (!bind_function)
+ {
+ DBG1(DBG_IMC, "TNC client failed to provide bind function");
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ if (bind_function(this->id, "TNC_TNCC_ReportMessageTypes",
+ (void**)&this->report_message_types) != TNC_RESULT_SUCCESS)
+ {
+ this->report_message_types = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCC_ReportMessageTypesLong",
+ (void**)&this->report_message_types_long) != TNC_RESULT_SUCCESS)
+ {
+ this->report_message_types_long = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCC_RequestHandshakeRetry",
+ (void**)&this->public.request_handshake_retry) != TNC_RESULT_SUCCESS)
+ {
+ this->public.request_handshake_retry = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCC_SendMessage",
+ (void**)&this->send_message) != TNC_RESULT_SUCCESS)
+ {
+ this->send_message = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCC_SendMessageLong",
+ (void**)&this->send_message_long) != TNC_RESULT_SUCCESS)
+ {
+ this->send_message_long = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCC_GetAttribute",
+ (void**)&this->get_attribute) != TNC_RESULT_SUCCESS)
+ {
+ this->get_attribute = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCC_SetAttribute",
+ (void**)&this->set_attribute) != TNC_RESULT_SUCCESS)
+ {
+ this->set_attribute = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCC_ReserveAdditionalIMCID",
+ (void**)&this->reserve_additional_id) != TNC_RESULT_SUCCESS)
+ {
+ this->reserve_additional_id = NULL;
+ }
+ DBG2(DBG_IMC, "IMC %u \"%s\" provided with bind function",
+ this->id, this->name);
+
+ if (this->report_message_types_long)
+ {
+ this->report_message_types_long(this->id, &this->vendor_id,
+ &this->subtype, 1);
+ }
+ else if (this->report_message_types &&
+ this->vendor_id <= TNC_VENDORID_ANY &&
+ this->subtype <= TNC_SUBTYPE_ANY)
+ {
+ TNC_MessageType type;
+
+ type = (this->vendor_id << 8) | this->subtype;
+ this->report_message_types(this->id, &type, 1);
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * finds a connection state based on its Connection ID
+ */
+static imc_state_t* find_connection(private_imc_agent_t *this,
+ TNC_ConnectionID id)
+{
+ enumerator_t *enumerator;
+ imc_state_t *state, *found = NULL;
+
+ this->connection_lock->read_lock(this->connection_lock);
+ enumerator = this->connections->create_enumerator(this->connections);
+ while (enumerator->enumerate(enumerator, &state))
+ {
+ if (id == state->get_connection_id(state))
+ {
+ found = state;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->connection_lock->unlock(this->connection_lock);
+
+ return found;
+}
+
+/**
+ * delete a connection state with a given Connection ID
+ */
+static bool delete_connection(private_imc_agent_t *this, TNC_ConnectionID id)
+{
+ enumerator_t *enumerator;
+ imc_state_t *state;
+ bool found = FALSE;
+
+ this->connection_lock->write_lock(this->connection_lock);
+ enumerator = this->connections->create_enumerator(this->connections);
+ while (enumerator->enumerate(enumerator, &state))
+ {
+ if (id == state->get_connection_id(state))
+ {
+ found = TRUE;
+ state->destroy(state);
+ this->connections->remove_at(this->connections, enumerator);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->connection_lock->unlock(this->connection_lock);
+
+ return found;
+}
+
+/**
+ * Read a boolean attribute
+ */
+static bool get_bool_attribute(private_imc_agent_t *this, TNC_ConnectionID id,
+ TNC_AttributeID attribute_id)
+{
+ TNC_UInt32 len;
+ char buf[4];
+
+ return this->get_attribute &&
+ this->get_attribute(this->id, id, attribute_id, 4, buf, &len) ==
+ TNC_RESULT_SUCCESS && len == 1 && *buf == 0x01;
+}
+
+/**
+ * Read a string attribute
+ */
+static char* get_str_attribute(private_imc_agent_t *this, TNC_ConnectionID id,
+ TNC_AttributeID attribute_id)
+{
+ TNC_UInt32 len;
+ char buf[BUF_LEN];
+
+ if (this->get_attribute &&
+ this->get_attribute(this->id, id, attribute_id, BUF_LEN, buf, &len) ==
+ TNC_RESULT_SUCCESS && len <= BUF_LEN)
+ {
+ return strdup(buf);
+ }
+ return NULL;
+ }
+
+METHOD(imc_agent_t, create_state, TNC_Result,
+ private_imc_agent_t *this, imc_state_t *state)
+{
+ TNC_ConnectionID conn_id;
+ char *tnccs_p = NULL, *tnccs_v = NULL, *t_p = NULL, *t_v = NULL;
+ bool has_long = FALSE, has_excl = FALSE, has_soh = FALSE;
+
+ conn_id = state->get_connection_id(state);
+ if (find_connection(this, conn_id))
+ {
+ DBG1(DBG_IMC, "IMC %u \"%s\" already created a state for Connection ID %u",
+ this->id, this->name, conn_id);
+ state->destroy(state);
+ return TNC_RESULT_OTHER;
+ }
+
+ /* Get and display attributes from TNCC via IF-IMC */
+ has_long = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_LONG_TYPES);
+ has_excl = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_EXCLUSIVE);
+ has_soh = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_SOH);
+ tnccs_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL);
+ tnccs_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_VERSION);
+ t_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_PROTOCOL);
+ t_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_VERSION);
+
+ state->set_flags(state, has_long, has_excl);
+
+ DBG2(DBG_IMC, "IMC %u \"%s\" created a state for Connection ID %u: "
+ "%s %s with %slong %sexcl %ssoh over %s %s",
+ this->id, this->name, conn_id, tnccs_p ? tnccs_p:"?",
+ tnccs_v ? tnccs_v:"?", has_long ? "+":"-", has_excl ? "+":"-",
+ has_soh ? "+":"-", t_p ? t_p:"?", t_v ? t_v :"?");
+ free(tnccs_p);
+ free(tnccs_v);
+ free(t_p);
+ free(t_v);
+
+ this->connection_lock->write_lock(this->connection_lock);
+ this->connections->insert_last(this->connections, state);
+ this->connection_lock->unlock(this->connection_lock);
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imc_agent_t, delete_state, TNC_Result,
+ private_imc_agent_t *this, TNC_ConnectionID connection_id)
+{
+ if (!delete_connection(this, connection_id))
+ {
+ DBG1(DBG_IMC, "IMC %u \"%s\" has no state for Connection ID %u",
+ this->id, this->name, connection_id);
+ return TNC_RESULT_FATAL;
+ }
+ DBG2(DBG_IMC, "IMC %u \"%s\" deleted the state of Connection ID %u",
+ this->id, this->name, connection_id);
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imc_agent_t, change_state, TNC_Result,
+ private_imc_agent_t *this, TNC_ConnectionID connection_id,
+ TNC_ConnectionState new_state,
+ imc_state_t **state_p)
+{
+ imc_state_t *state;
+
+ switch (new_state)
+ {
+ case TNC_CONNECTION_STATE_HANDSHAKE:
+ case TNC_CONNECTION_STATE_ACCESS_ALLOWED:
+ case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
+ case TNC_CONNECTION_STATE_ACCESS_NONE:
+ state = find_connection(this, connection_id);
+
+ if (!state)
+ {
+ DBG1(DBG_IMC, "IMC %u \"%s\" has no state for Connection ID %u",
+ this->id, this->name, connection_id);
+ return TNC_RESULT_FATAL;
+ }
+ state->change_state(state, new_state);
+ DBG2(DBG_IMC, "IMC %u \"%s\" changed state of Connection ID %u to '%N'",
+ this->id, this->name, connection_id,
+ TNC_Connection_State_names, new_state);
+ if (state_p)
+ {
+ *state_p = state;
+ }
+ break;
+ case TNC_CONNECTION_STATE_CREATE:
+ DBG1(DBG_IMC, "state '%N' should be handled by create_state()",
+ TNC_Connection_State_names, new_state);
+ return TNC_RESULT_FATAL;
+ case TNC_CONNECTION_STATE_DELETE:
+ DBG1(DBG_IMC, "state '%N' should be handled by delete_state()",
+ TNC_Connection_State_names, new_state);
+ return TNC_RESULT_FATAL;
+ default:
+ DBG1(DBG_IMC, "IMC %u \"%s\" was notified of unknown state %u "
+ "for Connection ID %u",
+ this->id, this->name, new_state, connection_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imc_agent_t, get_state, bool,
+ private_imc_agent_t *this, TNC_ConnectionID connection_id,
+ imc_state_t **state)
+{
+ *state = find_connection(this, connection_id);
+ if (!*state)
+ {
+ DBG1(DBG_IMC, "IMC %u \"%s\" has no state for Connection ID %u",
+ this->id, this->name, connection_id);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+METHOD(imc_agent_t, send_message, TNC_Result,
+ private_imc_agent_t *this, TNC_ConnectionID connection_id, bool excl,
+ TNC_UInt32 src_imc_id, TNC_UInt32 dst_imv_id, chunk_t msg)
+{
+ TNC_MessageType type;
+ TNC_UInt32 msg_flags;
+ imc_state_t *state;
+
+ state = find_connection(this, connection_id);
+ if (!state)
+ {
+ DBG1(DBG_IMV, "IMC %u \"%s\" has no state for Connection ID %u",
+ this->id, this->name, connection_id);
+ return TNC_RESULT_FATAL;
+ }
+
+ if (state->has_long(state) && this->send_message_long)
+ {
+ if (!src_imc_id)
+ {
+ src_imc_id = this->id;
+ }
+ msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0;
+
+ return this->send_message_long(src_imc_id, connection_id, msg_flags,
+ msg.ptr, msg.len, this->vendor_id,
+ this->subtype, dst_imv_id);
+ }
+ if (this->send_message)
+ {
+ type = (this->vendor_id << 8) | this->subtype;
+
+ return this->send_message(this->id, connection_id, msg.ptr, msg.len,
+ type);
+ }
+ return TNC_RESULT_FATAL;
+}
+
+METHOD(imc_agent_t, receive_message, TNC_Result,
+ private_imc_agent_t *this, imc_state_t *state, chunk_t msg,
+ TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imv_id, TNC_UInt32 dst_imc_id, pa_tnc_msg_t **pa_tnc_msg)
+{
+ pa_tnc_msg_t *pa_msg, *error_msg;
+ pa_tnc_attr_t *error_attr;
+ enumerator_t *enumerator;
+ TNC_MessageType msg_type;
+ TNC_UInt32 msg_flags, src_imc_id, dst_imv_id;
+ TNC_ConnectionID connection_id;
+ TNC_Result result;
+
+ connection_id = state->get_connection_id(state);
+
+ if (state->has_long(state))
+ {
+ if (dst_imc_id != TNC_IMCID_ANY)
+ {
+ DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u "
+ "from IMV %u to IMC %u", this->id, this->name,
+ connection_id, src_imv_id, dst_imc_id);
+ }
+ else
+ {
+ DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u "
+ "from IMV %u", this->id, this->name, connection_id,
+ src_imv_id);
+ }
+ }
+ else
+ {
+ DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u",
+ this->id, this->name, connection_id);
+ }
+
+ *pa_tnc_msg = NULL;
+ pa_msg = pa_tnc_msg_create_from_data(msg);
+
+ switch (pa_msg->process(pa_msg))
+ {
+ case SUCCESS:
+ *pa_tnc_msg = pa_msg;
+ break;
+ case VERIFY_ERROR:
+ /* build error message */
+ error_msg = pa_tnc_msg_create();
+ enumerator = pa_msg->create_error_enumerator(pa_msg);
+ while (enumerator->enumerate(enumerator, &error_attr))
+ {
+ error_msg->add_attribute(error_msg,
+ error_attr->get_ref(error_attr));
+ }
+ enumerator->destroy(enumerator);
+ error_msg->build(error_msg);
+
+ /* send error message */
+ if (state->has_long(state) && this->send_message_long)
+ {
+ if (state->has_excl(state))
+ {
+ msg_flags = TNC_MESSAGE_FLAGS_EXCLUSIVE;
+ dst_imv_id = src_imv_id;
+ }
+ else
+ {
+ msg_flags = 0;
+ dst_imv_id = TNC_IMVID_ANY;
+ }
+ src_imc_id = (dst_imc_id == TNC_IMCID_ANY) ? this->id
+ : dst_imc_id;
+
+ result = this->send_message_long(src_imc_id, connection_id,
+ msg_flags, msg.ptr, msg.len, msg_vid,
+ msg_subtype, dst_imv_id);
+ }
+ else if (this->send_message)
+ {
+ msg_type = (msg_vid << 8) | msg_subtype;
+
+ result = this->send_message(this->id, connection_id,
+ msg.ptr, msg.len, msg_type);
+ }
+ else
+ {
+ result = TNC_RESULT_FATAL;
+ }
+
+ /* clean up */
+ error_msg->destroy(error_msg);
+ pa_msg->destroy(pa_msg);
+ return result;
+ case FAILED:
+ default:
+ pa_msg->destroy(pa_msg);
+ return TNC_RESULT_FATAL;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imc_agent_t, reserve_additional_ids, TNC_Result,
+ private_imc_agent_t *this, int count)
+{
+ TNC_Result result;
+ TNC_UInt32 id;
+ void *pointer;
+
+ if (!this->reserve_additional_id)
+ {
+ DBG1(DBG_IMC, "IMC %u \"%s\" did not detect the capability to reserve "
+ "additional IMC IDs from the TNCC", this->id, this->name);
+ return TNC_RESULT_ILLEGAL_OPERATION;
+ }
+ while (count > 0)
+ {
+ result = this->reserve_additional_id(this->id, &id);
+ if (result != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_IMC, "IMC %u \"%s\" failed to reserve %d additional IMC IDs",
+ this->id, this->name, count);
+ return result;
+ }
+ count--;
+
+ /* store the scalar value in the pointer */
+ pointer = (void*)id;
+ this->additional_ids->insert_last(this->additional_ids, pointer);
+ DBG2(DBG_IMC, "IMC %u \"%s\" reserved additional ID %u",
+ this->id, this->name, id);
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imc_agent_t, count_additional_ids, int,
+ private_imc_agent_t *this)
+{
+ return this->additional_ids->get_count(this->additional_ids);
+}
+
+METHOD(imc_agent_t, create_id_enumerator, enumerator_t*,
+ private_imc_agent_t *this)
+{
+ return this->additional_ids->create_enumerator(this->additional_ids);
+}
+
+METHOD(imc_agent_t, destroy, void,
+ private_imc_agent_t *this)
+{
+ DBG1(DBG_IMC, "IMC %u \"%s\" terminated", this->id, this->name);
+ this->additional_ids->destroy(this->additional_ids);
+ this->connections->destroy_function(this->connections, free);
+ this->connection_lock->destroy(this->connection_lock);
+ free(this);
+
+ /* decrease the reference count or terminate */
+ libimcv_deinit();
+}
+
+/**
+ * Described in header.
+ */
+imc_agent_t *imc_agent_create(const char *name,
+ pen_t vendor_id, u_int32_t subtype,
+ TNC_IMCID id, TNC_Version *actual_version)
+{
+ private_imc_agent_t *this;
+
+ /* initialize or increase the reference count */
+ if (!libimcv_init())
+ {
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .bind_functions = _bind_functions,
+ .create_state = _create_state,
+ .delete_state = _delete_state,
+ .change_state = _change_state,
+ .get_state = _get_state,
+ .send_message = _send_message,
+ .receive_message = _receive_message,
+ .reserve_additional_ids = _reserve_additional_ids,
+ .count_additional_ids = _count_additional_ids,
+ .create_id_enumerator = _create_id_enumerator,
+ .destroy = _destroy,
+ },
+ .name = name,
+ .vendor_id = vendor_id,
+ .subtype = subtype,
+ .id = id,
+ .additional_ids = linked_list_create(),
+ .connections = linked_list_create(),
+ .connection_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
+
+ *actual_version = TNC_IFIMC_VERSION_1;
+ DBG1(DBG_IMC, "IMC %u \"%s\" initialized", this->id, this->name);
+
+ return &this->public;
+}
+
diff --git a/src/libimcv/imc/imc_agent.h b/src/libimcv/imc/imc_agent.h
new file mode 100644
index 000000000..d1fef4d8d
--- /dev/null
+++ b/src/libimcv/imc/imc_agent.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2011 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 imc_agent_t imc_agent
+ * @{ @ingroup imc_agent
+ */
+
+#ifndef IMC_AGENT_H_
+#define IMC_AGENT_H_
+
+#include "imc_state.h"
+#include "pa_tnc/pa_tnc_msg.h"
+
+#include <tncifimc.h>
+#include <pen/pen.h>
+
+#include <library.h>
+
+typedef struct imc_agent_t imc_agent_t;
+
+/**
+ * Core functions of an Integrity Measurement Verifier (IMC)
+ */
+struct imc_agent_t {
+
+ /**
+ * Ask a TNCC to retry an Integrity Check Handshake
+ *
+ * @param imc_id IMC ID assigned by TNCC
+ * @param connection_id network connection ID assigned by TNCC
+ * @param reason IMC retry reason
+ * @return TNC result code
+ */
+ TNC_Result (*request_handshake_retry)(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_RetryReason reason);
+
+ /**
+ * Bind TNCC functions
+ *
+ * @param bind_function function offered by the TNCC
+ * @return TNC result code
+ */
+ TNC_Result (*bind_functions)(imc_agent_t *this,
+ TNC_TNCC_BindFunctionPointer bind_function);
+
+ /**
+ * Create the IMC state for a TNCCS connection instance
+ *
+ * @param state internal IMC state instance
+ * @return TNC result code
+ */
+ TNC_Result (*create_state)(imc_agent_t *this, imc_state_t *state);
+
+ /**
+ * Delete the IMC state for a TNCCS connection instance
+ *
+ * @param connection_id network connection ID assigned by TNCS
+ * @return TNC result code
+ */
+ TNC_Result (*delete_state)(imc_agent_t *this,
+ TNC_ConnectionID connection_id);
+
+ /**
+ * Change the current state of a TNCCS connection
+ *
+ * @param connection_id network connection ID assigned by TNCS
+ * @param new_state new state of TNCCS connection
+ * @param state_p internal IMC state instance [optional argument]
+ * @return TNC result code
+ */
+ TNC_Result (*change_state)(imc_agent_t *this,
+ TNC_ConnectionID connection_id,
+ TNC_ConnectionState new_state,
+ imc_state_t **state_p);
+
+ /**
+ * Get the IMC state for a TNCCS connection instance
+ *
+ * @param connection_id network connection ID assigned by TNCS
+ * @param state internal IMC state instance
+ * @return TRUE if the state was found
+ */
+ bool (*get_state)(imc_agent_t *this,
+ TNC_ConnectionID connection_id, imc_state_t **state);
+
+ /**
+ * Call when an PA-TNC message is to be sent
+ *
+ * @param connection_id network connection ID assigned by TNCC
+ * @param excl exclusive flag
+ * @param src_imc_id IMC ID to be set as source
+ * @param dst_imv_id IMV ID to be set as destination
+ * @param msg message to send
+ * @return TNC result code
+ */
+ TNC_Result (*send_message)(imc_agent_t *this,
+ TNC_ConnectionID connection_id, bool excl,
+ TNC_UInt32 src_imc_id, TNC_UInt32 dst_imv_id,
+ chunk_t msg);
+
+ /**
+ * Call when a PA-TNC message was received
+ *
+ * @param state state for current connection
+ * @param msg received unparsed message
+ * @param msg_vid message vendorID of the received message
+ * @param msg_subtype message subtype of the received message
+ * @param src_imv_id source IMV ID
+ * @param dst_imc_id destination IMC ID
+ * @param pa_tnc_message parsed PA-TNC message or NULL if an error occurred
+ * @return TNC result code
+ */
+ TNC_Result (*receive_message)(imc_agent_t *this,
+ imc_state_t *state, chunk_t msg,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imv_id,
+ TNC_UInt32 dst_imc_id,
+ pa_tnc_msg_t **pa_tnc_msg);
+
+ /**
+ * Reserve additional IMC IDs from TNCC
+ *
+ * @param count number of additional IMC IDs to be assigned
+ * @return TNC result code
+ */
+ TNC_Result (*reserve_additional_ids)(imc_agent_t *this, int count);
+
+ /**
+ * Return the number of additional IMC IDs assigned by the TNCC
+ *
+ * @return number of additional IMC IDs
+ */
+ int (*count_additional_ids)(imc_agent_t *this);
+
+ /**
+ * Create an enumerator for the additional IMC IDs
+ */
+ enumerator_t* (*create_id_enumerator)(imc_agent_t *this);
+
+ /**
+ * Destroys an imc_agent_t object
+ */
+ void (*destroy)(imc_agent_t *this);
+};
+
+/**
+ * Create an imc_agent_t object
+ *
+ * @param name name of the IMC
+ * @param vendor_id vendor ID of the IMC
+ * @param subtype message subtype of the IMC
+ * @param id ID of the IMC as assigned by the TNCS
+ * @param actual_version actual version of the IF-IMC API
+ *
+ */
+imc_agent_t *imc_agent_create(const char *name,
+ pen_t vendor_id, u_int32_t subtype,
+ TNC_IMCID id, TNC_Version *actual_version);
+
+#endif /** IMC_AGENT_H_ @}*/
diff --git a/src/libimcv/imc/imc_state.h b/src/libimcv/imc/imc_state.h
new file mode 100644
index 000000000..f1b0358c9
--- /dev/null
+++ b/src/libimcv/imc/imc_state.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 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 imc_state_t imc_state
+ * @{ @ingroup imc_state
+ */
+
+#ifndef IMC_STATE_H_
+#define IMC_STATE_H_
+
+#include <tncif.h>
+
+#include <library.h>
+
+typedef struct imc_state_t imc_state_t;
+
+/**
+ * Internal state of an IMC connection instance
+ */
+struct imc_state_t {
+
+ /**
+ * Get the TNCS connection I
+D attached to the state
+ *
+ * @return TNCS connection ID of the state
+ */
+ TNC_ConnectionID (*get_connection_id)(imc_state_t *this);
+
+ /**
+ * Checks if long message types are supported for this TNCCS connection
+ *
+ * @return TRUE if set, FALSE otherwise
+ */
+ bool (*has_long)(imc_state_t *this);
+
+ /**
+ * Checks if the exclusive delivery is supported for this TNCCS connection
+ *
+ * @return TRUE if set, FALSE otherwise
+ */
+ bool (*has_excl)(imc_state_t *this);
+
+ /**
+ * Sets the long message types and exclusive flags for this TNCCS connection
+ *
+ * @param has_long TNCCS connection supports long message types
+ * @param has_excl TNCCS connection supports exclusive delivery
+ * @return TRUE if set, FALSE otherwise
+ */
+ void (*set_flags)(imc_state_t *this, bool has_long, bool has_excl);
+
+ /**
+ * Change the connection state
+ *
+ * @param new_state new connection state
+ */
+ void (*change_state)(imc_state_t *this, TNC_ConnectionState new_state);
+
+ /**
+ * Destroys an imc_state_t object
+ */
+ void (*destroy)(imc_state_t *this);
+};
+
+#endif /** IMC_STATE_H_ @}*/
diff --git a/src/libimcv/imcv.c b/src/libimcv/imcv.c
new file mode 100644
index 000000000..a8c0af47b
--- /dev/null
+++ b/src/libimcv/imcv.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2011 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 "imcv.h"
+#include "ietf/ietf_attr.h"
+#include "ita/ita_attr.h"
+
+#include <utils.h>
+#include <debug.h>
+#include <pen/pen.h>
+
+#include <syslog.h>
+
+#define IMCV_DEBUG_LEVEL 1
+
+/**
+ * PA-TNC attribute manager
+ */
+pa_tnc_attr_manager_t *imcv_pa_tnc_attributes;
+
+/**
+ * Reference count for libimcv
+ */
+static refcount_t libimcv_ref = 0;
+
+/**
+ * Reference count for libstrongswan
+ */
+static refcount_t libstrongswan_ref = 0;
+
+/**
+ * Global configuration of imcv dbg function
+ */
+static int imcv_debug_level;
+static bool imcv_stderr_quiet;
+
+/**
+ * imvc dbg function
+ */
+static void imcv_dbg(debug_t group, level_t level, char *fmt, ...)
+{
+ int priority = LOG_INFO;
+ char buffer[8192];
+ char *current = buffer, *next;
+ va_list args;
+
+ if (level <= imcv_debug_level)
+ {
+ if (!imcv_stderr_quiet)
+ {
+ va_start(args, fmt);
+ fprintf(stderr, "[HSR] ");
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ va_end(args);
+ }
+
+ /* write in memory buffer first */
+ va_start(args, fmt);
+ vsnprintf(buffer, sizeof(buffer), fmt, args);
+ va_end(args);
+
+ /* do a syslog with every line */
+ while (current)
+ {
+ next = strchr(current, '\n');
+ if (next)
+ {
+ *(next++) = '\0';
+ }
+ syslog(priority, "[HSR] %s\n", current);
+ current = next;
+ }
+ }
+}
+
+/**
+ * Described in header.
+ */
+bool libimcv_init(void)
+{
+ /* initialize libstrongswan library only once */
+ if (lib)
+ {
+ /* did main program initialize libstrongswan? */
+ if (libstrongswan_ref == 0)
+ {
+ ref_get(&libstrongswan_ref);
+ }
+ }
+ else
+ {
+ /* we are the first to initialize libstrongswan */
+ if (!library_init(NULL))
+ {
+ return FALSE;
+ }
+
+ if (!lib->plugins->load(lib->plugins, NULL,
+ "sha1 sha2 random gmp pubkey x509"))
+ {
+ library_deinit();
+ return FALSE;
+ }
+
+ /* set the debug level and stderr output */
+ imcv_debug_level = lib->settings->get_int(lib->settings,
+ "libimcv.debug_level", IMCV_DEBUG_LEVEL);
+ imcv_stderr_quiet = lib->settings->get_int(lib->settings,
+ "libimcv.stderr_quiet", FALSE);
+
+ /* activate the imcv debugging hook */
+ dbg = imcv_dbg;
+ openlog("imcv", 0, LOG_DAEMON);
+ }
+ ref_get(&libstrongswan_ref);
+
+ if (libimcv_ref == 0)
+ {
+ /* initialize the PA-TNC attribute manager */
+ imcv_pa_tnc_attributes = pa_tnc_attr_manager_create();
+ imcv_pa_tnc_attributes->add_vendor(imcv_pa_tnc_attributes, PEN_IETF,
+ ietf_attr_create_from_data, ietf_attr_names);
+ imcv_pa_tnc_attributes->add_vendor(imcv_pa_tnc_attributes, PEN_ITA,
+ ita_attr_create_from_data, ita_attr_names);
+ DBG1(DBG_LIB, "libimcv initialized");
+ }
+ ref_get(&libimcv_ref);
+
+ return TRUE;
+}
+
+/**
+ * Described in header.
+ */
+void libimcv_deinit(void)
+{
+ if (ref_put(&libimcv_ref))
+ {
+ imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_IETF);
+ imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_ITA);
+ DESTROY_IF(imcv_pa_tnc_attributes);
+ DBG1(DBG_LIB, "libimcv terminated");
+ }
+ if (ref_put(&libstrongswan_ref))
+ {
+ library_deinit();
+ }
+}
+
diff --git a/src/libimcv/imcv.h b/src/libimcv/imcv.h
new file mode 100644
index 000000000..a1a5a5f43
--- /dev/null
+++ b/src/libimcv/imcv.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 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 libimcv libimcv
+ *
+ * @defgroup iplugins plugins
+ * @ingroup libimcv
+ *
+ * @addtogroup libimcv
+ * @{
+ */
+
+#ifndef IMCV_H_
+#define IMCV_H_
+
+#include "pa_tnc/pa_tnc_attr_manager.h"
+
+#include <library.h>
+
+/**
+ * Initialize libimcv.
+ *
+ * @return FALSE if initialization failed
+ */
+bool libimcv_init(void);
+
+/**
+ * Deinitialize libimcv.
+ */
+void libimcv_deinit(void);
+
+/**
+ * PA-TNC attribute manager
+ */
+extern pa_tnc_attr_manager_t* imcv_pa_tnc_attributes;
+
+#endif /** IMCV_H_ @}*/
diff --git a/src/libimcv/imv/imv_agent.c b/src/libimcv/imv/imv_agent.c
new file mode 100644
index 000000000..56131c547
--- /dev/null
+++ b/src/libimcv/imv/imv_agent.c
@@ -0,0 +1,792 @@
+/*
+ * Copyright (C) 2011 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 "imcv.h"
+#include "imv_agent.h"
+
+#include <tncif_names.h>
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <threading/rwlock.h>
+
+typedef struct private_imv_agent_t private_imv_agent_t;
+
+/**
+ * Private data of an imv_agent_t object.
+ */
+struct private_imv_agent_t {
+
+ /**
+ * Public members of imv_agent_t
+ */
+ imv_agent_t public;
+
+ /**
+ * name of IMV
+ */
+ const char *name;
+
+ /**
+ * message vendor ID of IMV
+ */
+ TNC_VendorID vendor_id;
+
+ /**
+ * message subtype of IMV
+ */
+ TNC_MessageSubtype subtype;
+
+ /**
+ * ID of IMV as assigned by TNCS
+ */
+ TNC_IMVID id;
+
+ /**
+ * List of additional IMV IDs assigned by TNCS
+ */
+ linked_list_t *additional_ids;
+
+ /**
+ * list of TNCS connection entries
+ */
+ linked_list_t *connections;
+
+ /**
+ * rwlock to lock TNCS connection entries
+ */
+ rwlock_t *connection_lock;
+
+ /**
+ * Inform a TNCS about the set of message types the IMV is able to receive
+ *
+ * @param imv_id IMV ID assigned by TNCS
+ * @param supported_types list of supported message types
+ * @param type_count number of list elements
+ * @return TNC result code
+ */
+ TNC_Result (*report_message_types)(TNC_IMVID imv_id,
+ TNC_MessageTypeList supported_types,
+ TNC_UInt32 type_count);
+
+ /**
+ * Inform a TNCS about the set of message types the IMV is able to receive
+ *
+ * @param imv_id IMV ID assigned by TNCS
+ * @param supported_vids list of supported message vendor IDs
+ * @param supported_subtypes list of supported message subtypes
+ * @param type_count number of list elements
+ * @return TNC result code
+ */
+ TNC_Result (*report_message_types_long)(TNC_IMVID imv_id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count);
+
+ /**
+ * Call when an IMV-IMC message is to be sent
+ *
+ * @param imv_id IMV ID assigned by TNCS
+ * @param connection_id network connection ID assigned by TNCS
+ * @param msg message to send
+ * @param msg_len message length in bytes
+ * @param msg_type message type
+ * @return TNC result code
+ */
+ TNC_Result (*send_message)(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type);
+
+ /**
+ * Call when an IMV-IMC message is to be sent with long message types
+ *
+ * @param imv_id IMV ID assigned by TNCS
+ * @param connection_id network connection ID assigned by TNCS
+ * @param msg_flags message flags
+ * @param msg message to send
+ * @param msg_len message length in bytes
+ * @param msg_vid message vendor ID
+ * @param msg_subtype message subtype
+ * @param dst_imc_id destination IMC ID
+ * @return TNC result code
+ */
+ TNC_Result (*send_message_long)(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 dst_imc_id);
+
+ /**
+ * Deliver IMV Action Recommendation and IMV Evaluation Results to the TNCS
+ *
+ * @param imv_id IMV ID assigned by TNCS
+ # @param connection_id network connection ID assigned by TNCS
+ * @param rec IMV action recommendation
+ * @param eval IMV evaluation result
+ * @return TNC result code
+ */
+ TNC_Result (*provide_recommendation)(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_IMV_Action_Recommendation rec,
+ TNC_IMV_Evaluation_Result eval);
+
+ /**
+ * Get the value of an attribute associated with a connection
+ * or with the TNCS as a whole.
+ *
+ * @param imv_id IMV ID assigned by TNCS
+ * @param connection_id network connection ID assigned by TNCS
+ * @param attribute_id attribute ID
+ * @param buffer_len length of buffer in bytes
+ * @param buffer buffer
+ * @param out_value_len size in bytes of attribute stored in buffer
+ * @return TNC result code
+ */
+ TNC_Result (*get_attribute)(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer,
+ TNC_UInt32 *out_value_len);
+
+ /**
+ * Set the value of an attribute associated with a connection
+ * or with the TNCS as a whole.
+ *
+ * @param imv_id IMV ID assigned by TNCS
+ * @param connection_id network connection ID assigned by TNCS
+ * @param attribute_id attribute ID
+ * @param buffer_len length of buffer in bytes
+ * @param buffer buffer
+ * @return TNC result code
+ */
+ TNC_Result (*set_attribute)(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_AttributeID attribute_id,
+ TNC_UInt32 buffer_len,
+ TNC_BufferReference buffer);
+
+ /**
+ * Reserve an additional IMV ID
+ *
+ * @param imv_id primary IMV ID assigned by TNCS
+ * @param out_imv_id additional IMV ID assigned by TNCS
+ * @return TNC result code
+ */
+ TNC_Result (*reserve_additional_id)(TNC_IMVID imv_id,
+ TNC_UInt32 *out_imv_id);
+
+};
+
+METHOD(imv_agent_t, bind_functions, TNC_Result,
+ private_imv_agent_t *this, TNC_TNCS_BindFunctionPointer bind_function)
+{
+ if (!bind_function)
+ {
+ DBG1(DBG_IMV, "TNC server failed to provide bind function");
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ if (bind_function(this->id, "TNC_TNCS_ReportMessageTypes",
+ (void**)&this->report_message_types) != TNC_RESULT_SUCCESS)
+ {
+ this->report_message_types = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCS_ReportMessageTypesLong",
+ (void**)&this->report_message_types_long) != TNC_RESULT_SUCCESS)
+ {
+ this->report_message_types_long = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCS_RequestHandshakeRetry",
+ (void**)&this->public.request_handshake_retry) != TNC_RESULT_SUCCESS)
+ {
+ this->public.request_handshake_retry = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCS_SendMessage",
+ (void**)&this->send_message) != TNC_RESULT_SUCCESS)
+ {
+ this->send_message = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCS_SendMessageLong",
+ (void**)&this->send_message_long) != TNC_RESULT_SUCCESS)
+ {
+ this->send_message_long = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCS_ProvideRecommendation",
+ (void**)&this->provide_recommendation) != TNC_RESULT_SUCCESS)
+ {
+ this->provide_recommendation = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCS_GetAttribute",
+ (void**)&this->get_attribute) != TNC_RESULT_SUCCESS)
+ {
+ this->get_attribute = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCS_SetAttribute",
+ (void**)&this->set_attribute) != TNC_RESULT_SUCCESS)
+ {
+ this->set_attribute = NULL;
+ }
+ if (bind_function(this->id, "TNC_TNCC_ReserveAdditionalIMVID",
+ (void**)&this->reserve_additional_id) != TNC_RESULT_SUCCESS)
+ {
+ this->reserve_additional_id = NULL;
+ }
+ DBG2(DBG_IMV, "IMV %u \"%s\" provided with bind function",
+ this->id, this->name);
+
+ if (this->report_message_types_long)
+ {
+ this->report_message_types_long(this->id, &this->vendor_id,
+ &this->subtype, 1);
+ }
+ else if (this->report_message_types &&
+ this->vendor_id <= TNC_VENDORID_ANY &&
+ this->subtype <= TNC_SUBTYPE_ANY)
+ {
+ TNC_MessageType type;
+
+ type = (this->vendor_id << 8) | this->subtype;
+ this->report_message_types(this->id, &type, 1);
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * finds a connection state based on its Connection ID
+ */
+static imv_state_t* find_connection(private_imv_agent_t *this,
+ TNC_ConnectionID id)
+{
+ enumerator_t *enumerator;
+ imv_state_t *state, *found = NULL;
+
+ this->connection_lock->read_lock(this->connection_lock);
+ enumerator = this->connections->create_enumerator(this->connections);
+ while (enumerator->enumerate(enumerator, &state))
+ {
+ if (id == state->get_connection_id(state))
+ {
+ found = state;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->connection_lock->unlock(this->connection_lock);
+
+ return found;
+}
+
+/**
+ * delete a connection state with a given Connection ID
+ */
+static bool delete_connection(private_imv_agent_t *this, TNC_ConnectionID id)
+{
+ enumerator_t *enumerator;
+ imv_state_t *state;
+ bool found = FALSE;
+
+ this->connection_lock->write_lock(this->connection_lock);
+ enumerator = this->connections->create_enumerator(this->connections);
+ while (enumerator->enumerate(enumerator, &state))
+ {
+ if (id == state->get_connection_id(state))
+ {
+ found = TRUE;
+ state->destroy(state);
+ this->connections->remove_at(this->connections, enumerator);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->connection_lock->unlock(this->connection_lock);
+
+ return found;
+}
+
+/**
+ * Read a boolean attribute
+ */
+static bool get_bool_attribute(private_imv_agent_t *this, TNC_ConnectionID id,
+ TNC_AttributeID attribute_id)
+{
+ TNC_UInt32 len;
+ char buf[4];
+
+ return this->get_attribute &&
+ this->get_attribute(this->id, id, attribute_id, 4, buf, &len) ==
+ TNC_RESULT_SUCCESS && len == 1 && *buf == 0x01;
+ }
+
+/**
+ * Read a string attribute
+ */
+static char* get_str_attribute(private_imv_agent_t *this, TNC_ConnectionID id,
+ TNC_AttributeID attribute_id)
+{
+ TNC_UInt32 len;
+ char buf[BUF_LEN];
+
+ if (this->get_attribute &&
+ this->get_attribute(this->id, id, attribute_id, BUF_LEN, buf, &len) ==
+ TNC_RESULT_SUCCESS && len <= BUF_LEN)
+ {
+ return strdup(buf);
+ }
+ return NULL;
+ }
+
+METHOD(imv_agent_t, create_state, TNC_Result,
+ private_imv_agent_t *this, imv_state_t *state)
+{
+ TNC_ConnectionID conn_id;
+ char *tnccs_p = NULL, *tnccs_v = NULL, *t_p = NULL, *t_v = NULL;
+ bool has_long = FALSE, has_excl = FALSE, has_soh = FALSE;
+
+ conn_id = state->get_connection_id(state);
+ if (find_connection(this, conn_id))
+ {
+ DBG1(DBG_IMV, "IMV %u \"%s\" already created a state for Connection ID %u",
+ this->id, this->name, conn_id);
+ state->destroy(state);
+ return TNC_RESULT_OTHER;
+ }
+
+ /* Get and display attributes from TNCS via IF-IMV */
+ has_long = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_LONG_TYPES);
+ has_excl = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_EXCLUSIVE);
+ has_soh = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_SOH);
+ tnccs_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL);
+ tnccs_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_VERSION);
+ t_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_PROTOCOL);
+ t_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_VERSION);
+
+ state->set_flags(state, has_long, has_excl);
+
+ DBG2(DBG_IMV, "IMV %u \"%s\" created a state for Connection ID %u: "
+ "%s %s with %slong %sexcl %ssoh over %s %s",
+ this->id, this->name, conn_id, tnccs_p ? tnccs_p:"?",
+ tnccs_v ? tnccs_v:"?", has_long ? "+":"-", has_excl ? "+":"-",
+ has_soh ? "+":"-", t_p ? t_p:"?", t_v ? t_v :"?");
+ free(tnccs_p);
+ free(tnccs_v);
+ free(t_p);
+ free(t_v);
+
+ this->connection_lock->write_lock(this->connection_lock);
+ this->connections->insert_last(this->connections, state);
+ this->connection_lock->unlock(this->connection_lock);
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imv_agent_t, delete_state, TNC_Result,
+ private_imv_agent_t *this, TNC_ConnectionID connection_id)
+{
+ if (!delete_connection(this, connection_id))
+ {
+ DBG1(DBG_IMV, "IMV %u \"%s\" has no state for Connection ID %u",
+ this->id, this->name, connection_id);
+ return TNC_RESULT_FATAL;
+ }
+ DBG2(DBG_IMV, "IMV %u \"%s\" deleted the state of Connection ID %u",
+ this->id, this->name, connection_id);
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imv_agent_t, change_state, TNC_Result,
+ private_imv_agent_t *this, TNC_ConnectionID connection_id,
+ TNC_ConnectionState new_state,
+ imv_state_t **state_p)
+{
+ imv_state_t *state;
+
+ switch (new_state)
+ {
+ case TNC_CONNECTION_STATE_HANDSHAKE:
+ case TNC_CONNECTION_STATE_ACCESS_ALLOWED:
+ case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
+ case TNC_CONNECTION_STATE_ACCESS_NONE:
+ state = find_connection(this, connection_id);
+ if (!state)
+ {
+ DBG1(DBG_IMV, "IMV %u \"%s\" has no state for Connection ID %u",
+ this->id, this->name, connection_id);
+ return TNC_RESULT_FATAL;
+ }
+ state->change_state(state, new_state);
+ DBG2(DBG_IMV, "IMV %u \"%s\" changed state of Connection ID %u to '%N'",
+ this->id, this->name, connection_id,
+ TNC_Connection_State_names, new_state);
+ if (state_p)
+ {
+ *state_p = state;
+ }
+ break;
+ case TNC_CONNECTION_STATE_CREATE:
+ DBG1(DBG_IMV, "state '%N' should be handled by create_state()",
+ TNC_Connection_State_names, new_state);
+ return TNC_RESULT_FATAL;
+ case TNC_CONNECTION_STATE_DELETE:
+ DBG1(DBG_IMV, "state '%N' should be handled by delete_state()",
+ TNC_Connection_State_names, new_state);
+ return TNC_RESULT_FATAL;
+ default:
+ DBG1(DBG_IMV, "IMV %u \"%s\" was notified of unknown state %u "
+ "for Connection ID %u",
+ this->id, this->name, new_state, connection_id);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imv_agent_t, get_state, bool,
+ private_imv_agent_t *this, TNC_ConnectionID connection_id,
+ imv_state_t **state)
+{
+ *state = find_connection(this, connection_id);
+ if (!*state)
+ {
+ DBG1(DBG_IMV, "IMV %u \"%s\" has no state for Connection ID %u",
+ this->id, this->name, connection_id);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+METHOD(imv_agent_t, send_message, TNC_Result,
+ private_imv_agent_t *this, TNC_ConnectionID connection_id, bool excl,
+ TNC_UInt32 src_imv_id, TNC_UInt32 dst_imc_id, chunk_t msg)
+{
+ TNC_MessageType type;
+ TNC_UInt32 msg_flags;
+ imv_state_t *state;
+
+ state = find_connection(this, connection_id);
+ if (!state)
+ {
+ DBG1(DBG_IMV, "IMV %u \"%s\" has no state for Connection ID %u",
+ this->id, this->name, connection_id);
+ return TNC_RESULT_FATAL;
+ }
+
+ if (state->has_long(state) && this->send_message_long)
+ {
+ if (!src_imv_id)
+ {
+ src_imv_id = this->id;
+ }
+ msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0;
+
+ return this->send_message_long(src_imv_id, connection_id, msg_flags,
+ msg.ptr, msg.len, this->vendor_id,
+ this->subtype, dst_imc_id);
+ }
+ if (this->send_message)
+ {
+ type = (this->vendor_id << 8) | this->subtype;
+
+ return this->send_message(this->id, connection_id, msg.ptr, msg.len,
+ type);
+ }
+ return TNC_RESULT_FATAL;
+}
+
+METHOD(imv_agent_t, set_recommendation, TNC_Result,
+ private_imv_agent_t *this, TNC_ConnectionID connection_id,
+ TNC_IMV_Action_Recommendation rec,
+ TNC_IMV_Evaluation_Result eval)
+{
+ imv_state_t *state;
+
+ state = find_connection(this, connection_id);
+ if (!state)
+ {
+ DBG1(DBG_IMV, "IMV %u \"%s\" has no state for Connection ID %u",
+ this->id, this->name, connection_id);
+ return TNC_RESULT_FATAL;
+ }
+
+ state->set_recommendation(state, rec, eval);
+ return this->provide_recommendation(this->id, connection_id, rec, eval);
+}
+
+METHOD(imv_agent_t, receive_message, TNC_Result,
+ private_imv_agent_t *this, imv_state_t *state, chunk_t msg,
+ TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imc_id, TNC_UInt32 dst_imv_id, pa_tnc_msg_t **pa_tnc_msg)
+{
+ pa_tnc_msg_t *pa_msg, *error_msg;
+ pa_tnc_attr_t *error_attr;
+ enumerator_t *enumerator;
+ TNC_MessageType msg_type;
+ TNC_UInt32 msg_flags, src_imv_id, dst_imc_id;
+ TNC_ConnectionID connection_id;
+ TNC_Result result;
+
+ connection_id = state->get_connection_id(state);
+
+ if (state->has_long(state))
+ {
+ if (dst_imv_id != TNC_IMVID_ANY)
+ {
+ DBG2(DBG_IMV, "IMV %u \"%s\" received message for Connection ID %u "
+ "from IMC %u to IMV %u", this->id, this->name,
+ connection_id, src_imc_id, dst_imv_id);
+ }
+ else
+ {
+ DBG2(DBG_IMV, "IMV %u \"%s\" received message for Connection ID %u "
+ "from IMC %u", this->id, this->name, connection_id,
+ src_imc_id);
+ }
+ }
+ else
+ {
+ DBG2(DBG_IMV, "IMV %u \"%s\" received message for Connection ID %u",
+ this->id, this->name, connection_id);
+ }
+
+ *pa_tnc_msg = NULL;
+ pa_msg = pa_tnc_msg_create_from_data(msg);
+
+ switch (pa_msg->process(pa_msg))
+ {
+ case SUCCESS:
+ *pa_tnc_msg = pa_msg;
+ break;
+ case VERIFY_ERROR:
+ /* build error message */
+ error_msg = pa_tnc_msg_create();
+ enumerator = pa_msg->create_error_enumerator(pa_msg);
+ while (enumerator->enumerate(enumerator, &error_attr))
+ {
+ error_msg->add_attribute(error_msg,
+ error_attr->get_ref(error_attr));
+ }
+ enumerator->destroy(enumerator);
+ error_msg->build(error_msg);
+
+ /* send error message */
+ msg = error_msg->get_encoding(error_msg);
+
+ if (state->has_long(state) && this->send_message_long)
+ {
+ if (state->has_excl(state))
+ {
+ msg_flags = TNC_MESSAGE_FLAGS_EXCLUSIVE;
+ dst_imc_id = src_imc_id;
+ }
+ else
+ {
+ msg_flags = 0;
+ dst_imc_id = TNC_IMCID_ANY;
+ }
+ src_imv_id = (dst_imv_id == TNC_IMVID_ANY) ? this->id
+ : dst_imv_id;
+
+ result = this->send_message_long(src_imv_id, connection_id,
+ msg_flags, msg.ptr, msg.len, msg_vid,
+ msg_subtype, dst_imc_id);
+ }
+ else if (this->send_message)
+ {
+ msg_type = (msg_vid << 8) | msg_subtype;
+
+ result = this->send_message(this->id, connection_id,
+ msg.ptr, msg.len, msg_type);
+ }
+ else
+ {
+ result = TNC_RESULT_FATAL;
+ }
+
+ /* clean up */
+ error_msg->destroy(error_msg);
+ pa_msg->destroy(pa_msg);
+ return result;
+ case FAILED:
+ default:
+ pa_msg->destroy(pa_msg);
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
+ TNC_IMV_EVALUATION_RESULT_ERROR);
+ return this->provide_recommendation(this->id, connection_id,
+ TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
+ TNC_IMV_EVALUATION_RESULT_ERROR);
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imv_agent_t, provide_recommendation, TNC_Result,
+ private_imv_agent_t *this, TNC_ConnectionID connection_id)
+{
+ imv_state_t *state;
+ TNC_IMV_Action_Recommendation rec;
+ TNC_IMV_Evaluation_Result eval;
+ TNC_UInt32 lang_len;
+ char buf[BUF_LEN];
+ chunk_t pref_lang = { buf, 0 }, reason_string, reason_lang;
+
+ state = find_connection(this, connection_id);
+ if (!state)
+ {
+ DBG1(DBG_IMV, "IMV %u \"%s\" has no state for Connection ID %u",
+ this->id, this->name, connection_id);
+ return TNC_RESULT_FATAL;
+ }
+ state->get_recommendation(state, &rec, &eval);
+
+
+ /* send a reason string if action recommendation is not allow */
+ if (rec != TNC_IMV_ACTION_RECOMMENDATION_ALLOW)
+ {
+ /* check if there a preferred language has been requested */
+ if (this->get_attribute &&
+ this->get_attribute(this->id, connection_id,
+ TNC_ATTRIBUTEID_PREFERRED_LANGUAGE, BUF_LEN,
+ buf, &lang_len) == TNC_RESULT_SUCCESS &&
+ lang_len <= BUF_LEN)
+ {
+ pref_lang.len = lang_len;
+ DBG2(DBG_IMV, "preferred language is '%.*s'",
+ pref_lang.len, pref_lang.ptr);
+ }
+
+ /* find a reason string for the preferred or default language and set it */
+ if (this->set_attribute &&
+ state->get_reason_string(state, pref_lang, &reason_string,
+ &reason_lang))
+ {
+ this->set_attribute(this->id, connection_id,
+ TNC_ATTRIBUTEID_REASON_STRING,
+ reason_string.len, reason_string.ptr);
+ this->set_attribute(this->id, connection_id,
+ TNC_ATTRIBUTEID_REASON_LANGUAGE,
+ reason_lang.len, reason_lang.ptr);
+ }
+ }
+
+ return this->provide_recommendation(this->id, connection_id, rec, eval);
+}
+
+METHOD(imv_agent_t, reserve_additional_ids, TNC_Result,
+ private_imv_agent_t *this, int count)
+{
+ TNC_Result result;
+ TNC_UInt32 id;
+ void *pointer;
+
+ if (!this->reserve_additional_id)
+ {
+ DBG1(DBG_IMV, "IMV %u \"%s\" did not detect the capability to reserve "
+ "additional IMV IDs from the TNCS", this->id, this->name);
+ return TNC_RESULT_ILLEGAL_OPERATION;
+ }
+ while (count > 0)
+ {
+ result = this->reserve_additional_id(this->id, &id);
+ if (result != TNC_RESULT_SUCCESS)
+ {
+ DBG1(DBG_IMV, "IMV %u \"%s\" failed to reserve %d additional IMV IDs",
+ this->id, this->name, count);
+ return result;
+ }
+ count--;
+
+ /* store the scalar value in the pointer */
+ pointer = (void*)id;
+ this->additional_ids->insert_last(this->additional_ids, pointer);
+ DBG2(DBG_IMV, "IMV %u \"%s\" reserved additional ID %u",
+ this->id, this->name, id);
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imv_agent_t, count_additional_ids, int,
+ private_imv_agent_t *this)
+{
+ return this->additional_ids->get_count(this->additional_ids);
+}
+
+METHOD(imv_agent_t, create_id_enumerator, enumerator_t*,
+ private_imv_agent_t *this)
+{
+ return this->additional_ids->create_enumerator(this->additional_ids);
+}
+
+METHOD(imv_agent_t, destroy, void,
+ private_imv_agent_t *this)
+{
+ DBG1(DBG_IMV, "IMV %u \"%s\" terminated", this->id, this->name);
+ this->additional_ids->destroy(this->additional_ids);
+ this->connections->destroy_offset(this->connections,
+ offsetof(imv_state_t, destroy));
+ this->connection_lock->destroy(this->connection_lock);
+ free(this);
+
+ /* decrease the reference count or terminate */
+ libimcv_deinit();
+}
+
+/**
+ * Described in header.
+ */
+imv_agent_t *imv_agent_create(const char *name,
+ pen_t vendor_id, u_int32_t subtype,
+ TNC_IMVID id, TNC_Version *actual_version)
+{
+ private_imv_agent_t *this;
+
+ /* initialize or increase the reference count */
+ if (!libimcv_init())
+ {
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .bind_functions = _bind_functions,
+ .create_state = _create_state,
+ .delete_state = _delete_state,
+ .change_state = _change_state,
+ .get_state = _get_state,
+ .send_message = _send_message,
+ .receive_message = _receive_message,
+ .set_recommendation = _set_recommendation,
+ .provide_recommendation = _provide_recommendation,
+ .reserve_additional_ids = _reserve_additional_ids,
+ .count_additional_ids = _count_additional_ids,
+ .create_id_enumerator = _create_id_enumerator,
+ .destroy = _destroy,
+ },
+ .name = name,
+ .vendor_id = vendor_id,
+ .subtype = subtype,
+ .id = id,
+ .additional_ids = linked_list_create(),
+ .connections = linked_list_create(),
+ .connection_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
+
+ *actual_version = TNC_IFIMV_VERSION_1;
+ DBG1(DBG_IMV, "IMV %u \"%s\" initialized", this->id, this->name);
+
+ return &this->public;
+}
+
+
diff --git a/src/libimcv/imv/imv_agent.h b/src/libimcv/imv/imv_agent.h
new file mode 100644
index 000000000..de70f3bc1
--- /dev/null
+++ b/src/libimcv/imv/imv_agent.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2011 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 imv_agent_t imv_agent
+ * @{ @ingroup imv_agent
+ */
+
+#ifndef IMV_AGENT_H_
+#define IMV_AGENT_H_
+
+#include "imv_state.h"
+#include "pa_tnc/pa_tnc_msg.h"
+
+#include <tncifimv.h>
+#include <pen/pen.h>
+
+#include <library.h>
+
+typedef struct imv_agent_t imv_agent_t;
+
+/**
+ * Core functions of an Integrity Measurement Verifier (IMV)
+ */
+struct imv_agent_t {
+
+ /**
+ * Ask a TNCS to retry an Integrity Check Handshake
+ *
+ * @param imv_id IMV ID assigned by TNCS
+ * @param connection_id network connection ID assigned by TNCS
+ * @param reason IMV retry reason
+ * @return TNC result code
+ */
+ TNC_Result (*request_handshake_retry)(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_RetryReason reason);
+
+ /**
+ * Bind TNCS functions
+ *
+ * @param bind_function function offered by the TNCS
+ * @return TNC result code
+ */
+ TNC_Result (*bind_functions)(imv_agent_t *this,
+ TNC_TNCS_BindFunctionPointer bind_function);
+
+ /**
+ * Create the IMV state for a TNCCS connection instance
+ *
+ * @param state internal IMV state instance
+ * @return TNC result code
+ */
+ TNC_Result (*create_state)(imv_agent_t *this, imv_state_t *state);
+
+ /**
+ * Delete the IMV state for a TNCCS connection instance
+ *
+ * @param connection_id network connection ID assigned by TNCS
+ * @return TNC result code
+ */
+ TNC_Result (*delete_state)(imv_agent_t *this,
+ TNC_ConnectionID connection_id);
+
+ /**
+ * Change the current state of a TNCCS connection
+ *
+ * @param connection_id network connection ID assigned by TNCS
+ * @param new_state new state of TNCCS connection
+ * @param state_p internal IMV state instance [optional argument]
+ * @return TNC result code
+ */
+ TNC_Result (*change_state)(imv_agent_t *this,
+ TNC_ConnectionID connection_id,
+ TNC_ConnectionState new_state,
+ imv_state_t **state_p);
+
+ /**
+ * Get the IMV state for a TNCCS connection instance
+ *
+ * @param connection_id network connection ID assigned by TNCS
+ * @param state internal IMV state instance
+ * @return TRUE if the state was found
+ */
+ bool (*get_state)(imv_agent_t *this,
+ TNC_ConnectionID connection_id, imv_state_t **state);
+
+ /**
+ * Call when a PA-TNC message is to be sent
+ *
+ * @param connection_id network connection ID assigned by TNCS
+ * @param excl exclusive flag
+ * @param src_imv_id IMV ID to be set as source
+ * @param dst_imc_id IMD ID to be set as destination
+ * @param msg message to send
+ * @return TNC result code
+ */
+ TNC_Result (*send_message)(imv_agent_t *this,
+ TNC_ConnectionID connection_id, bool excl,
+ TNC_UInt32 src_imv_id, TNC_UInt32 dst_imc_id,
+ chunk_t msg);
+
+ /**
+ * Call when a PA-TNC message was received
+ *
+ * @param state state for current connection
+ * @param msg received unparsed message
+ * @param msg_vid message vendorID of the received message
+ * @param msg_subtype message subtype of the received message
+ * @param src_imc_id source IMC ID
+ * @param dst_imv_id destination IMV ID
+ * @param pa_tnc_message parsed PA-TNC message or NULL if an error occurred
+ * @return TNC result code
+ */
+ TNC_Result (*receive_message)(imv_agent_t *this,
+ imv_state_t *state, chunk_t msg,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id,
+ pa_tnc_msg_t **pa_tnc_msg);
+
+ /**
+ * Set Action Recommendation and Evaluation Result in the IMV state
+ *
+ * @param connection_id network connection ID assigned by TNCS
+ * @param rec IMV action recommendation
+ * @param eval IMV evaluation result
+ * @return TNC result code
+ */
+ TNC_Result (*set_recommendation)(imv_agent_t *this,
+ TNC_ConnectionID connection_id,
+ TNC_IMV_Action_Recommendation rec,
+ TNC_IMV_Evaluation_Result eval);
+
+ /**
+ * Deliver IMV Action Recommendation and IMV Evaluation Result to the TNCS
+ *
+ * @param connection_id network connection ID assigned by TNCS
+ * @return TNC result code
+ */
+ TNC_Result (*provide_recommendation)(imv_agent_t *this,
+ TNC_ConnectionID connection_id);
+
+ /**
+ * Reserve additional IMV IDs from TNCS
+ *
+ * @param count number of additional IMV IDs to be assigned
+ * @return TNC result code
+ */
+ TNC_Result (*reserve_additional_ids)(imv_agent_t *this, int count);
+
+ /**
+ * Return the number of additional IMV IDs assigned by the TNCS
+ *
+ * @return number of additional IMV IDs
+ */
+ int (*count_additional_ids)(imv_agent_t *this);
+
+ /**
+ * Create an enumerator for the additional IMV IDs
+ */
+ enumerator_t* (*create_id_enumerator)(imv_agent_t *this);
+
+ /**
+ * Destroys an imv_agent_t object
+ */
+ void (*destroy)(imv_agent_t *this);
+};
+
+/**
+ * Create an imv_agent_t object
+ *
+ * @param name name of the IMV
+ * @param vendor_id vendor ID of the IMV
+ * @param subtype message subtype of the IMV
+ * @param id ID of the IMV as assigned by the TNCS
+ * @param actual_version actual version of the IF-IMV API
+ *
+ */
+imv_agent_t *imv_agent_create(const char *name,
+ pen_t vendor_id, u_int32_t subtype,
+ TNC_IMVID id, TNC_Version *actual_version);
+
+#endif /** IMV_AGENT_H_ @}*/
diff --git a/src/libimcv/imv/imv_state.h b/src/libimcv/imv/imv_state.h
new file mode 100644
index 000000000..9e7a29a9f
--- /dev/null
+++ b/src/libimcv/imv/imv_state.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2011 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 imv_state_t imv_state
+ * @{ @ingroup imv_state
+ */
+
+#ifndef IMV_STATE_H_
+#define IMV_STATE_H_
+
+#include <tncifimv.h>
+
+#include <library.h>
+
+typedef struct imv_state_t imv_state_t;
+
+/**
+ * Internal state of an IMV connection instance
+ */
+struct imv_state_t {
+
+ /**
+ * Get the TNCS connection ID attached to the state
+ *
+ * @return TNCS connection ID of the state
+ */
+ TNC_ConnectionID (*get_connection_id)(imv_state_t *this);
+
+ /**
+ * Checks if long message types are supported for this TNCCS connection
+ *
+ * @return TRUE if set, FALSE otherwise
+ */
+ bool (*has_long)(imv_state_t *this);
+
+ /**
+ * Checks if the exclusive delivery is supported for this TNCCS connection
+ *
+ * @return TRUE if set, FALSE otherwise
+ */
+ bool (*has_excl)(imv_state_t *this);
+
+ /**
+ * Sets the long message types and exclusive flags for this TNCCS connection
+ *
+ * @param has_long TNCCS connection supports long message types
+ * @param has_excl TNCCS connection supports exclusive delivery
+ * @return TRUE if set, FALSE otherwise
+ */
+ void (*set_flags)(imv_state_t *this, bool has_long, bool has_excl);
+
+ /**
+ * Change the connection state
+ *
+ * @param new_state new connection state
+ */
+ void (*change_state)(imv_state_t *this, TNC_ConnectionState new_state);
+
+ /**
+ * Get IMV action recommendation and evaluation result
+ *
+ * @param rec IMV action recommendation
+ * @param eval IMV evaluation result
+ *
+ */
+ void (*get_recommendation)(imv_state_t *this,
+ TNC_IMV_Action_Recommendation *rec,
+ TNC_IMV_Evaluation_Result *eval);
+
+ /**
+ * Set IMV action recommendation and evaluation result
+ *
+ * @param rec IMV action recommendation
+ * @param eval IMV evaluation result
+ *
+ */
+ void (*set_recommendation)(imv_state_t *this,
+ TNC_IMV_Action_Recommendation rec,
+ TNC_IMV_Evaluation_Result eval);
+
+ /**
+ * Get reason string based on the preferred language
+ *
+ * @param preferred_language preferred language
+ * @param reason_string reason string
+ * @param language code language of the returned reason string
+ * @return TRUE if a reason string was found
+ */
+ bool (*get_reason_string)(imv_state_t *this, chunk_t preferred_language,
+ chunk_t *reason_string, chunk_t *language_code);
+
+ /**
+ * Destroys an imv_state_t object
+ */
+ void (*destroy)(imv_state_t *this);
+};
+
+#endif /** IMV_STATE_H_ @}*/
diff --git a/src/libimcv/ita/ita_attr.c b/src/libimcv/ita/ita_attr.c
new file mode 100644
index 000000000..ec23c11ea
--- /dev/null
+++ b/src/libimcv/ita/ita_attr.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 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 "ita_attr.h"
+#include "ita/ita_attr_command.h"
+
+ENUM(ita_attr_names, ITA_ATTR_COMMAND, ITA_ATTR_COMMAND,
+ "Command",
+);
+
+/**
+ * See header
+ */
+pa_tnc_attr_t* ita_attr_create_from_data(u_int32_t type, chunk_t value)
+{
+ switch (type)
+ {
+ case ITA_ATTR_COMMAND:
+ return ita_attr_command_create_from_data(value);
+ default:
+ return NULL;
+ }
+}
diff --git a/src/libimcv/ita/ita_attr.h b/src/libimcv/ita/ita_attr.h
new file mode 100644
index 000000000..82debdd1e
--- /dev/null
+++ b/src/libimcv/ita/ita_attr.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2011 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 ita_attrt ita_attr
+ * @{ @ingroup ita_attr
+ */
+
+#ifndef ITA_ATTR_H_
+#define ITA_ATTR_H_
+
+#include "pa_tnc/pa_tnc_attr.h"
+
+#include <library.h>
+
+typedef enum ita_attr_t ita_attr_t;
+
+/**
+ * IETF standard PA-TNC attribute types defined by RFC 5792
+ */
+enum ita_attr_t {
+ ITA_ATTR_COMMAND = 1,
+};
+
+/**
+ * enum name for ita_attr_t.
+ */
+extern enum_name_t *ita_attr_names;
+
+/**
+ * Create a ITA PA-TNC attribute from data
+ *
+ * @param type attribute type
+ * @param value attribute value
+ */
+pa_tnc_attr_t* ita_attr_create_from_data(u_int32_t type, chunk_t value);
+
+#endif /** ITA_ATTR_H_ @}*/
diff --git a/src/libimcv/ita/ita_attr_command.c b/src/libimcv/ita/ita_attr_command.c
new file mode 100644
index 000000000..5c1577a7c
--- /dev/null
+++ b/src/libimcv/ita/ita_attr_command.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2011 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 "ita_attr.h"
+#include "ita_attr_command.h"
+
+#include <pen/pen.h>
+
+#include <debug.h>
+
+typedef struct private_ita_attr_command_t private_ita_attr_command_t;
+
+/**
+ * Private data of an ita_attr_command_t object.
+ */
+struct private_ita_attr_command_t {
+
+ /**
+ * Public members of ita_attr_command_t
+ */
+ ita_attr_command_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Command string
+ */
+ char *command;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_ita_attr_command_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_ita_attr_command_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_ita_attr_command_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_ita_attr_command_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_ita_attr_command_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_ita_attr_command_t *this)
+{
+ this->value = chunk_create(this->command, strlen(this->command));
+ this->value = chunk_clone(this->value);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_ita_attr_command_t *this, u_int32_t *offset)
+{
+ this->command = malloc(this->value.len + 1);
+ memcpy(this->command, this->value.ptr, this->value.len);
+ this->command[this->value.len] = '\0';
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_ita_attr_command_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_ita_attr_command_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this->command);
+ free(this);
+ }
+}
+
+METHOD(ita_attr_command_t, get_command, char*,
+ private_ita_attr_command_t *this)
+{
+ return this->command;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ita_attr_command_create(char *command)
+{
+ private_ita_attr_command_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_command = _get_command,
+ },
+ .vendor_id = PEN_ITA,
+ .type = ITA_ATTR_COMMAND,
+ .command = strdup(command),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ita_attr_command_create_from_data(chunk_t data)
+{
+ private_ita_attr_command_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_command = _get_command,
+ },
+ .vendor_id = PEN_ITA,
+ .type = ITA_ATTR_COMMAND,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
diff --git a/src/libimcv/ita/ita_attr_command.h b/src/libimcv/ita/ita_attr_command.h
new file mode 100644
index 000000000..372355197
--- /dev/null
+++ b/src/libimcv/ita/ita_attr_command.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 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 ita_attr_commandt ita_attr_command
+ * @{ @ingroup ita_attr_command
+ */
+
+#ifndef ITA_ATTR_COMMAND_H_
+#define ITA_ATTR_COMMAND_H_
+
+typedef struct ita_attr_command_t ita_attr_command_t;
+
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the ITA Command PA-TNC attribute.
+ *
+ */
+struct ita_attr_command_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get the ITA command string
+ *
+ * @return ITA command string
+ */
+ char* (*get_command)(ita_attr_command_t *this);
+};
+
+/**
+ * Creates an ita_attr_command_t object from a command string
+ *
+ * @param command ITA command string
+ */
+pa_tnc_attr_t* ita_attr_command_create(char *command);
+
+/**
+ * Creates an ita_attr_command_t object from received data
+ *
+ * @param command ITA command string
+ */
+pa_tnc_attr_t* ita_attr_command_create_from_data(chunk_t value);
+
+#endif /** ITA_ATTR_COMMAND_H_ @}*/
diff --git a/src/libimcv/pa_tnc/pa_tnc_attr.h b/src/libimcv/pa_tnc/pa_tnc_attr.h
new file mode 100644
index 000000000..b6057a70b
--- /dev/null
+++ b/src/libimcv/pa_tnc/pa_tnc_attr.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 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 pa_tnc_attr pa_tnc_attr
+ * @{ @ingroup libimcv
+ */
+
+#ifndef PA_TNC_ATTR_H_
+#define PA_TNC_ATTR_H_
+
+typedef struct pa_tnc_attr_t pa_tnc_attr_t;
+
+#include <library.h>
+#include <pen/pen.h>
+
+/**
+ * Interface for an RFC 5792 PA-TNC Posture Attribute.
+ *
+ */
+struct pa_tnc_attr_t {
+
+ /**
+ * Get the vendor ID of an PA-TNC attribute
+ *
+ * @return attribute vendor ID
+ */
+ u_int32_t (*get_vendor_id)(pa_tnc_attr_t *this);
+
+ /**
+ * Get the type of an PA-TNC attribute
+ *
+ * @return attribute type
+ */
+ u_int32_t (*get_type)(pa_tnc_attr_t *this);
+
+ /**
+ * Get the value of an PA-TNC attribute
+ *
+ * @return attribute value
+ */
+ chunk_t (*get_value)(pa_tnc_attr_t *this);
+
+ /**
+ * Get the noskip flag
+ *
+ * @return TRUE if the noskip flag is set
+ */
+ bool (*get_noskip_flag)(pa_tnc_attr_t *this);
+
+ /**
+ * Set the noskip flag
+ *
+ * @param noskip_flag TRUE if the noskip flag is to be set
+ */
+ void (*set_noskip_flag)(pa_tnc_attr_t *this, bool noskip);
+
+ /**
+ * Build value of an PA-TNC attribute from its parameters
+ */
+ void (*build)(pa_tnc_attr_t *this);
+
+ /**
+ * Process the value of an PA-TNC attribute to extract its parameters
+ *
+ * @param relative error offset within attribute body
+ * @return result status
+ */
+ status_t (*process)(pa_tnc_attr_t *this, u_int32_t *offset);
+
+ /**
+ * Get a new reference to the PA-TNC attribute
+ *
+ * @return this, with an increased refcount
+ */
+ pa_tnc_attr_t* (*get_ref)(pa_tnc_attr_t *this);
+
+ /**
+ * Destroys a pa_tnc_attr_t object.
+ */
+ void (*destroy)(pa_tnc_attr_t *this);
+};
+
+#endif /** PA_TNC_ATTR_H_ @}*/
diff --git a/src/libimcv/pa_tnc/pa_tnc_attr_manager.c b/src/libimcv/pa_tnc/pa_tnc_attr_manager.c
new file mode 100644
index 000000000..1de89d87d
--- /dev/null
+++ b/src/libimcv/pa_tnc/pa_tnc_attr_manager.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2011 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 "pa_tnc_attr_manager.h"
+
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_pa_tnc_attr_manager_t private_pa_tnc_attr_manager_t;
+typedef struct entry_t entry_t;
+
+struct entry_t {
+ pen_t vendor_id;
+ enum_name_t *attr_names;
+ pa_tnc_attr_create_t attr_create;
+};
+
+/**
+ * Private data of a pa_tnc_attr_manager_t object.
+ *
+ */
+struct private_pa_tnc_attr_manager_t {
+
+ /**
+ * Public pa_tnc_attr_manager_t interface.
+ */
+ pa_tnc_attr_manager_t public;
+
+ /**
+ * List of PA-TNC vendor attributes
+ */
+ linked_list_t *list;
+};
+
+METHOD(pa_tnc_attr_manager_t, add_vendor, void,
+ private_pa_tnc_attr_manager_t *this, pen_t vendor_id,
+ pa_tnc_attr_create_t attr_create, enum_name_t *attr_names)
+{
+ entry_t *entry;
+
+ entry = malloc_thing(entry_t);
+ entry->vendor_id = vendor_id;
+ entry->attr_create = attr_create;
+ entry->attr_names = attr_names;
+
+ this->list->insert_last(this->list, entry);
+ DBG2(DBG_TNC, "added %N attributes", pen_names, vendor_id);
+}
+
+METHOD(pa_tnc_attr_manager_t, remove_vendor, void,
+ private_pa_tnc_attr_manager_t *this, pen_t vendor_id)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ this->list->remove_at(this->list, enumerator);
+ free(entry);
+ DBG2(DBG_TNC, "removed %N attributes", pen_names, vendor_id);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(pa_tnc_attr_manager_t, get_names, enum_name_t*,
+ private_pa_tnc_attr_manager_t *this, pen_t vendor_id)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ enum_name_t *attr_names = NULL;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ attr_names = entry->attr_names;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return attr_names;
+}
+
+METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
+ private_pa_tnc_attr_manager_t *this, pen_t vendor_id, u_int32_t type,
+ chunk_t value)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ pa_tnc_attr_t *attr = NULL;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ if (entry->attr_create)
+ {
+ attr = entry->attr_create(type, value);
+ }
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return attr;
+}
+
+METHOD(pa_tnc_attr_manager_t, destroy, void,
+ private_pa_tnc_attr_manager_t *this)
+{
+ this->list->destroy_function(this->list, free);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pa_tnc_attr_manager_t *pa_tnc_attr_manager_create(void)
+{
+ private_pa_tnc_attr_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .add_vendor = _add_vendor,
+ .remove_vendor = _remove_vendor,
+ .get_names = _get_names,
+ .create = _create,
+ .destroy = _destroy,
+ },
+ .list = linked_list_create(),
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libimcv/pa_tnc/pa_tnc_attr_manager.h b/src/libimcv/pa_tnc/pa_tnc_attr_manager.h
new file mode 100644
index 000000000..40c3ab335
--- /dev/null
+++ b/src/libimcv/pa_tnc/pa_tnc_attr_manager.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 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 pa_tnc_attr_manager pa_tnc_attr_manager
+ * @{ @ingroup libimcv
+ */
+
+#ifndef PA_TNC_ATTR_MANAGER_H_
+#define PA_TNC_ATTR_MANAGER_H_
+
+typedef struct pa_tnc_attr_manager_t pa_tnc_attr_manager_t;
+
+#include "pa_tnc_attr.h"
+
+#include <library.h>
+
+typedef pa_tnc_attr_t* (*pa_tnc_attr_create_t)(u_int32_t type, chunk_t value);
+
+/**
+ * Manages PA-TNC attributes for arbitrary PENs
+ */
+struct pa_tnc_attr_manager_t {
+
+ /**
+ * Add vendor-specific attribute names and creation method
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ * @param attr_create Vendor-specific attribute create method
+ * @param attr_names Vendor-specific attribute names
+ */
+ void (*add_vendor)(pa_tnc_attr_manager_t *this, pen_t vendor_id,
+ pa_tnc_attr_create_t attr_create,
+ enum_name_t *attr_names);
+
+ /**
+ * Remove vendor-specific attribute names and creation method
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ */
+ void (*remove_vendor)(pa_tnc_attr_manager_t *this, pen_t vendor_id);
+
+ /*
+ * Return the PA-TNC attribute names for a given vendor ID
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ * @return PA-TNC attribute names if found, NULL else
+ */
+ enum_name_t* (*get_names)(pa_tnc_attr_manager_t *this, pen_t vendor_id);
+
+ /**
+ * Create a PA-TNC attribute object from data for a given vendor ID and type
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ * @param type PA-TNC attribute type
+ * @param value PA-TNC attribute value as encoded data
+ * @return PA-TNC attribute object if supported, NULL else
+ */
+ pa_tnc_attr_t* (*create)(pa_tnc_attr_manager_t *this, pen_t vendor_id,
+ u_int32_t type, chunk_t value);
+
+ /**
+ * Destroys a pa_tnc_attr_manager_t object.
+ */
+ void (*destroy)(pa_tnc_attr_manager_t *this);
+};
+
+/**
+ * Create a PA-TNC attribute manager
+ */
+pa_tnc_attr_manager_t* pa_tnc_attr_manager_create(void);
+
+#endif /** PA_TNC_ATTR_MANAGER_H_ @}*/
diff --git a/src/libimcv/pa_tnc/pa_tnc_msg.c b/src/libimcv/pa_tnc/pa_tnc_msg.c
new file mode 100644
index 000000000..b5df0a5b5
--- /dev/null
+++ b/src/libimcv/pa_tnc/pa_tnc_msg.c
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2011 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 "imcv.h"
+#include "pa_tnc_msg.h"
+#include "ietf/ietf_attr_pa_tnc_error.h"
+
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/linked_list.h>
+#include <pen/pen.h>
+#include <debug.h>
+
+
+typedef struct private_pa_tnc_msg_t private_pa_tnc_msg_t;
+
+/**
+ * PA-TNC message header
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Message Identifier |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PA_TNC_HEADER_SIZE 8
+#define PA_TNC_RESERVED 0x000000
+
+/**
+ * PA-TNC attribute
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | PA-TNC Attribute Vendor ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | PA-TNC Attribute Type |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | PA-TNC Attribute Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Attribute Value (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PA_TNC_ATTR_FLAG_NONE 0x00
+#define PA_TNC_ATTR_FLAG_NOSKIP (1<<7)
+#define PA_TNC_ATTR_HEADER_SIZE 12
+#define PA_TNC_ATTR_INFO_SIZE 8
+
+/**
+ * Private data of a pa_tnc_msg_t object.
+ *
+ */
+struct private_pa_tnc_msg_t {
+
+ /**
+ * Public pa_tnc_msg_t interface.
+ */
+ pa_tnc_msg_t public;
+
+ /**
+ * List of PA-TNC attributes
+ */
+ linked_list_t *attributes;
+
+ /**
+ * linked list of PA-TNC error messages
+ */
+ linked_list_t *errors;
+
+ /**
+ * Message identifier
+ */
+ u_int32_t identifier;
+
+ /**
+ * Encoded message
+ */
+ chunk_t encoding;
+};
+
+METHOD(pa_tnc_msg_t, get_encoding, chunk_t,
+ private_pa_tnc_msg_t *this)
+{
+ return this->encoding;
+}
+
+METHOD(pa_tnc_msg_t, add_attribute, void,
+ private_pa_tnc_msg_t *this, pa_tnc_attr_t *attr)
+{
+ this->attributes->insert_last(this->attributes, attr);
+}
+
+METHOD(pa_tnc_msg_t, build, void,
+ private_pa_tnc_msg_t *this)
+{
+ bio_writer_t *writer;
+ enumerator_t *enumerator;
+ pa_tnc_attr_t *attr;
+ enum_name_t *pa_attr_names;
+ pen_t vendor_id;
+ u_int32_t type;
+ u_int8_t flags;
+ chunk_t value;
+ rng_t *rng;
+
+ /* create a random message identifier */
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ rng->get_bytes(rng, sizeof(this->identifier), (u_int8_t*)&this->identifier);
+ rng->destroy(rng);
+ DBG2(DBG_TNC, "creating PA-TNC message with ID 0x%08x", this->identifier);
+
+ /* build message header */
+ writer = bio_writer_create(PA_TNC_HEADER_SIZE);
+ writer->write_uint8 (writer, PA_TNC_VERSION);
+ writer->write_uint24(writer, PA_TNC_RESERVED);
+ writer->write_uint32(writer, this->identifier);
+
+ /* build and append encoding of PA-TNC attributes */
+ enumerator = this->attributes->create_enumerator(this->attributes);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ attr->build(attr);
+ vendor_id = attr->get_vendor_id(attr);
+ type = attr->get_type(attr);
+ value = attr->get_value(attr);
+ flags = attr->get_noskip_flag(attr) ? PA_TNC_ATTR_FLAG_NOSKIP :
+ PA_TNC_ATTR_FLAG_NONE;
+
+ pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
+ vendor_id);
+ if (pa_attr_names)
+ {
+ DBG2(DBG_TNC, "creating PA-TNC attribute type '%N/%N' "
+ "0x%06x/0x%08x", pen_names, vendor_id,
+ pa_attr_names, type, vendor_id, type);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "creating PA-TNC attribute type '%N' "
+ "0x%06x/0x%08x", pen_names, vendor_id,
+ vendor_id, type);
+ }
+ DBG3(DBG_TNC, "%B", &value);
+
+ writer->write_uint8 (writer, flags);
+ writer->write_uint24(writer, vendor_id);
+ writer->write_uint32(writer, type);
+ writer->write_uint32(writer, PA_TNC_ATTR_HEADER_SIZE + value.len);
+ writer->write_data (writer, value);
+ }
+ enumerator->destroy(enumerator);
+
+ free(this->encoding.ptr);
+ this->encoding = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_msg_t, process, status_t,
+ private_pa_tnc_msg_t *this)
+{
+ bio_reader_t *reader;
+ pa_tnc_attr_t *error;
+ u_int8_t version;
+ u_int32_t reserved, offset, attr_offset;
+
+ /* process message header */
+ if (this->encoding.len < PA_TNC_HEADER_SIZE)
+ {
+ DBG1(DBG_TNC, "%u bytes insufficient to parse PA-TNC message header",
+ this->encoding.len);
+ return FAILED;
+ }
+ reader = bio_reader_create(this->encoding);
+ reader->read_uint8 (reader, &version);
+ reader->read_uint24(reader, &reserved);
+ reader->read_uint32(reader, &this->identifier);
+ DBG2(DBG_TNC, "processing PA-TNC message with ID 0x%08x", this->identifier);
+
+ if (version != PA_TNC_VERSION)
+ {
+ DBG1(DBG_TNC, "PA-TNC version %u not supported", version);
+ error = ietf_attr_pa_tnc_error_create(PEN_IETF,
+ PA_ERROR_VERSION_NOT_SUPPORTED, this->encoding);
+ goto err;
+ }
+
+ /* offset of the first PA-TNC attribute in the PA-TNC message */
+ offset = PA_TNC_HEADER_SIZE;
+
+ /* pre-process PA-TNC attributes */
+ while (reader->remaining(reader) >= PA_TNC_ATTR_HEADER_SIZE)
+ {
+ pen_t vendor_id;
+ u_int8_t flags;
+ u_int32_t type, length;
+ chunk_t value, attr_info;
+ pa_tnc_attr_t *attr;
+ enum_name_t *pa_attr_names;
+ ietf_attr_pa_tnc_error_t *error_attr;
+
+ attr_info = reader->peek(reader);
+ attr_info.len = PA_TNC_ATTR_INFO_SIZE;
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint24(reader, &vendor_id);
+ reader->read_uint32(reader, &type);
+ reader->read_uint32(reader, &length);
+
+ pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
+ vendor_id);
+ if (pa_attr_names)
+ {
+ DBG2(DBG_TNC, "processing PA-TNC attribute type '%N/%N' "
+ "0x%06x/0x%08x", pen_names, vendor_id,
+ pa_attr_names, type, vendor_id, type);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "processing PA-TNC attribute type '%N' "
+ "0x%06x/0x%08x", pen_names, vendor_id,
+ vendor_id, type);
+ }
+
+ if (length < PA_TNC_ATTR_HEADER_SIZE)
+ {
+ DBG1(DBG_TNC, "%u bytes too small for PA-TNC attribute length",
+ length);
+ error = ietf_attr_pa_tnc_error_create_with_offset(PEN_IETF,
+ PA_ERROR_INVALID_PARAMETER, this->encoding,
+ offset + PA_TNC_ATTR_INFO_SIZE);
+ goto err;
+ }
+
+ if (!reader->read_data(reader, length - PA_TNC_ATTR_HEADER_SIZE, &value))
+ {
+ DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value");
+ error = ietf_attr_pa_tnc_error_create_with_offset(PEN_IETF,
+ PA_ERROR_INVALID_PARAMETER, this->encoding,
+ offset + PA_TNC_ATTR_INFO_SIZE);
+ goto err;
+ }
+ DBG3(DBG_TNC, "%B", &value);
+
+ attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
+ vendor_id, type, value);
+ if (!attr)
+ {
+ if (flags & PA_TNC_ATTR_FLAG_NOSKIP)
+ {
+ DBG1(DBG_TNC, "unsupported PA-TNC attribute with NOSKIP flag");
+ error = ietf_attr_pa_tnc_error_create(PEN_IETF,
+ PA_ERROR_ATTR_TYPE_NOT_SUPPORTED, this->encoding);
+ error_attr = (ietf_attr_pa_tnc_error_t*)error;
+ error_attr->set_attr_info(error_attr, attr_info);
+ goto err;
+ }
+ else
+ {
+ DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
+ offset += length;
+ continue;
+ }
+ }
+
+ if (attr->process(attr, &attr_offset) != SUCCESS)
+ {
+ attr->destroy(attr);
+ if (vendor_id == PEN_IETF && type == IETF_ATTR_PA_TNC_ERROR)
+ {
+ /* error while processing a PA-TNC error attribute - abort */
+ reader->destroy(reader);
+ return FAILED;
+ }
+ error = ietf_attr_pa_tnc_error_create_with_offset(PEN_IETF,
+ PA_ERROR_INVALID_PARAMETER, this->encoding,
+ offset + PA_TNC_ATTR_HEADER_SIZE + attr_offset);
+ goto err;
+ }
+ add_attribute(this, attr);
+ offset += length;
+ }
+
+ if (reader->remaining(reader) == 0)
+ {
+ reader->destroy(reader);
+ return SUCCESS;
+ }
+ DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute header");
+ error = ietf_attr_pa_tnc_error_create_with_offset(PEN_IETF,
+ PA_ERROR_INVALID_PARAMETER, this->encoding, offset);
+
+err:
+ reader->destroy(reader);
+ this->errors->insert_last(this->errors, error);
+ return VERIFY_ERROR;
+}
+
+METHOD(pa_tnc_msg_t, process_ietf_std_errors, bool,
+ private_pa_tnc_msg_t *this)
+{
+ enumerator_t *enumerator;
+ pa_tnc_attr_t *attr;
+ bool fatal_error = FALSE;
+
+ enumerator = this->attributes->create_enumerator(this->attributes);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ if (attr->get_vendor_id(attr) == PEN_IETF &&
+ attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR)
+ {
+ ietf_attr_pa_tnc_error_t *error_attr;
+ pen_t error_vendor_id;
+ pa_tnc_error_code_t error_code;
+ chunk_t msg_info, attr_info;
+ u_int32_t offset;
+
+ error_attr = (ietf_attr_pa_tnc_error_t*)attr;
+ error_vendor_id = error_attr->get_vendor_id(error_attr);
+ error_code = error_attr->get_error_code(error_attr);
+ msg_info = error_attr->get_msg_info(error_attr);
+
+ /* skip errors from non-IETF namespaces */
+ if (error_vendor_id != PEN_IETF)
+ {
+ continue;
+ }
+ DBG1(DBG_IMC, "received PA-TNC error '%N' concerning message "
+ "0x%08x/0x%08x", pa_tnc_error_code_names, error_code,
+ untoh32(msg_info.ptr), untoh32(msg_info.ptr + 4));
+
+ switch (error_code)
+ {
+ case PA_ERROR_INVALID_PARAMETER:
+ offset = error_attr->get_offset(error_attr);
+ DBG1(DBG_IMC, " occurred at offset of %u bytes", offset);
+ break;
+ case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
+ attr_info = error_attr->get_attr_info(error_attr);
+ DBG1(DBG_IMC, " unsupported attribute %#B", &attr_info);
+ break;
+ default:
+ break;
+ }
+
+ /* remove the processed IETF standard error attribute */
+ this->attributes->remove_at(this->attributes, enumerator);
+ fatal_error = TRUE;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return fatal_error;
+}
+
+METHOD(pa_tnc_msg_t, create_attribute_enumerator, enumerator_t*,
+ private_pa_tnc_msg_t *this)
+{
+ return this->attributes->create_enumerator(this->attributes);
+}
+
+METHOD(pa_tnc_msg_t, create_error_enumerator, enumerator_t*,
+ private_pa_tnc_msg_t *this)
+{
+ return this->errors->create_enumerator(this->errors);
+}
+
+METHOD(pa_tnc_msg_t, destroy, void,
+ private_pa_tnc_msg_t *this)
+{
+ this->attributes->destroy_offset(this->attributes,
+ offsetof(pa_tnc_attr_t, destroy));
+ this->errors->destroy_offset(this->errors,
+ offsetof(pa_tnc_attr_t, destroy));
+ free(this->encoding.ptr);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pa_tnc_msg_t *pa_tnc_msg_create_from_data(chunk_t data)
+{
+ private_pa_tnc_msg_t *this;
+
+ INIT(this,
+ .public = {
+ .get_encoding = _get_encoding,
+ .add_attribute = _add_attribute,
+ .build = _build,
+ .process = _process,
+ .process_ietf_std_errors = _process_ietf_std_errors,
+ .create_attribute_enumerator = _create_attribute_enumerator,
+ .create_error_enumerator = _create_error_enumerator,
+ .destroy = _destroy,
+ },
+ .encoding = chunk_clone(data),
+ .attributes = linked_list_create(),
+ .errors = linked_list_create(),
+ );
+
+ return &this->public;
+}
+
+/**
+ * See header
+ */
+pa_tnc_msg_t *pa_tnc_msg_create(void)
+{
+ return pa_tnc_msg_create_from_data(chunk_empty);
+}
+
diff --git a/src/libimcv/pa_tnc/pa_tnc_msg.h b/src/libimcv/pa_tnc/pa_tnc_msg.h
new file mode 100644
index 000000000..c3ce829d5
--- /dev/null
+++ b/src/libimcv/pa_tnc/pa_tnc_msg.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2011 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 pa_tnc_msg pa_tnc_msg
+ * @{ @ingroup libimcv
+ */
+
+#ifndef PA_TNC_MSG_H_
+#define PA_TNC_MSG_H_
+
+typedef struct pa_tnc_msg_t pa_tnc_msg_t;
+
+#define PA_TNC_VERSION 0x01
+
+#include "pa_tnc_attr.h"
+
+#include <library.h>
+
+/**
+ * Interface for the RFC 5792 PA-TNC Posture Attribute protocol.
+ *
+ */
+struct pa_tnc_msg_t {
+
+ /**
+ * Get the encoding of the PA-TNC message
+ *
+ * @return encoded PA-TNC message
+ */
+ chunk_t (*get_encoding)(pa_tnc_msg_t *this);
+
+ /**
+ * Add a PA-TNC attribute
+ *
+ * @param attr PA-TNC attribute to be addedd
+ */
+ void (*add_attribute)(pa_tnc_msg_t *this, pa_tnc_attr_t* attr);
+
+ /**
+ * Build the PA-TNC message
+ */
+ void (*build)(pa_tnc_msg_t *this);
+
+ /**
+ * Process the PA-TNC message
+ *
+ * @return return processing status
+ */
+ status_t (*process)(pa_tnc_msg_t *this);
+
+ /**
+ * Process and remove all IETF standard error PA-TNC attributes
+ *
+ * @return TRUE if at least one error attribute processed
+ */
+ bool (*process_ietf_std_errors)(pa_tnc_msg_t *this);
+
+ /**
+ * Enumerates over all PA-TNC attributes
+ *
+ * @return return attribute enumerator
+ */
+ enumerator_t* (*create_attribute_enumerator)(pa_tnc_msg_t *this);
+
+ /**
+ * Enumerates over all parsing errors
+ *
+ * @return return error enumerator
+ */
+ enumerator_t* (*create_error_enumerator)(pa_tnc_msg_t *this);
+
+ /**
+ * Destroys a pa_tnc_msg_t object.
+ */
+ void (*destroy)(pa_tnc_msg_t *this);
+};
+
+/**
+ * Create an empty PA-TNC message
+ */
+pa_tnc_msg_t* pa_tnc_msg_create(void);
+
+/**
+ * Create an unprocessed PA-TNC message from received data
+ *
+ * @param data PA-TNC message data
+ */
+pa_tnc_msg_t* pa_tnc_msg_create_from_data(chunk_t data);
+
+#endif /** PA_TNC_MSG_H_ @}*/
diff --git a/src/libimcv/plugins/imc_scanner/Makefile.am b/src/libimcv/plugins/imc_scanner/Makefile.am
new file mode 100644
index 000000000..f27d73b67
--- /dev/null
+++ b/src/libimcv/plugins/imc_scanner/Makefile.am
@@ -0,0 +1,15 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libimcv
+
+AM_CFLAGS = -rdynamic
+
+imcv_LTLIBRARIES = imc-scanner.la
+
+imc_scanner_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+
+imc_scanner_la_SOURCES = imc_scanner.c imc_scanner_state.h imc_scanner_state.c
+
+imc_scanner_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libimcv/plugins/imc_scanner/Makefile.in b/src/libimcv/plugins/imc_scanner/Makefile.in
new file mode 100644
index 000000000..497d317d5
--- /dev/null
+++ b/src/libimcv/plugins/imc_scanner/Makefile.in
@@ -0,0 +1,600 @@
+# 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/libimcv/plugins/imc_scanner
+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)$(imcvdir)"
+LTLIBRARIES = $(imcv_LTLIBRARIES)
+imc_scanner_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+am_imc_scanner_la_OBJECTS = imc_scanner.lo imc_scanner_state.lo
+imc_scanner_la_OBJECTS = $(am_imc_scanner_la_OBJECTS)
+imc_scanner_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(imc_scanner_la_LDFLAGS) $(LDFLAGS) -o $@
+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 = $(imc_scanner_la_SOURCES)
+DIST_SOURCES = $(imc_scanner_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libtncif \
+ -I$(top_srcdir)/src/libimcv
+
+AM_CFLAGS = -rdynamic
+imcv_LTLIBRARIES = imc-scanner.la
+imc_scanner_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+
+imc_scanner_la_SOURCES = imc_scanner.c imc_scanner_state.h imc_scanner_state.c
+imc_scanner_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/libimcv/plugins/imc_scanner/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libimcv/plugins/imc_scanner/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):
+install-imcvLTLIBRARIES: $(imcv_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(imcvdir)" || $(MKDIR_P) "$(DESTDIR)$(imcvdir)"
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || 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)$(imcvdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(imcvdir)"; \
+ }
+
+uninstall-imcvLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(imcvdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(imcvdir)/$$f"; \
+ done
+
+clean-imcvLTLIBRARIES:
+ -test -z "$(imcv_LTLIBRARIES)" || rm -f $(imcv_LTLIBRARIES)
+ @list='$(imcv_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
+imc-scanner.la: $(imc_scanner_la_OBJECTS) $(imc_scanner_la_DEPENDENCIES)
+ $(imc_scanner_la_LINK) -rpath $(imcvdir) $(imc_scanner_la_OBJECTS) $(imc_scanner_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imc_scanner.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imc_scanner_state.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)$(imcvdir)"; 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-imcvLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-imcvLTLIBRARIES
+
+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-imcvLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-imcvLTLIBRARIES clean-libtool 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-imcvLTLIBRARIES install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-imcvLTLIBRARIES
+
+
+# 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/libimcv/plugins/imc_scanner/imc_scanner.c b/src/libimcv/plugins/imc_scanner/imc_scanner.c
new file mode 100644
index 000000000..b24c39c3a
--- /dev/null
+++ b/src/libimcv/plugins/imc_scanner/imc_scanner.c
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2011 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 "imc_scanner_state.h"
+
+#include <imc/imc_agent.h>
+#include <pa_tnc/pa_tnc_msg.h>
+#include <ietf/ietf_attr.h>
+#include <ietf/ietf_attr_pa_tnc_error.h>
+#include <ietf/ietf_attr_port_filter.h>
+
+#include <tncif_names.h>
+#include <tncif_pa_subtypes.h>
+
+#include <pen/pen.h>
+#include <utils/lexparser.h>
+#include <debug.h>
+
+#include <stdio.h>
+
+/* IMC definitions */
+
+static const char imc_name[] = "Scanner";
+
+#define IMC_VENDOR_ID PEN_ITA
+#define IMC_SUBTYPE PA_SUBTYPE_ITA_SCANNER
+
+static imc_agent_t *imc_scanner;
+
+/**
+ * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
+ TNC_Version min_version,
+ TNC_Version max_version,
+ TNC_Version *actual_version)
+{
+ if (imc_scanner)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
+ return TNC_RESULT_ALREADY_INITIALIZED;
+ }
+ imc_scanner = imc_agent_create(imc_name, IMC_VENDOR_ID, IMC_SUBTYPE,
+ imc_id, actual_version);
+ if (!imc_scanner)
+ {
+ return TNC_RESULT_FATAL;
+ }
+ if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
+ {
+ DBG1(DBG_IMC, "no common IF-IMC version");
+ return TNC_RESULT_NO_COMMON_VERSION;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.2 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_ConnectionState new_state)
+{
+ imc_state_t *state;
+
+ if (!imc_scanner)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ switch (new_state)
+ {
+ case TNC_CONNECTION_STATE_CREATE:
+ state = imc_scanner_state_create(connection_id);
+ return imc_scanner->create_state(imc_scanner, state);
+ case TNC_CONNECTION_STATE_DELETE:
+ return imc_scanner->delete_state(imc_scanner, connection_id);
+ default:
+ return imc_scanner->change_state(imc_scanner, connection_id,
+ new_state, NULL);
+ }
+}
+
+/**
+ * Determine all TCP and UDP server sockets listening on physical interfaces
+ */
+static bool do_netstat(ietf_attr_port_filter_t *attr)
+{
+ FILE *file;
+ char buf[BUF_LEN];
+ chunk_t line, token;
+ int n = 0;
+ bool success = FALSE;
+ const char loopback_v4[] = "127.0.0.1";
+ const char loopback_v6[] = "::1";
+
+ /* Open a pipe stream for reading the output of the netstat commmand */
+ file = popen("/bin/netstat -n -l -p -4 -6 --inet", "r");
+ if (!file)
+ {
+ DBG1(DBG_IMC, "Failed to run netstat command");
+ return FALSE;
+ }
+
+ /* Read the output a line at a time */
+ while (fgets(buf, BUF_LEN-1, file))
+ {
+ u_char *pos;
+ u_int8_t new_protocol, protocol;
+ u_int16_t new_port, port;
+ int i;
+ enumerator_t *enumerator;
+ bool allowed, found = FALSE;
+
+ DBG2(DBG_IMC, "%.*s", strlen(buf)-1, buf);
+
+ if (n++ < 2)
+ {
+ /* skip the first two header lines */
+ continue;
+ }
+ line = chunk_create(buf, strlen(buf));
+
+ /* Extract the IP protocol type */
+ if (!extract_token(&token, ' ', &line))
+ {
+ DBG1(DBG_IMC, "Protocol field in netstat output not found");
+ goto end;
+ }
+ if (match("tcp", &token) || match("tcp6", &token))
+ {
+ new_protocol = IPPROTO_TCP;
+ }
+ else if (match("udp", &token) || match("udp6", &token))
+ {
+ new_protocol = IPPROTO_UDP;
+ }
+ else
+ {
+ DBG1(DBG_IMC, "Skipped unknown IP protocol in netstat output");
+ continue;
+ }
+
+ /* Skip the Recv-Q and Send-Q fields */
+ for (i = 0; i < 3; i++)
+ {
+ if (!eat_whitespace(&line) || !extract_token(&token, ' ', &line))
+ {
+ token = chunk_empty;
+ break;
+ }
+ }
+ if (token.len == 0)
+ {
+ DBG1(DBG_IMC, "Local Address field in netstat output not found");
+ goto end;
+ }
+
+ /* Find the local port appended to the local address */
+ pos = token.ptr + token.len;
+ while (*--pos != ':' && --token.len);
+ if (*pos != ':')
+ {
+ DBG1(DBG_IMC, "Local port field in netstat output not found");
+ goto end;
+ }
+ token.len--;
+
+ /* ignore ports of IPv4 and IPv6 loopback interfaces */
+ if ((token.len == strlen(loopback_v4) &&
+ memeq(loopback_v4, token.ptr, token.len)) ||
+ (token.len == strlen(loopback_v6) &&
+ memeq(loopback_v6, token.ptr, token.len)))
+ {
+ continue;
+ }
+
+ /* convert the port string to an integer */
+ new_port = atoi(pos+1);
+
+ /* check if the there is already a port entry */
+ enumerator = attr->create_port_enumerator(attr);
+ while (enumerator->enumerate(enumerator, &allowed, &protocol, &port))
+ {
+ if (new_port == port && new_protocol == protocol)
+ {
+ found = TRUE;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ /* Skip the duplicate port entry */
+ if (found)
+ {
+ continue;
+ }
+
+ /* Add new port entry */
+ attr->add_port(attr, FALSE, new_protocol, new_port);
+ }
+
+ /* Successfully completed the parsing of the netstat output */
+ success = TRUE;
+
+end:
+ /* Close the pipe stream */
+ pclose(file);
+ return success;
+}
+
+static TNC_Result send_message(TNC_ConnectionID connection_id)
+{
+ pa_tnc_msg_t *msg;
+ pa_tnc_attr_t *attr;
+ ietf_attr_port_filter_t *attr_port_filter;
+ TNC_Result result;
+
+ attr = ietf_attr_port_filter_create();
+ attr->set_noskip_flag(attr, TRUE);
+ attr_port_filter = (ietf_attr_port_filter_t*)attr;
+ if (!do_netstat(attr_port_filter))
+ {
+ attr->destroy(attr);
+ return TNC_RESULT_FATAL;
+ }
+ msg = pa_tnc_msg_create();
+ msg->add_attribute(msg, attr);
+ msg->build(msg);
+ result = imc_scanner->send_message(imc_scanner, connection_id, FALSE, 0,
+ TNC_IMVID_ANY, msg->get_encoding(msg));
+ msg->destroy(msg);
+
+ return result;
+}
+
+/**
+ * see section 3.8.3 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id)
+{
+ if (!imc_scanner)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return send_message(connection_id);
+}
+
+static TNC_Result receive_message(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ chunk_t msg,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imv_id,
+ TNC_UInt32 dst_imc_id)
+{
+ pa_tnc_msg_t *pa_tnc_msg;
+ imc_state_t *state;
+ TNC_Result result;
+ bool fatal_error;
+
+ if (!imc_scanner)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+
+ /* get current IMC state */
+ if (!imc_scanner->get_state(imc_scanner, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+
+ /* parse received PA-TNC message and automatically handle any errors */
+ result = imc_scanner->receive_message(imc_scanner, state, msg, msg_vid,
+ msg_subtype, src_imv_id, dst_imc_id, &pa_tnc_msg);
+
+ /* no parsed PA-TNC attributes available if an error occurred */
+ if (!pa_tnc_msg)
+ {
+ return result;
+ }
+
+ /* preprocess any IETF standard error attributes */
+ fatal_error = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg);
+ pa_tnc_msg->destroy(pa_tnc_msg);
+
+ /* if no error occurred then always return the same response */
+ return fatal_error ? TNC_RESULT_FATAL : send_message(connection_id);
+}
+
+/**
+ * see section 3.8.4 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type)
+{
+ TNC_VendorID msg_vid;
+ TNC_MessageSubtype msg_subtype;
+
+ msg_vid = msg_type >> 8;
+ msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+
+ return receive_message(imc_id, connection_id, 0, chunk_create(msg, msg_len),
+ msg_vid, msg_subtype, 0, TNC_IMCID_ANY);
+}
+
+/**
+ * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imv_id,
+ TNC_UInt32 dst_imc_id)
+{
+ return receive_message(imc_id, connection_id, msg_flags,
+ chunk_create(msg, msg_len), msg_vid, msg_subtype,
+ src_imv_id, dst_imc_id);
+}
+
+/**
+ * see section 3.8.7 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_BatchEnding(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id)
+{
+ if (!imc_scanner)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.8 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
+{
+ if (!imc_scanner)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ imc_scanner->destroy(imc_scanner);
+ imc_scanner = NULL;
+
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id,
+ TNC_TNCC_BindFunctionPointer bind_function)
+{
+ if (!imc_scanner)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return imc_scanner->bind_functions(imc_scanner, bind_function);
+}
diff --git a/src/libimcv/plugins/imc_scanner/imc_scanner_state.c b/src/libimcv/plugins/imc_scanner/imc_scanner_state.c
new file mode 100644
index 000000000..563105548
--- /dev/null
+++ b/src/libimcv/plugins/imc_scanner/imc_scanner_state.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2011 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 "imc_scanner_state.h"
+
+#include <debug.h>
+
+typedef struct private_imc_scanner_state_t private_imc_scanner_state_t;
+
+/**
+ * Private data of an imc_scanner_state_t object.
+ */
+struct private_imc_scanner_state_t {
+
+ /**
+ * Public members of imc_scanner_state_t
+ */
+ imc_scanner_state_t public;
+
+ /**
+ * TNCCS connection ID
+ */
+ TNC_ConnectionID connection_id;
+
+ /**
+ * TNCCS connection state
+ */
+ TNC_ConnectionState state;
+
+ /**
+ * Does the TNCCS connection support long message types?
+ */
+ bool has_long;
+
+ /**
+ * Does the TNCCS connection support exclusive delivery?
+ */
+ bool has_excl;
+
+};
+
+METHOD(imc_state_t, get_connection_id, TNC_ConnectionID,
+ private_imc_scanner_state_t *this)
+{
+ return this->connection_id;
+}
+
+METHOD(imc_state_t, has_long, bool,
+ private_imc_scanner_state_t *this)
+{
+ return this->has_long;
+}
+
+METHOD(imc_state_t, has_excl, bool,
+ private_imc_scanner_state_t *this)
+{
+ return this->has_excl;
+}
+
+METHOD(imc_state_t, set_flags, void,
+ private_imc_scanner_state_t *this, bool has_long, bool has_excl)
+{
+ this->has_long = has_long;
+ this->has_excl = has_excl;
+}
+
+METHOD(imc_state_t, change_state, void,
+ private_imc_scanner_state_t *this, TNC_ConnectionState new_state)
+{
+ this->state = new_state;
+}
+
+METHOD(imc_state_t, destroy, void,
+ private_imc_scanner_state_t *this)
+{
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+imc_state_t *imc_scanner_state_create(TNC_ConnectionID connection_id)
+{
+ private_imc_scanner_state_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .get_connection_id = _get_connection_id,
+ .has_long = _has_long,
+ .has_excl = _has_excl,
+ .set_flags = _set_flags,
+ .change_state = _change_state,
+ .destroy = _destroy,
+ },
+ },
+ .state = TNC_CONNECTION_STATE_CREATE,
+ .connection_id = connection_id,
+ );
+
+ return &this->public.interface;
+}
+
+
diff --git a/src/libimcv/plugins/imc_scanner/imc_scanner_state.h b/src/libimcv/plugins/imc_scanner/imc_scanner_state.h
new file mode 100644
index 000000000..76aa4165b
--- /dev/null
+++ b/src/libimcv/plugins/imc_scanner/imc_scanner_state.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 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 imc_scanner_state_t imc_scanner_state
+ * @{ @ingroup imc_scanner_state
+ */
+
+#ifndef IMC_SCANNER_STATE_H_
+#define IMC_SCANNER_STATE_H_
+
+#include <imc/imc_state.h>
+#include <library.h>
+
+typedef struct imc_scanner_state_t imc_scanner_state_t;
+
+/**
+ * Internal state of an imc_scanner_t connection instance
+ */
+struct imc_scanner_state_t {
+
+ /**
+ * imc_state_t interface
+ */
+ imc_state_t interface;
+};
+
+/**
+ * Create an imc_scanner_state_t instance
+ *
+ * @param id connection ID
+ */
+imc_state_t* imc_scanner_state_create(TNC_ConnectionID id);
+
+#endif /** IMC_SCANNER_STATE_H_ @}*/
diff --git a/src/libimcv/plugins/imc_test/Makefile.am b/src/libimcv/plugins/imc_test/Makefile.am
new file mode 100644
index 000000000..b55e7bcd4
--- /dev/null
+++ b/src/libimcv/plugins/imc_test/Makefile.am
@@ -0,0 +1,15 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libimcv
+
+AM_CFLAGS = -rdynamic
+
+imcv_LTLIBRARIES = imc-test.la
+
+imc_test_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+
+imc_test_la_SOURCES = imc_test.c imc_test_state.h imc_test_state.c
+
+imc_test_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libimcv/plugins/imc_test/Makefile.in b/src/libimcv/plugins/imc_test/Makefile.in
new file mode 100644
index 000000000..b4e3f8ae0
--- /dev/null
+++ b/src/libimcv/plugins/imc_test/Makefile.in
@@ -0,0 +1,600 @@
+# 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/libimcv/plugins/imc_test
+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)$(imcvdir)"
+LTLIBRARIES = $(imcv_LTLIBRARIES)
+imc_test_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+am_imc_test_la_OBJECTS = imc_test.lo imc_test_state.lo
+imc_test_la_OBJECTS = $(am_imc_test_la_OBJECTS)
+imc_test_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(imc_test_la_LDFLAGS) $(LDFLAGS) -o $@
+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 = $(imc_test_la_SOURCES)
+DIST_SOURCES = $(imc_test_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libtncif \
+ -I$(top_srcdir)/src/libimcv
+
+AM_CFLAGS = -rdynamic
+imcv_LTLIBRARIES = imc-test.la
+imc_test_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+
+imc_test_la_SOURCES = imc_test.c imc_test_state.h imc_test_state.c
+imc_test_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/libimcv/plugins/imc_test/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libimcv/plugins/imc_test/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):
+install-imcvLTLIBRARIES: $(imcv_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(imcvdir)" || $(MKDIR_P) "$(DESTDIR)$(imcvdir)"
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || 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)$(imcvdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(imcvdir)"; \
+ }
+
+uninstall-imcvLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(imcvdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(imcvdir)/$$f"; \
+ done
+
+clean-imcvLTLIBRARIES:
+ -test -z "$(imcv_LTLIBRARIES)" || rm -f $(imcv_LTLIBRARIES)
+ @list='$(imcv_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
+imc-test.la: $(imc_test_la_OBJECTS) $(imc_test_la_DEPENDENCIES)
+ $(imc_test_la_LINK) -rpath $(imcvdir) $(imc_test_la_OBJECTS) $(imc_test_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imc_test.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imc_test_state.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)$(imcvdir)"; 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-imcvLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-imcvLTLIBRARIES
+
+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-imcvLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-imcvLTLIBRARIES clean-libtool 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-imcvLTLIBRARIES install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-imcvLTLIBRARIES
+
+
+# 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/libimcv/plugins/imc_test/imc_test.c b/src/libimcv/plugins/imc_test/imc_test.c
new file mode 100644
index 000000000..fe005ed4a
--- /dev/null
+++ b/src/libimcv/plugins/imc_test/imc_test.c
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2011 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 "imc_test_state.h"
+
+#include <imc/imc_agent.h>
+#include <pa_tnc/pa_tnc_msg.h>
+#include <ietf/ietf_attr.h>
+#include <ietf/ietf_attr_pa_tnc_error.h>
+#include <ita/ita_attr.h>
+#include <ita/ita_attr_command.h>
+
+#include <tncif_names.h>
+#include <tncif_pa_subtypes.h>
+
+#include <pen/pen.h>
+#include <debug.h>
+
+/* IMC definitions */
+
+static const char imc_name[] = "Test";
+
+#define IMC_VENDOR_ID PEN_ITA
+#define IMC_SUBTYPE PA_SUBTYPE_ITA_TEST
+
+static imc_agent_t *imc_test;
+
+/**
+ * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
+ TNC_Version min_version,
+ TNC_Version max_version,
+ TNC_Version *actual_version)
+{
+ if (imc_test)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
+ return TNC_RESULT_ALREADY_INITIALIZED;
+ }
+ imc_test = imc_agent_create(imc_name, IMC_VENDOR_ID, IMC_SUBTYPE,
+ imc_id, actual_version);
+ if (!imc_test)
+ {
+ return TNC_RESULT_FATAL;
+ }
+ if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
+ {
+ DBG1(DBG_IMC, "no common IF-IMC version");
+ return TNC_RESULT_NO_COMMON_VERSION;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.2 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_ConnectionState new_state)
+{
+ imc_state_t *state;
+ imc_test_state_t *test_state;
+ TNC_Result result;
+ char *command;
+ bool retry;
+ int additional_ids;
+
+ if (!imc_test)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+
+ switch (new_state)
+ {
+ case TNC_CONNECTION_STATE_CREATE:
+ command = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-test.command", "none");
+ retry = lib->settings->get_bool(lib->settings,
+ "libimcv.plugins.imc-test.retry", FALSE);
+ state = imc_test_state_create(connection_id, command, retry);
+
+ result = imc_test->create_state(imc_test, state);
+ if (result != TNC_RESULT_SUCCESS)
+ {
+ return result;
+ }
+
+ /* Optionally reserve additional IMC IDs */
+ additional_ids = lib->settings->get_int(lib->settings,
+ "libimcv.plugins.imc-test.additional_ids", 0);
+ imc_test->reserve_additional_ids(imc_test, additional_ids -
+ imc_test->count_additional_ids(imc_test));
+
+ return TNC_RESULT_SUCCESS;
+
+ case TNC_CONNECTION_STATE_HANDSHAKE:
+ /* get updated IMC state */
+ result = imc_test->change_state(imc_test, connection_id,
+ new_state, &state);
+ if (result != TNC_RESULT_SUCCESS)
+ {
+ return TNC_RESULT_FATAL;
+ }
+ test_state = (imc_test_state_t*)state;
+
+ /* is it the first handshake or a retry ? */
+ if (!test_state->is_first_handshake(test_state))
+ {
+ command = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-test.retry_command",
+ test_state->get_command(test_state));
+ test_state->set_command(test_state, command);
+ }
+ return TNC_RESULT_SUCCESS;
+
+ case TNC_CONNECTION_STATE_DELETE:
+ return imc_test->delete_state(imc_test, connection_id);
+
+ case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
+ case TNC_CONNECTION_STATE_ACCESS_NONE:
+ /* get updated IMC state */
+ result = imc_test->change_state(imc_test, connection_id,
+ new_state, &state);
+ if (result != TNC_RESULT_SUCCESS)
+ {
+ return TNC_RESULT_FATAL;
+ }
+ test_state = (imc_test_state_t*)state;
+
+ /* do a handshake retry? */
+ if (test_state->do_handshake_retry(test_state))
+ {
+ return imc_test->request_handshake_retry(imc_id, connection_id,
+ TNC_RETRY_REASON_IMC_REMEDIATION_COMPLETE);
+ }
+ return TNC_RESULT_SUCCESS;
+
+ default:
+ return imc_test->change_state(imc_test, connection_id,
+ new_state, NULL);
+ }
+}
+
+static TNC_Result send_message(imc_state_t *state, TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id)
+{
+ imc_test_state_t *test_state;
+ pa_tnc_msg_t *msg;
+ pa_tnc_attr_t *attr;
+ bool excl;
+ TNC_ConnectionID connection_id;
+ TNC_Result result;
+
+ connection_id = state->get_connection_id(state);
+ test_state = (imc_test_state_t*)state;
+ attr = ita_attr_command_create(test_state->get_command(test_state));
+ attr->set_noskip_flag(attr, TRUE);
+ msg = pa_tnc_msg_create();
+ msg->add_attribute(msg, attr);
+ msg->build(msg);
+ excl = dst_imv_id != TNC_IMVID_ANY;
+ result = imc_test->send_message(imc_test, connection_id, excl, src_imc_id,
+ dst_imv_id, msg->get_encoding(msg));
+ msg->destroy(msg);
+
+ return result;
+}
+
+/**
+ * see section 3.8.3 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id)
+{
+ imc_state_t *state;
+ enumerator_t *enumerator;
+ void *pointer;
+ TNC_UInt32 additional_id;
+ TNC_Result result;
+
+ if (!imc_test)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+
+ /* get current IMC state */
+ if (!imc_test->get_state(imc_test, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+
+ /* send PA message for primary IMC ID */
+ result = send_message(state, imc_id, TNC_IMVID_ANY);
+
+ /* Exit if there are no additional IMC IDs */
+ if (!imc_test->count_additional_ids(imc_test))
+ {
+ return result;
+ }
+
+ /* Do we have support for transporting multiple IMC IDs? */
+ if (!state->has_long(state))
+ {
+ DBG1(DBG_IMC, "IMC %u \"%s\" did not detect support for transporting "
+ "multiple IMC IDs", imc_id, imc_name);
+ return result;
+ }
+
+ /* send PA messages for additional IMC IDs */
+ enumerator = imc_test->create_id_enumerator(imc_test);
+ while (result == TNC_RESULT_SUCCESS &&
+ enumerator->enumerate(enumerator, &pointer))
+ {
+ /* interpret pointer as scalar value */
+ additional_id = (TNC_UInt32)pointer;
+ result = send_message(state, additional_id, TNC_IMVID_ANY);
+ }
+ enumerator->destroy(enumerator);
+
+ return result;
+}
+
+static TNC_Result receive_message(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ chunk_t msg,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imv_id,
+ TNC_UInt32 dst_imc_id)
+{
+ pa_tnc_msg_t *pa_tnc_msg;
+ pa_tnc_attr_t *attr;
+ imc_state_t *state;
+ enumerator_t *enumerator;
+ TNC_Result result;
+ bool fatal_error = FALSE;
+
+ if (!imc_test)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+
+ /* get current IMC state */
+ if (!imc_test->get_state(imc_test, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+
+ /* parse received PA-TNC message and automatically handle any errors */
+ result = imc_test->receive_message(imc_test, state, msg, msg_vid,
+ msg_subtype, src_imv_id, dst_imc_id, &pa_tnc_msg);
+
+ /* no parsed PA-TNC attributes available if an error occurred */
+ if (!pa_tnc_msg)
+ {
+ return result;
+ }
+
+ /* preprocess any IETF standard error attributes */
+ fatal_error = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg);
+
+ /* analyze PA-TNC attributes */
+ enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ if (attr->get_vendor_id(attr) == PEN_ITA &&
+ attr->get_type(attr) == ITA_ATTR_COMMAND)
+ {
+ ita_attr_command_t *ita_attr;
+ char *command;
+
+ ita_attr = (ita_attr_command_t*)attr;
+ command = ita_attr->get_command(ita_attr);
+ }
+ }
+ enumerator->destroy(enumerator);
+ pa_tnc_msg->destroy(pa_tnc_msg);
+
+ /* if no error occurred then always return the same response */
+ return fatal_error ? TNC_RESULT_FATAL :
+ send_message(state, dst_imc_id, src_imv_id);
+}
+
+/**
+ * see section 3.8.4 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type)
+{
+ TNC_VendorID msg_vid;
+ TNC_MessageSubtype msg_subtype;
+
+ msg_vid = msg_type >> 8;
+ msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+
+ return receive_message(imc_id, connection_id, 0, chunk_create(msg, msg_len),
+ msg_vid, msg_subtype, 0, TNC_IMCID_ANY);
+}
+
+/**
+ * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imv_id,
+ TNC_UInt32 dst_imc_id)
+{
+ return receive_message(imc_id, connection_id, msg_flags,
+ chunk_create(msg, msg_len), msg_vid, msg_subtype,
+ src_imv_id, dst_imc_id);
+}
+
+/**
+ * see section 3.8.7 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_BatchEnding(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id)
+{
+ if (!imc_test)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.8 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
+{
+ if (!imc_test)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ imc_test->destroy(imc_test);
+ imc_test = NULL;
+
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id,
+ TNC_TNCC_BindFunctionPointer bind_function)
+{
+ if (!imc_test)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return imc_test->bind_functions(imc_test, bind_function);
+}
diff --git a/src/libimcv/plugins/imc_test/imc_test_state.c b/src/libimcv/plugins/imc_test/imc_test_state.c
new file mode 100644
index 000000000..2adfd7d64
--- /dev/null
+++ b/src/libimcv/plugins/imc_test/imc_test_state.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2011 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 "imc_test_state.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+
+typedef struct private_imc_test_state_t private_imc_test_state_t;
+
+/**
+ * Private data of an imc_test_state_t object.
+ */
+struct private_imc_test_state_t {
+
+ /**
+ * Public members of imc_test_state_t
+ */
+ imc_test_state_t public;
+
+ /**
+ * TNCCS connection ID
+ */
+ TNC_ConnectionID connection_id;
+
+ /**
+ * TNCCS connection state
+ */
+ TNC_ConnectionState state;
+
+ /**
+ * Does the TNCCS connection support long message types?
+ */
+ bool has_long;
+
+ /**
+ * Does the TNCCS connection support exclusive delivery?
+ */
+ bool has_excl;
+
+ /**
+ * Command to transmit to IMV
+ */
+ char *command;
+
+ /**
+ * Is it the first handshake?
+ */
+ bool first_handshake;
+
+ /**
+ * Do a handshake retry
+ */
+ bool handshake_retry;
+
+};
+
+METHOD(imc_state_t, get_connection_id, TNC_ConnectionID,
+ private_imc_test_state_t *this)
+{
+ return this->connection_id;
+}
+
+METHOD(imc_state_t, has_long, bool,
+ private_imc_test_state_t *this)
+{
+ return this->has_long;
+}
+
+METHOD(imc_state_t, has_excl, bool,
+ private_imc_test_state_t *this)
+{
+ return this->has_excl;
+}
+
+METHOD(imc_state_t, set_flags, void,
+ private_imc_test_state_t *this, bool has_long, bool has_excl)
+{
+ this->has_long = has_long;
+ this->has_excl = has_excl;
+}
+
+METHOD(imc_state_t, change_state, void,
+ private_imc_test_state_t *this, TNC_ConnectionState new_state)
+{
+ this->state = new_state;
+}
+
+METHOD(imc_state_t, destroy, void,
+ private_imc_test_state_t *this)
+{
+ free(this->command);
+ free(this);
+}
+
+METHOD(imc_test_state_t, get_command, char*,
+ private_imc_test_state_t *this)
+{
+ return this->command;
+}
+
+METHOD(imc_test_state_t, set_command, void,
+ private_imc_test_state_t *this, char* command)
+{
+ char *old_command;
+
+ old_command = this->command;
+ this->command = strdup(command);
+ free(old_command);
+}
+
+METHOD(imc_test_state_t, is_first_handshake, bool,
+ private_imc_test_state_t *this)
+{
+ bool first;
+
+ /* test and reset first_handshake flag */
+ first= this->first_handshake;
+ this->first_handshake = FALSE;
+ return first;
+}
+
+METHOD(imc_test_state_t, do_handshake_retry, bool,
+ private_imc_test_state_t *this)
+{
+ bool retry;
+
+ /* test and reset handshake_retry flag */
+ retry = this->handshake_retry;
+ this->handshake_retry = FALSE;
+ return retry;
+}
+
+/**
+ * Described in header.
+ */
+imc_state_t *imc_test_state_create(TNC_ConnectionID connection_id,
+ char *command, bool retry)
+{
+ private_imc_test_state_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .get_connection_id = _get_connection_id,
+ .has_long = _has_long,
+ .has_excl = _has_excl,
+ .set_flags = _set_flags,
+ .change_state = _change_state,
+ .destroy = _destroy,
+ },
+ .get_command = _get_command,
+ .set_command = _set_command,
+ .is_first_handshake = _is_first_handshake,
+ .do_handshake_retry = _do_handshake_retry,
+ },
+ .state = TNC_CONNECTION_STATE_CREATE,
+ .connection_id = connection_id,
+ .command = strdup(command),
+ .first_handshake = TRUE,
+ .handshake_retry = retry,
+ );
+
+ return &this->public.interface;
+}
+
+
diff --git a/src/libimcv/plugins/imc_test/imc_test_state.h b/src/libimcv/plugins/imc_test/imc_test_state.h
new file mode 100644
index 000000000..d9160df94
--- /dev/null
+++ b/src/libimcv/plugins/imc_test/imc_test_state.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 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 imc_test_state_t imc_test_state
+ * @{ @ingroup imc_test_state
+ */
+
+#ifndef IMC_TEST_STATE_H_
+#define IMC_TEST_STATE_H_
+
+#include <tncifimc.h>
+#include <imc/imc_state.h>
+#include <library.h>
+
+typedef struct imc_test_state_t imc_test_state_t;
+
+/**
+ * Internal state of an imc_test_t connection instance
+ */
+struct imc_test_state_t {
+
+ /**
+ * imc_state_t interface
+ */
+ imc_state_t interface;
+
+ /**
+ * get the command to send to IMV
+ *
+ * @return commmand to send to IMV
+ */
+ char* (*get_command)(imc_test_state_t *this);
+
+ /**
+ * set the command to send to IMV
+ *
+ * @param command commmand to send to IMV
+ */
+ void (*set_command)(imc_test_state_t *this, char *command);
+
+ /**
+ * Test and reset the first handshake flag
+ *
+ * @return TRUE if first handshake
+ */
+ bool (*is_first_handshake)(imc_test_state_t *this);
+
+ /**
+ * Test and reset the retry handshake flag
+ *
+ * @return TRUE if a handshake retry should be done
+ */
+ bool (*do_handshake_retry)(imc_test_state_t *this);
+
+};
+
+/**
+ * Create an imc_test_state_t instance
+ *
+ * @param id connection ID
+ * @param command command to send to IMV
+ * @param retry TRUE if a handshake retry should be done
+ */
+imc_state_t* imc_test_state_create(TNC_ConnectionID id, char* command,
+ bool retry);
+
+#endif /** IMC_TEST_STATE_H_ @}*/
diff --git a/src/libimcv/plugins/imv_scanner/Makefile.am b/src/libimcv/plugins/imv_scanner/Makefile.am
new file mode 100644
index 000000000..df2158e72
--- /dev/null
+++ b/src/libimcv/plugins/imv_scanner/Makefile.am
@@ -0,0 +1,15 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libimcv
+
+AM_CFLAGS = -rdynamic
+
+imcv_LTLIBRARIES = imv-scanner.la
+
+imv_scanner_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+
+imv_scanner_la_SOURCES = imv_scanner.c imv_scanner_state.h imv_scanner_state.c
+
+imv_scanner_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libimcv/plugins/imv_scanner/Makefile.in b/src/libimcv/plugins/imv_scanner/Makefile.in
new file mode 100644
index 000000000..63602c707
--- /dev/null
+++ b/src/libimcv/plugins/imv_scanner/Makefile.in
@@ -0,0 +1,600 @@
+# 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/libimcv/plugins/imv_scanner
+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)$(imcvdir)"
+LTLIBRARIES = $(imcv_LTLIBRARIES)
+imv_scanner_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+am_imv_scanner_la_OBJECTS = imv_scanner.lo imv_scanner_state.lo
+imv_scanner_la_OBJECTS = $(am_imv_scanner_la_OBJECTS)
+imv_scanner_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(imv_scanner_la_LDFLAGS) $(LDFLAGS) -o $@
+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 = $(imv_scanner_la_SOURCES)
+DIST_SOURCES = $(imv_scanner_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libtncif \
+ -I$(top_srcdir)/src/libimcv
+
+AM_CFLAGS = -rdynamic
+imcv_LTLIBRARIES = imv-scanner.la
+imv_scanner_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+
+imv_scanner_la_SOURCES = imv_scanner.c imv_scanner_state.h imv_scanner_state.c
+imv_scanner_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/libimcv/plugins/imv_scanner/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libimcv/plugins/imv_scanner/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):
+install-imcvLTLIBRARIES: $(imcv_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(imcvdir)" || $(MKDIR_P) "$(DESTDIR)$(imcvdir)"
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || 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)$(imcvdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(imcvdir)"; \
+ }
+
+uninstall-imcvLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(imcvdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(imcvdir)/$$f"; \
+ done
+
+clean-imcvLTLIBRARIES:
+ -test -z "$(imcv_LTLIBRARIES)" || rm -f $(imcv_LTLIBRARIES)
+ @list='$(imcv_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
+imv-scanner.la: $(imv_scanner_la_OBJECTS) $(imv_scanner_la_DEPENDENCIES)
+ $(imv_scanner_la_LINK) -rpath $(imcvdir) $(imv_scanner_la_OBJECTS) $(imv_scanner_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_scanner.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_scanner_state.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)$(imcvdir)"; 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-imcvLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-imcvLTLIBRARIES
+
+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-imcvLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-imcvLTLIBRARIES clean-libtool 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-imcvLTLIBRARIES install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-imcvLTLIBRARIES
+
+
+# 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/libimcv/plugins/imv_scanner/imv_scanner.c b/src/libimcv/plugins/imv_scanner/imv_scanner.c
new file mode 100644
index 000000000..dba3fd632
--- /dev/null
+++ b/src/libimcv/plugins/imv_scanner/imv_scanner.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2011 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 "imv_scanner_state.h"
+
+#include <imv/imv_agent.h>
+#include <pa_tnc/pa_tnc_msg.h>
+#include <ietf/ietf_attr.h>
+#include <ietf/ietf_attr_pa_tnc_error.h>
+#include <ietf/ietf_attr_port_filter.h>
+
+#include <tncif_names.h>
+#include <tncif_pa_subtypes.h>
+
+#include <pen/pen.h>
+#include <utils/linked_list.h>
+#include <utils/lexparser.h>
+#include <debug.h>
+
+/* IMV definitions */
+
+static const char imv_name[] = "Scanner";
+
+#define IMV_VENDOR_ID PEN_ITA
+#define IMV_SUBTYPE PA_SUBTYPE_ITA_SCANNER
+
+static imv_agent_t *imv_scanner;
+
+typedef struct port_range_t port_range_t;
+
+struct port_range_t {
+ u_int16_t start, stop;
+};
+
+
+/**
+ * Default port policy
+ *
+ * TRUE: all server ports on the TNC client must be closed
+ * FALSE: any server port on the TNC client is allowed to be open
+ */
+static bool closed_port_policy = TRUE;
+
+/**
+ * List of TCP and UDP port ranges
+ *
+ * TRUE: server ports on the TNC client that are allowed to be open
+ * FALSE: server ports on the TNC client that must be closed
+ */
+static linked_list_t *tcp_ports, *udp_ports;
+
+/**
+ * Get a TCP or UDP port list from strongswan.conf
+ */
+static linked_list_t* get_port_list(char *label)
+{
+ char key[40], *value;
+ linked_list_t *list;
+ chunk_t port_list, port_item, port_start;
+ port_range_t *port_range;
+
+ list = linked_list_create();
+
+ snprintf(key, sizeof(key), "libimcv.plugins.imv-scanner.%s_ports", label);
+ value = lib->settings->get_str(lib->settings, key, NULL);
+ if (!value)
+ {
+ DBG1(DBG_IMV, "%s not defined", key);
+ return list;
+ }
+ port_list = chunk_create(value, strlen(value));
+ DBG2(DBG_IMV, "list of %s ports that %s:", label,
+ closed_port_policy ? "are allowed to be open" : "must be closed");
+
+ while (eat_whitespace(&port_list))
+ {
+ if (!extract_token(&port_item, ' ', &port_list))
+ {
+ /* reached last port item */
+ port_item = port_list;
+ port_list = chunk_empty;
+ }
+ port_range = malloc_thing(port_range_t);
+ port_range->start = atoi(port_item.ptr);
+
+ if (extract_token(&port_start, '-', &port_item) && port_item.len)
+ {
+ port_range->stop = atoi(port_item.ptr);
+ }
+ else
+ {
+ port_range->stop = port_range->start;
+ }
+ DBG2(DBG_IMV, "%5u - %5u", port_range->start, port_range->stop);
+ list->insert_last(list, port_range);
+ }
+
+ return list;
+}
+
+
+/*
+ * see section 3.8.1 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id,
+ TNC_Version min_version,
+ TNC_Version max_version,
+ TNC_Version *actual_version)
+{
+ if (imv_scanner)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has already been initialized", imv_name);
+ return TNC_RESULT_ALREADY_INITIALIZED;
+ }
+ imv_scanner = imv_agent_create(imv_name, IMV_VENDOR_ID, IMV_SUBTYPE,
+ imv_id, actual_version);
+ if (!imv_scanner)
+ {
+ return TNC_RESULT_FATAL;
+ }
+ if (min_version > TNC_IFIMV_VERSION_1 || max_version < TNC_IFIMV_VERSION_1)
+ {
+ DBG1(DBG_IMV, "no common IF-IMV version");
+ return TNC_RESULT_NO_COMMON_VERSION;
+ }
+
+ /* set the default port policy to closed (TRUE) or open (FALSE) */
+ closed_port_policy = lib->settings->get_bool(lib->settings,
+ "libimcv.plugins.imv-scanner.closed_port_policy", TRUE);
+ DBG2(DBG_IMV, "default port policy is %s ports",
+ closed_port_policy ? "closed" : "open");
+
+ /* get the list of open|closed ports */
+ tcp_ports = get_port_list("tcp");
+ udp_ports = get_port_list("udp");
+
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.2 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_ConnectionState new_state)
+{
+ imv_state_t *state;
+
+ if (!imv_scanner)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ switch (new_state)
+ {
+ case TNC_CONNECTION_STATE_CREATE:
+ state = imv_scanner_state_create(connection_id);
+ return imv_scanner->create_state(imv_scanner, state);
+ case TNC_CONNECTION_STATE_DELETE:
+ return imv_scanner->delete_state(imv_scanner, connection_id);
+ default:
+ return imv_scanner->change_state(imv_scanner, connection_id,
+ new_state, NULL);
+ }
+}
+
+static TNC_Result receive_message(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ chunk_t msg,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id)
+{
+ pa_tnc_msg_t *pa_tnc_msg;
+ pa_tnc_attr_t *attr;
+ imv_state_t *state;
+ enumerator_t *enumerator;
+ TNC_Result result;
+ bool fatal_error;
+
+ if (!imv_scanner)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+
+ /* get current IMV state */
+ if (!imv_scanner->get_state(imv_scanner, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+
+ /* parse received PA-TNC message and automatically handle any errors */
+ result = imv_scanner->receive_message(imv_scanner, state, msg, msg_vid,
+ msg_subtype, src_imc_id, dst_imv_id, &pa_tnc_msg);
+
+ /* no parsed PA-TNC attributes available if an error occurred */
+ if (!pa_tnc_msg)
+ {
+ return result;
+ }
+
+ /* preprocess any IETF standard error attributes */
+ fatal_error = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg);
+
+ /* analyze PA-TNC attributes */
+ enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ if (attr->get_vendor_id(attr) == PEN_IETF &&
+ attr->get_type(attr) == IETF_ATTR_PORT_FILTER)
+ {
+ ietf_attr_port_filter_t *attr_port_filter;
+ enumerator_t *enumerator;
+ u_int8_t protocol;
+ u_int16_t port;
+ char buf[BUF_LEN], *pos = buf;
+ size_t len = BUF_LEN;
+ bool blocked, compliant = TRUE;
+
+ attr_port_filter = (ietf_attr_port_filter_t*)attr;
+ enumerator = attr_port_filter->create_port_enumerator(attr_port_filter);
+ while (enumerator->enumerate(enumerator, &blocked, &protocol, &port))
+ {
+ enumerator_t *e;
+ port_range_t *port_range;
+ bool passed, found = FALSE;
+ int written = 0;
+
+ if (blocked)
+ {
+ /* ignore closed ports */
+ continue;
+ }
+
+ e = (protocol == IPPROTO_TCP) ?
+ tcp_ports->create_enumerator(tcp_ports) :
+ udp_ports->create_enumerator(udp_ports);
+ while (e->enumerate(e, &port_range))
+ {
+ if (port >= port_range->start && port <= port_range->stop)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ e->destroy(e);
+
+ passed = (closed_port_policy == found);
+ DBG2(DBG_IMV, "%s port %5u %s: %s",
+ (protocol == IPPROTO_TCP) ? "tcp" : "udp", port,
+ blocked ? "closed" : "open", passed ? "ok" : "fatal");
+ if (!passed)
+ {
+ compliant = FALSE;
+ written = snprintf(pos, len, " %s/%u",
+ (protocol == IPPROTO_TCP) ? "tcp" : "udp",
+ port);
+ if (written < 0 || written >= len)
+ {
+ break;
+ }
+ pos += written;
+ len -= written;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (compliant)
+ {
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_ALLOW,
+ TNC_IMV_EVALUATION_RESULT_COMPLIANT);
+ }
+ else
+ {
+ imv_scanner_state_t *imv_scanner_state;
+
+ imv_scanner_state = (imv_scanner_state_t*)state;
+ imv_scanner_state->set_violating_ports(imv_scanner_state, buf);
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS,
+ TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ pa_tnc_msg->destroy(pa_tnc_msg);
+
+ if (fatal_error)
+ {
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
+ TNC_IMV_EVALUATION_RESULT_ERROR);
+ return imv_scanner->provide_recommendation(imv_scanner, connection_id);
+ }
+
+ return imv_scanner->provide_recommendation(imv_scanner, connection_id);
+ }
+
+/**
+ * see section 3.8.4 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type)
+{
+ TNC_VendorID msg_vid;
+ TNC_MessageSubtype msg_subtype;
+
+ msg_vid = msg_type >> 8;
+ msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+
+ return receive_message(imv_id, connection_id, 0, chunk_create(msg, msg_len),
+ msg_vid, msg_subtype, 0, TNC_IMVID_ANY);
+}
+
+/**
+ * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_ReceiveMessageLong(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id)
+{
+ return receive_message(imv_id, connection_id, msg_flags,
+ chunk_create(msg, msg_len), msg_vid, msg_subtype,
+ src_imc_id, dst_imv_id);
+}
+
+/**
+ * see section 3.8.7 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_SolicitRecommendation(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id)
+{
+ if (!imv_scanner)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return imv_scanner->provide_recommendation(imv_scanner, connection_id);
+}
+
+/**
+ * see section 3.8.8 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id)
+{
+ if (!imv_scanner)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.9 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_Terminate(TNC_IMVID imv_id)
+{
+ if (!imv_scanner)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ tcp_ports->destroy_function(tcp_ports, free);
+ udp_ports->destroy_function(udp_ports, free);
+ imv_scanner->destroy(imv_scanner);
+ imv_scanner = NULL;
+
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 4.2.8.1 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_ProvideBindFunction(TNC_IMVID imv_id,
+ TNC_TNCS_BindFunctionPointer bind_function)
+{
+ if (!imv_scanner)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return imv_scanner->bind_functions(imv_scanner, bind_function);
+}
diff --git a/src/libimcv/plugins/imv_scanner/imv_scanner_state.c b/src/libimcv/plugins/imv_scanner/imv_scanner_state.c
new file mode 100644
index 000000000..422cb980d
--- /dev/null
+++ b/src/libimcv/plugins/imv_scanner/imv_scanner_state.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2011 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 "imv_scanner_state.h"
+
+#include <utils/lexparser.h>
+#include <debug.h>
+
+typedef struct private_imv_scanner_state_t private_imv_scanner_state_t;
+
+/**
+ * Private data of an imv_scanner_state_t object.
+ */
+struct private_imv_scanner_state_t {
+
+ /**
+ * Public members of imv_scanner_state_t
+ */
+ imv_scanner_state_t public;
+
+ /**
+ * TNCCS connection ID
+ */
+ TNC_ConnectionID connection_id;
+
+ /**
+ * TNCCS connection state
+ */
+ TNC_ConnectionState state;
+
+ /**
+ * Does the TNCCS connection support long message types?
+ */
+ bool has_long;
+
+ /**
+ * Does the TNCCS connection support exclusive delivery?
+ */
+ bool has_excl;
+
+ /**
+ * IMV action recommendation
+ */
+ TNC_IMV_Action_Recommendation rec;
+
+ /**
+ * IMV evaluation result
+ */
+ TNC_IMV_Evaluation_Result eval;
+
+ /**
+ * String with list of ports that should be closed
+ */
+ char *violating_ports;
+
+ /**
+ * Local copy of the reason string
+ */
+ chunk_t reason_string;
+};
+
+typedef struct entry_t entry_t;
+
+/**
+ * Define an internal reason string entry
+ */
+struct entry_t {
+ char *lang;
+ char *string;
+};
+
+/**
+ * Table of multi-lingual reason string entries
+ */
+static entry_t reasons[] = {
+ { "en", "The following ports are open:" },
+ { "de", "Die folgenden Ports sind offen" },
+ { "fr", "Les ports suivants sont ouverts:" },
+ { "pl", "Następujące porty sa otwarte:" }
+};
+
+METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
+ private_imv_scanner_state_t *this)
+{
+ return this->connection_id;
+}
+
+METHOD(imv_state_t, has_long, bool,
+ private_imv_scanner_state_t *this)
+{
+ return this->has_long;
+}
+
+METHOD(imv_state_t, has_excl, bool,
+ private_imv_scanner_state_t *this)
+{
+ return this->has_excl;
+}
+
+METHOD(imv_state_t, set_flags, void,
+ private_imv_scanner_state_t *this, bool has_long, bool has_excl)
+{
+ this->has_long = has_long;
+ this->has_excl = has_excl;
+}
+
+METHOD(imv_state_t, change_state, void,
+ private_imv_scanner_state_t *this, TNC_ConnectionState new_state)
+{
+ this->state = new_state;
+}
+
+METHOD(imv_state_t, get_recommendation, void,
+ private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation *rec,
+ TNC_IMV_Evaluation_Result *eval)
+{
+ *rec = this->rec;
+ *eval = this->eval;
+}
+
+METHOD(imv_state_t, set_recommendation, void,
+ private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation rec,
+ TNC_IMV_Evaluation_Result eval)
+{
+ this->rec = rec;
+ this->eval = eval;
+}
+
+METHOD(imv_state_t, get_reason_string, bool,
+ private_imv_scanner_state_t *this, chunk_t preferred_language,
+ chunk_t *reason_string, chunk_t *reason_language)
+{
+ chunk_t pref_lang, lang;
+ u_char *pos;
+ int i;
+
+ if (!this->violating_ports)
+ {
+ return FALSE;
+ }
+
+ while (eat_whitespace(&preferred_language))
+ {
+ if (!extract_token(&pref_lang, ',', &preferred_language))
+ {
+ /* last entry in a comma-separated list or single entry */
+ pref_lang = preferred_language;
+ }
+
+ /* eat trailing whitespace */
+ pos = pref_lang.ptr + pref_lang.len - 1;
+ while (pref_lang.len && *pos-- == ' ')
+ {
+ pref_lang.len--;
+ }
+
+ for (i = 0 ; i < countof(reasons); i++)
+ {
+ lang = chunk_create(reasons[i].lang, strlen(reasons[i].lang));
+ if (chunk_equals(lang, pref_lang))
+ {
+ this->reason_string = chunk_cat("cc",
+ chunk_create(reasons[i].string,
+ strlen(reasons[i].string)),
+ chunk_create(this->violating_ports,
+ strlen(this->violating_ports)));
+ *reason_string = this->reason_string;
+ *reason_language = lang;
+ return TRUE;
+ }
+ }
+ }
+
+ /* no preferred language match found - use the default language */
+
+ this->reason_string = chunk_cat("cc",
+ chunk_create(reasons[0].string,
+ strlen(reasons[0].string)),
+ chunk_create(this->violating_ports,
+ strlen(this->violating_ports)));
+ *reason_string = this->reason_string;
+ *reason_language = chunk_create(reasons[0].lang,
+ strlen(reasons[0].lang));
+ return TRUE;
+}
+
+METHOD(imv_state_t, destroy, void,
+ private_imv_scanner_state_t *this)
+{
+ free(this->violating_ports);
+ free(this->reason_string.ptr);
+ free(this);
+}
+
+METHOD(imv_scanner_state_t, set_violating_ports, void,
+ private_imv_scanner_state_t *this, char *ports)
+{
+ this->violating_ports = strdup(ports);
+}
+
+/**
+ * Described in header.
+ */
+imv_state_t *imv_scanner_state_create(TNC_ConnectionID connection_id)
+{
+ private_imv_scanner_state_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .get_connection_id = _get_connection_id,
+ .has_long = _has_long,
+ .has_excl = _has_excl,
+ .set_flags = _set_flags,
+ .change_state = _change_state,
+ .get_recommendation = _get_recommendation,
+ .set_recommendation = _set_recommendation,
+ .get_reason_string = _get_reason_string,
+ .destroy = _destroy,
+ },
+ .set_violating_ports = _set_violating_ports,
+ },
+ .state = TNC_CONNECTION_STATE_CREATE,
+ .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
+ .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
+ .connection_id = connection_id,
+ );
+
+ return &this->public.interface;
+}
+
+
diff --git a/src/libimcv/plugins/imv_scanner/imv_scanner_state.h b/src/libimcv/plugins/imv_scanner/imv_scanner_state.h
new file mode 100644
index 000000000..716ddfea0
--- /dev/null
+++ b/src/libimcv/plugins/imv_scanner/imv_scanner_state.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 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 imv_scanner_state_t imv_scanner_state
+ * @{ @ingroup imv_scanner_state
+ */
+
+#ifndef IMV_SCANNER_STATE_H_
+#define IMV_SCANNER_STATE_H_
+
+#include <imv/imv_state.h>
+#include <library.h>
+
+typedef struct imv_scanner_state_t imv_scanner_state_t;
+
+/**
+ * Internal state of an imv_scanner_t connection instance
+ */
+struct imv_scanner_state_t {
+
+ /**
+ * imv_state_t interface
+ */
+ imv_state_t interface;
+
+ /**
+ * list of violating TCP and UDP ports
+ */
+ void (*set_violating_ports)(imv_scanner_state_t *this, char *ports);
+};
+
+/**
+ * Create an imv_scanner_state_t instance
+ *
+ * @param id connection ID
+ */
+imv_state_t* imv_scanner_state_create(TNC_ConnectionID id);
+
+#endif /** IMV_SCANNER_STATE_H_ @}*/
diff --git a/src/libimcv/plugins/imv_test/Makefile.am b/src/libimcv/plugins/imv_test/Makefile.am
new file mode 100644
index 000000000..4ca5b852b
--- /dev/null
+++ b/src/libimcv/plugins/imv_test/Makefile.am
@@ -0,0 +1,15 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libimcv
+
+AM_CFLAGS = -rdynamic
+
+imcv_LTLIBRARIES = imv-test.la
+
+imv_test_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+
+imv_test_la_SOURCES = imv_test.c imv_test_state.h imv_test_state.c
+
+imv_test_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libimcv/plugins/imv_test/Makefile.in b/src/libimcv/plugins/imv_test/Makefile.in
new file mode 100644
index 000000000..e51ad9afd
--- /dev/null
+++ b/src/libimcv/plugins/imv_test/Makefile.in
@@ -0,0 +1,600 @@
+# 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/libimcv/plugins/imv_test
+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)$(imcvdir)"
+LTLIBRARIES = $(imcv_LTLIBRARIES)
+imv_test_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+am_imv_test_la_OBJECTS = imv_test.lo imv_test_state.lo
+imv_test_la_OBJECTS = $(am_imv_test_la_OBJECTS)
+imv_test_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(imv_test_la_LDFLAGS) $(LDFLAGS) -o $@
+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 = $(imv_test_la_SOURCES)
+DIST_SOURCES = $(imv_test_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libtncif \
+ -I$(top_srcdir)/src/libimcv
+
+AM_CFLAGS = -rdynamic
+imcv_LTLIBRARIES = imv-test.la
+imv_test_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+
+imv_test_la_SOURCES = imv_test.c imv_test_state.h imv_test_state.c
+imv_test_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/libimcv/plugins/imv_test/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libimcv/plugins/imv_test/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):
+install-imcvLTLIBRARIES: $(imcv_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(imcvdir)" || $(MKDIR_P) "$(DESTDIR)$(imcvdir)"
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || 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)$(imcvdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(imcvdir)"; \
+ }
+
+uninstall-imcvLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(imcvdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(imcvdir)/$$f"; \
+ done
+
+clean-imcvLTLIBRARIES:
+ -test -z "$(imcv_LTLIBRARIES)" || rm -f $(imcv_LTLIBRARIES)
+ @list='$(imcv_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
+imv-test.la: $(imv_test_la_OBJECTS) $(imv_test_la_DEPENDENCIES)
+ $(imv_test_la_LINK) -rpath $(imcvdir) $(imv_test_la_OBJECTS) $(imv_test_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_test.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_test_state.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)$(imcvdir)"; 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-imcvLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-imcvLTLIBRARIES
+
+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-imcvLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-imcvLTLIBRARIES clean-libtool 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-imcvLTLIBRARIES install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-imcvLTLIBRARIES
+
+
+# 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/libimcv/plugins/imv_test/imv_test.c b/src/libimcv/plugins/imv_test/imv_test.c
new file mode 100644
index 000000000..0afd81aec
--- /dev/null
+++ b/src/libimcv/plugins/imv_test/imv_test.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2011 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 "imv_test_state.h"
+
+#include <imv/imv_agent.h>
+#include <pa_tnc/pa_tnc_msg.h>
+#include <ietf/ietf_attr.h>
+#include <ietf/ietf_attr_pa_tnc_error.h>
+#include <ita/ita_attr.h>
+#include <ita/ita_attr_command.h>
+
+#include <tncif_names.h>
+#include <tncif_pa_subtypes.h>
+
+#include <pen/pen.h>
+#include <debug.h>
+
+/* IMV definitions */
+
+static const char imv_name[] = "Test";
+
+#define IMV_VENDOR_ID PEN_ITA
+#define IMV_SUBTYPE PA_SUBTYPE_ITA_TEST
+
+static imv_agent_t *imv_test;
+
+/**
+ * see section 3.8.1 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id,
+ TNC_Version min_version,
+ TNC_Version max_version,
+ TNC_Version *actual_version)
+{
+ if (imv_test)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has already been initialized", imv_name);
+ return TNC_RESULT_ALREADY_INITIALIZED;
+ }
+ imv_test = imv_agent_create(imv_name, IMV_VENDOR_ID, IMV_SUBTYPE,
+ imv_id, actual_version);
+ if (!imv_test)
+ {
+ return TNC_RESULT_FATAL;
+ }
+ if (min_version > TNC_IFIMV_VERSION_1 || max_version < TNC_IFIMV_VERSION_1)
+ {
+ DBG1(DBG_IMV, "no common IF-IMV version");
+ return TNC_RESULT_NO_COMMON_VERSION;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.2 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_ConnectionState new_state)
+{
+ imv_state_t *state;
+
+ if (!imv_test)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ switch (new_state)
+ {
+ case TNC_CONNECTION_STATE_CREATE:
+ state = imv_test_state_create(connection_id);
+ return imv_test->create_state(imv_test, state);
+ case TNC_CONNECTION_STATE_DELETE:
+ return imv_test->delete_state(imv_test, connection_id);
+ default:
+ return imv_test->change_state(imv_test, connection_id,
+ new_state, NULL);
+ }
+}
+
+static TNC_Result receive_message(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ chunk_t msg,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id)
+{
+ pa_tnc_msg_t *pa_tnc_msg;
+ pa_tnc_attr_t *attr;
+ imv_state_t *state;
+ imv_test_state_t *test_state;
+ enumerator_t *enumerator;
+ TNC_Result result;
+ int rounds;
+ bool fatal_error, retry = FALSE;
+
+ if (!imv_test)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+
+ /* get current IMV state */
+ if (!imv_test->get_state(imv_test, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+ test_state = (imv_test_state_t*)state;
+
+ /* parse received PA-TNC message and automatically handle any errors */
+ result = imv_test->receive_message(imv_test, state, msg, msg_vid,
+ msg_subtype, src_imc_id, dst_imv_id, &pa_tnc_msg);
+
+ /* no parsed PA-TNC attributes available if an error occurred */
+ if (!pa_tnc_msg)
+ {
+ return result;
+ }
+
+ /* preprocess any IETF standard error attributes */
+ fatal_error = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg);
+
+ /* add any new IMC and set its number of rounds */
+ rounds = lib->settings->get_int(lib->settings,
+ "libimcv.plugins.imv-test.rounds", 0);
+ test_state->add_imc(test_state, src_imc_id, rounds);
+
+ /* analyze PA-TNC attributes */
+ enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ if (attr->get_vendor_id(attr) == PEN_ITA &&
+ attr->get_type(attr) == ITA_ATTR_COMMAND)
+ {
+ ita_attr_command_t *ita_attr;
+ char *command;
+
+ ita_attr = (ita_attr_command_t*)attr;
+ command = ita_attr->get_command(ita_attr);
+
+ if (streq(command, "allow"))
+ {
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_ALLOW,
+ TNC_IMV_EVALUATION_RESULT_COMPLIANT);
+ }
+ else if (streq(command, "isolate"))
+ {
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
+ TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR);
+ }
+ else if (streq(command, "block") || streq(command, "none"))
+ {
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS,
+ TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR);
+ }
+ else if (streq(command, "retry"))
+ {
+ retry = TRUE;
+ }
+ else
+ {
+ DBG1(DBG_IMV, "unsupported ITA Command '%s'", command);
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
+ TNC_IMV_EVALUATION_RESULT_ERROR);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ pa_tnc_msg->destroy(pa_tnc_msg);
+
+ if (fatal_error)
+ {
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
+ TNC_IMV_EVALUATION_RESULT_ERROR);
+ return imv_test->provide_recommendation(imv_test, connection_id);
+ }
+
+ /* request a handshake retry ? */
+ if (retry)
+ {
+ test_state->set_rounds(test_state, rounds);
+ return imv_test->request_handshake_retry(imv_id, connection_id,
+ TNC_RETRY_REASON_IMV_SERIOUS_EVENT);
+ }
+
+ /* repeat the measurement ? */
+ if (test_state->another_round(test_state, src_imc_id))
+ {
+ attr = ita_attr_command_create("repeat");
+ pa_tnc_msg = pa_tnc_msg_create();
+ pa_tnc_msg->add_attribute(pa_tnc_msg, attr);
+ pa_tnc_msg->build(pa_tnc_msg);
+ result = imv_test->send_message(imv_test, connection_id, TRUE, imv_id,
+ src_imc_id, pa_tnc_msg->get_encoding(pa_tnc_msg));
+ pa_tnc_msg->destroy(pa_tnc_msg);
+
+ return result;
+ }
+
+ return imv_test->provide_recommendation(imv_test, connection_id);
+}
+
+/**
+ * see section 3.8.4 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type)
+{
+ TNC_VendorID msg_vid;
+ TNC_MessageSubtype msg_subtype;
+
+ msg_vid = msg_type >> 8;
+ msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+
+ return receive_message(imv_id, connection_id, 0, chunk_create(msg, msg_len),
+ msg_vid, msg_subtype, 0, TNC_IMVID_ANY);
+}
+
+/**
+ * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_ReceiveMessageLong(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id)
+{
+ return receive_message(imv_id, connection_id, msg_flags,
+ chunk_create(msg, msg_len), msg_vid, msg_subtype,
+ src_imc_id, dst_imv_id);
+}
+
+/**
+ * see section 3.8.7 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_SolicitRecommendation(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id)
+{
+ if (!imv_test)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return imv_test->provide_recommendation(imv_test, connection_id);
+}
+
+/**
+ * see section 3.8.8 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id)
+{
+ if (!imv_test)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.9 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_Terminate(TNC_IMVID imv_id)
+{
+ if (!imv_test)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ imv_test->destroy(imv_test);
+ imv_test = NULL;
+
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 4.2.8.1 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_ProvideBindFunction(TNC_IMVID imv_id,
+ TNC_TNCS_BindFunctionPointer bind_function)
+{
+ if (!imv_test)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return imv_test->bind_functions(imv_test, bind_function);
+}
diff --git a/src/libimcv/plugins/imv_test/imv_test_state.c b/src/libimcv/plugins/imv_test/imv_test_state.c
new file mode 100644
index 000000000..530090af7
--- /dev/null
+++ b/src/libimcv/plugins/imv_test/imv_test_state.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2011 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 "imv_test_state.h"
+
+#include <utils/lexparser.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_imv_test_state_t private_imv_test_state_t;
+
+/**
+ * Private data of an imv_test_state_t object.
+ */
+struct private_imv_test_state_t {
+
+ /**
+ * Public members of imv_test_state_t
+ */
+ imv_test_state_t public;
+
+ /**
+ * TNCCS connection ID
+ */
+ TNC_ConnectionID connection_id;
+
+ /**
+ * TNCCS connection state
+ */
+ TNC_ConnectionState state;
+
+ /**
+ * Does the TNCCS connection support long message types?
+ */
+ bool has_long;
+
+ /**
+ * Does the TNCCS connection support exclusive delivery?
+ */
+ bool has_excl;
+
+ /**
+ * IMV action recommendation
+ */
+ TNC_IMV_Action_Recommendation rec;
+
+ /**
+ * IMV evaluation result
+ */
+ TNC_IMV_Evaluation_Result eval;
+
+ /**
+ * List of IMCs
+ */
+ linked_list_t *imcs;
+
+};
+
+typedef struct imc_entry_t imc_entry_t;
+
+/**
+ * Define an internal IMC entry
+ */
+struct imc_entry_t {
+ TNC_UInt32 imc_id;
+ int rounds;
+};
+
+typedef struct entry_t entry_t;
+
+/**
+ * Define an internal reason string entry
+ */
+struct entry_t {
+ char *lang;
+ char *string;
+};
+
+/**
+ * Table of multi-lingual reason string entries
+ */
+static entry_t reasons[] = {
+ { "en", "IMC Test was not configured with \"command = allow\"" },
+ { "de", "IMC Test wurde nicht mit \"command = allow\" konfiguriert" },
+ { "fr", "IMC Test n'etait pas configuré avec \"command = allow\"" },
+ { "pl", "IMC Test nie zostało skonfigurowany z \"command = allow\"" }
+};
+
+METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
+ private_imv_test_state_t *this)
+{
+ return this->connection_id;
+}
+
+METHOD(imv_state_t, has_long, bool,
+ private_imv_test_state_t *this)
+{
+ return this->has_long;
+}
+
+METHOD(imv_state_t, has_excl, bool,
+ private_imv_test_state_t *this)
+{
+ return this->has_excl;
+}
+
+METHOD(imv_state_t, set_flags, void,
+ private_imv_test_state_t *this, bool has_long, bool has_excl)
+{
+ this->has_long = has_long;
+ this->has_excl = has_excl;
+}
+
+METHOD(imv_state_t, change_state, void,
+ private_imv_test_state_t *this, TNC_ConnectionState new_state)
+{
+ this->state = new_state;
+}
+
+METHOD(imv_state_t, get_recommendation, void,
+ private_imv_test_state_t *this, TNC_IMV_Action_Recommendation *rec,
+ TNC_IMV_Evaluation_Result *eval)
+{
+ *rec = this->rec;
+ *eval = this->eval;
+}
+
+METHOD(imv_state_t, set_recommendation, void,
+ private_imv_test_state_t *this, TNC_IMV_Action_Recommendation rec,
+ TNC_IMV_Evaluation_Result eval)
+{
+ this->rec = rec;
+ this->eval = eval;
+}
+
+METHOD(imv_state_t, get_reason_string, bool,
+ private_imv_test_state_t *this, chunk_t preferred_language,
+ chunk_t *reason_string, chunk_t *reason_language)
+{
+ chunk_t pref_lang, lang;
+ u_char *pos;
+ int i;
+
+ while (eat_whitespace(&preferred_language))
+ {
+ if (!extract_token(&pref_lang, ',', &preferred_language))
+ {
+ /* last entry in a comma-separated list or single entry */
+ pref_lang = preferred_language;
+ }
+
+ /* eat trailing whitespace */
+ pos = pref_lang.ptr + pref_lang.len - 1;
+ while (pref_lang.len && *pos-- == ' ')
+ {
+ pref_lang.len--;
+ }
+
+ for (i = 0 ; i < countof(reasons); i++)
+ {
+ lang = chunk_create(reasons[i].lang, strlen(reasons[i].lang));
+ if (chunk_equals(lang, pref_lang))
+ {
+ *reason_language = lang;
+ *reason_string = chunk_create(reasons[i].string,
+ strlen(reasons[i].string));
+ return TRUE;
+ }
+ }
+ }
+
+ /* no preferred language match found - use the default language */
+ *reason_string = chunk_create(reasons[0].string,
+ strlen(reasons[0].string));
+ *reason_language = chunk_create(reasons[0].lang,
+ strlen(reasons[0].lang));
+ return TRUE;
+}
+
+METHOD(imv_state_t, destroy, void,
+ private_imv_test_state_t *this)
+{
+ this->imcs->destroy_function(this->imcs, free);
+ free(this);
+}
+
+METHOD(imv_test_state_t, add_imc, void,
+ private_imv_test_state_t *this, TNC_UInt32 imc_id, int rounds)
+{
+ enumerator_t *enumerator;
+ imc_entry_t *imc_entry;
+ bool found = FALSE;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc_entry))
+ {
+ if (imc_entry->imc_id == imc_id)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ imc_entry = malloc_thing(imc_entry_t);
+ imc_entry->imc_id = imc_id;
+ imc_entry->rounds = rounds;
+ this->imcs->insert_last(this->imcs, imc_entry);
+ }
+}
+
+METHOD(imv_test_state_t, set_rounds, void,
+ private_imv_test_state_t *this, int rounds)
+{
+ enumerator_t *enumerator;
+ imc_entry_t *imc_entry;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc_entry))
+ {
+ imc_entry->rounds = rounds;
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(imv_test_state_t, another_round, bool,
+ private_imv_test_state_t *this, TNC_UInt32 imc_id)
+{
+ enumerator_t *enumerator;
+ imc_entry_t *imc_entry;
+ bool not_finished = FALSE;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc_entry))
+ {
+ if (imc_entry->rounds > 0)
+ {
+ not_finished = TRUE;
+ }
+ if (imc_entry->imc_id == imc_id)
+ {
+ imc_entry->rounds--;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return not_finished;
+}
+
+/**
+ * Described in header.
+ */
+imv_state_t *imv_test_state_create(TNC_ConnectionID connection_id)
+{
+ private_imv_test_state_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .get_connection_id = _get_connection_id,
+ .has_long = _has_long,
+ .has_excl = _has_excl,
+ .set_flags = _set_flags,
+ .change_state = _change_state,
+ .get_recommendation = _get_recommendation,
+ .set_recommendation = _set_recommendation,
+ .get_reason_string = _get_reason_string,
+ .destroy = _destroy,
+ },
+ .add_imc = _add_imc,
+ .set_rounds = _set_rounds,
+ .another_round = _another_round,
+ },
+ .state = TNC_CONNECTION_STATE_CREATE,
+ .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
+ .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
+ .connection_id = connection_id,
+ .imcs = linked_list_create(),
+ );
+
+ return &this->public.interface;
+}
+
+
diff --git a/src/libimcv/plugins/imv_test/imv_test_state.h b/src/libimcv/plugins/imv_test/imv_test_state.h
new file mode 100644
index 000000000..af78d1470
--- /dev/null
+++ b/src/libimcv/plugins/imv_test/imv_test_state.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2011 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 imv_test_state_t imv_test_state
+ * @{ @ingroup imv_test_state
+ */
+
+#ifndef IMV_TEST_STATE_H_
+#define IMV_TEST_STATE_H_
+
+#include <imv/imv_state.h>
+#include <library.h>
+
+typedef struct imv_test_state_t imv_test_state_t;
+
+/**
+ * Internal state of an imv_test_t connection instance
+ */
+struct imv_test_state_t {
+
+ /**
+ * imv_state_t interface
+ */
+ imv_state_t interface;
+
+ /**
+ * Add an IMC
+ *
+ * @param imc_id ID of the IMC to be added
+ * @param rounds number of re-measurement rounds
+ */
+ void (*add_imc)(imv_test_state_t *this, TNC_UInt32 imc_id, int rounds);
+
+ /**
+ * Set the IMC-IMV round-trip count
+ *
+ * @param rounds number of re-measurement rounds
+ */
+ void (*set_rounds)(imv_test_state_t *this, int rounds);
+
+ /**
+ * Check and decrease IMC-IMV round-trip count
+ *
+ * @param imc_id ID of the IMC to be checked
+ * @return new connection state
+ */
+ bool (*another_round)(imv_test_state_t *this, TNC_UInt32 imc_id);
+};
+
+/**
+ * Create an imv_test_state_t instance
+ *
+ * @param id connection ID
+ */
+imv_state_t* imv_test_state_create(TNC_ConnectionID id);
+
+#endif /** IMV_TEST_STATE_H_ @}*/
diff --git a/src/libpts/Makefile.am b/src/libpts/Makefile.am
new file mode 100644
index 000000000..3ff941794
--- /dev/null
+++ b/src/libpts/Makefile.am
@@ -0,0 +1,58 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libimcv
+
+ipseclib_LTLIBRARIES = libpts.la
+
+libpts_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la -ltspi
+
+libpts_la_SOURCES = \
+ libpts.h libpts.c \
+ pts/pts.h pts/pts.c \
+ pts/pts_error.h pts/pts_error.c \
+ pts/pts_proto_caps.h \
+ pts/pts_req_func_comp_evid.h \
+ pts/pts_simple_evid_final.h \
+ pts/pts_creds.h pts/pts_creds.c \
+ pts/pts_database.h pts/pts_database.c \
+ pts/pts_dh_group.h pts/pts_dh_group.c \
+ pts/pts_file_meas.h pts/pts_file_meas.c \
+ pts/pts_file_meta.h pts/pts_file_meta.c \
+ pts/pts_file_type.h pts/pts_file_type.c \
+ pts/pts_meas_algo.h pts/pts_meas_algo.c \
+ pts/components/pts_component.h \
+ pts/components/pts_component_manager.h pts/components/pts_component_manager.c \
+ pts/components/pts_comp_evidence.h pts/components/pts_comp_evidence.c \
+ pts/components/pts_comp_func_name.h pts/components/pts_comp_func_name.c \
+ pts/components/ita/ita_comp_func_name.h pts/components/ita/ita_comp_func_name.c \
+ pts/components/ita/ita_comp_ima.h pts/components/ita/ita_comp_ima.c \
+ pts/components/ita/ita_comp_tboot.h pts/components/ita/ita_comp_tboot.c \
+ pts/components/ita/ita_comp_tgrub.h pts/components/ita/ita_comp_tgrub.c \
+ pts/components/tcg/tcg_comp_func_name.h pts/components/tcg/tcg_comp_func_name.c \
+ tcg/tcg_attr.h tcg/tcg_attr.c \
+ tcg/tcg_pts_attr_proto_caps.h tcg/tcg_pts_attr_proto_caps.c \
+ tcg/tcg_pts_attr_dh_nonce_params_req.h tcg/tcg_pts_attr_dh_nonce_params_req.c \
+ tcg/tcg_pts_attr_dh_nonce_params_resp.h tcg/tcg_pts_attr_dh_nonce_params_resp.c \
+ tcg/tcg_pts_attr_dh_nonce_finish.h tcg/tcg_pts_attr_dh_nonce_finish.c \
+ tcg/tcg_pts_attr_meas_algo.h tcg/tcg_pts_attr_meas_algo.c \
+ tcg/tcg_pts_attr_get_tpm_version_info.h tcg/tcg_pts_attr_get_tpm_version_info.c \
+ tcg/tcg_pts_attr_tpm_version_info.h tcg/tcg_pts_attr_tpm_version_info.c \
+ tcg/tcg_pts_attr_get_aik.h tcg/tcg_pts_attr_get_aik.c \
+ tcg/tcg_pts_attr_aik.h tcg/tcg_pts_attr_aik.c \
+ tcg/tcg_pts_attr_req_func_comp_evid.h tcg/tcg_pts_attr_req_func_comp_evid.c \
+ tcg/tcg_pts_attr_gen_attest_evid.h tcg/tcg_pts_attr_gen_attest_evid.c \
+ tcg/tcg_pts_attr_simple_comp_evid.h tcg/tcg_pts_attr_simple_comp_evid.c \
+ tcg/tcg_pts_attr_simple_evid_final.h tcg/tcg_pts_attr_simple_evid_final.c \
+ tcg/tcg_pts_attr_req_file_meas.h tcg/tcg_pts_attr_req_file_meas.c \
+ tcg/tcg_pts_attr_file_meas.h tcg/tcg_pts_attr_file_meas.c \
+ tcg/tcg_pts_attr_req_file_meta.h tcg/tcg_pts_attr_req_file_meta.c \
+ tcg/tcg_pts_attr_unix_file_meta.h tcg/tcg_pts_attr_unix_file_meta.c
+
+SUBDIRS = .
+
+if USE_IMC_ATTESTATION
+ SUBDIRS += plugins/imc_attestation
+endif
+
+if USE_IMV_ATTESTATION
+ SUBDIRS += plugins/imv_attestation
+endif
diff --git a/src/libpts/Makefile.in b/src/libpts/Makefile.in
new file mode 100644
index 000000000..d317cfea1
--- /dev/null
+++ b/src/libpts/Makefile.in
@@ -0,0 +1,1083 @@
+# 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@
+@USE_IMC_ATTESTATION_TRUE@am__append_1 = plugins/imc_attestation
+@USE_IMV_ATTESTATION_TRUE@am__append_2 = plugins/imv_attestation
+subdir = src/libpts
+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)$(ipseclibdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
+libpts_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la
+am_libpts_la_OBJECTS = libpts.lo pts.lo pts_error.lo pts_creds.lo \
+ pts_database.lo pts_dh_group.lo pts_file_meas.lo \
+ pts_file_meta.lo pts_file_type.lo pts_meas_algo.lo \
+ pts_component_manager.lo pts_comp_evidence.lo \
+ pts_comp_func_name.lo ita_comp_func_name.lo ita_comp_ima.lo \
+ ita_comp_tboot.lo ita_comp_tgrub.lo tcg_comp_func_name.lo \
+ tcg_attr.lo tcg_pts_attr_proto_caps.lo \
+ tcg_pts_attr_dh_nonce_params_req.lo \
+ tcg_pts_attr_dh_nonce_params_resp.lo \
+ tcg_pts_attr_dh_nonce_finish.lo tcg_pts_attr_meas_algo.lo \
+ tcg_pts_attr_get_tpm_version_info.lo \
+ tcg_pts_attr_tpm_version_info.lo tcg_pts_attr_get_aik.lo \
+ tcg_pts_attr_aik.lo tcg_pts_attr_req_func_comp_evid.lo \
+ tcg_pts_attr_gen_attest_evid.lo \
+ tcg_pts_attr_simple_comp_evid.lo \
+ tcg_pts_attr_simple_evid_final.lo \
+ tcg_pts_attr_req_file_meas.lo tcg_pts_attr_file_meas.lo \
+ tcg_pts_attr_req_file_meta.lo tcg_pts_attr_unix_file_meta.lo
+libpts_la_OBJECTS = $(am_libpts_la_OBJECTS)
+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 = $(libpts_la_SOURCES)
+DIST_SOURCES = $(libpts_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = . plugins/imc_attestation plugins/imv_attestation
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libimcv
+ipseclib_LTLIBRARIES = libpts.la
+libpts_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la -ltspi
+libpts_la_SOURCES = \
+ libpts.h libpts.c \
+ pts/pts.h pts/pts.c \
+ pts/pts_error.h pts/pts_error.c \
+ pts/pts_proto_caps.h \
+ pts/pts_req_func_comp_evid.h \
+ pts/pts_simple_evid_final.h \
+ pts/pts_creds.h pts/pts_creds.c \
+ pts/pts_database.h pts/pts_database.c \
+ pts/pts_dh_group.h pts/pts_dh_group.c \
+ pts/pts_file_meas.h pts/pts_file_meas.c \
+ pts/pts_file_meta.h pts/pts_file_meta.c \
+ pts/pts_file_type.h pts/pts_file_type.c \
+ pts/pts_meas_algo.h pts/pts_meas_algo.c \
+ pts/components/pts_component.h \
+ pts/components/pts_component_manager.h pts/components/pts_component_manager.c \
+ pts/components/pts_comp_evidence.h pts/components/pts_comp_evidence.c \
+ pts/components/pts_comp_func_name.h pts/components/pts_comp_func_name.c \
+ pts/components/ita/ita_comp_func_name.h pts/components/ita/ita_comp_func_name.c \
+ pts/components/ita/ita_comp_ima.h pts/components/ita/ita_comp_ima.c \
+ pts/components/ita/ita_comp_tboot.h pts/components/ita/ita_comp_tboot.c \
+ pts/components/ita/ita_comp_tgrub.h pts/components/ita/ita_comp_tgrub.c \
+ pts/components/tcg/tcg_comp_func_name.h pts/components/tcg/tcg_comp_func_name.c \
+ tcg/tcg_attr.h tcg/tcg_attr.c \
+ tcg/tcg_pts_attr_proto_caps.h tcg/tcg_pts_attr_proto_caps.c \
+ tcg/tcg_pts_attr_dh_nonce_params_req.h tcg/tcg_pts_attr_dh_nonce_params_req.c \
+ tcg/tcg_pts_attr_dh_nonce_params_resp.h tcg/tcg_pts_attr_dh_nonce_params_resp.c \
+ tcg/tcg_pts_attr_dh_nonce_finish.h tcg/tcg_pts_attr_dh_nonce_finish.c \
+ tcg/tcg_pts_attr_meas_algo.h tcg/tcg_pts_attr_meas_algo.c \
+ tcg/tcg_pts_attr_get_tpm_version_info.h tcg/tcg_pts_attr_get_tpm_version_info.c \
+ tcg/tcg_pts_attr_tpm_version_info.h tcg/tcg_pts_attr_tpm_version_info.c \
+ tcg/tcg_pts_attr_get_aik.h tcg/tcg_pts_attr_get_aik.c \
+ tcg/tcg_pts_attr_aik.h tcg/tcg_pts_attr_aik.c \
+ tcg/tcg_pts_attr_req_func_comp_evid.h tcg/tcg_pts_attr_req_func_comp_evid.c \
+ tcg/tcg_pts_attr_gen_attest_evid.h tcg/tcg_pts_attr_gen_attest_evid.c \
+ tcg/tcg_pts_attr_simple_comp_evid.h tcg/tcg_pts_attr_simple_comp_evid.c \
+ tcg/tcg_pts_attr_simple_evid_final.h tcg/tcg_pts_attr_simple_evid_final.c \
+ tcg/tcg_pts_attr_req_file_meas.h tcg/tcg_pts_attr_req_file_meas.c \
+ tcg/tcg_pts_attr_file_meas.h tcg/tcg_pts_attr_file_meas.c \
+ tcg/tcg_pts_attr_req_file_meta.h tcg/tcg_pts_attr_req_file_meta.c \
+ tcg/tcg_pts_attr_unix_file_meta.h tcg/tcg_pts_attr_unix_file_meta.c
+
+SUBDIRS = . $(am__append_1) $(am__append_2)
+all: all-recursive
+
+.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/libpts/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libpts/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):
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
+ }
+
+uninstall-ipseclibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
+ done
+
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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
+libpts.la: $(libpts_la_OBJECTS) $(libpts_la_DEPENDENCIES)
+ $(LINK) -rpath $(ipseclibdir) $(libpts_la_OBJECTS) $(libpts_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ita_comp_func_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ita_comp_ima.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ita_comp_tboot.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ita_comp_tgrub.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libpts.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_comp_evidence.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_comp_func_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_component_manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_creds.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_database.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_dh_group.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_error.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_file_meas.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_file_meta.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_file_type.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_meas_algo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_attr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_comp_func_name.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_aik.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_dh_nonce_finish.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_dh_nonce_params_req.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_dh_nonce_params_resp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_file_meas.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_gen_attest_evid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_get_aik.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_get_tpm_version_info.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_meas_algo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_proto_caps.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_req_file_meas.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_req_file_meta.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_req_func_comp_evid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_simple_comp_evid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_simple_evid_final.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_tpm_version_info.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_unix_file_meta.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 $@ $<
+
+pts.lo: pts/pts.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts.lo -MD -MP -MF $(DEPDIR)/pts.Tpo -c -o pts.lo `test -f 'pts/pts.c' || echo '$(srcdir)/'`pts/pts.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts.Tpo $(DEPDIR)/pts.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/pts.c' object='pts.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 pts.lo `test -f 'pts/pts.c' || echo '$(srcdir)/'`pts/pts.c
+
+pts_error.lo: pts/pts_error.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_error.lo -MD -MP -MF $(DEPDIR)/pts_error.Tpo -c -o pts_error.lo `test -f 'pts/pts_error.c' || echo '$(srcdir)/'`pts/pts_error.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_error.Tpo $(DEPDIR)/pts_error.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/pts_error.c' object='pts_error.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 pts_error.lo `test -f 'pts/pts_error.c' || echo '$(srcdir)/'`pts/pts_error.c
+
+pts_creds.lo: pts/pts_creds.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_creds.lo -MD -MP -MF $(DEPDIR)/pts_creds.Tpo -c -o pts_creds.lo `test -f 'pts/pts_creds.c' || echo '$(srcdir)/'`pts/pts_creds.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_creds.Tpo $(DEPDIR)/pts_creds.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/pts_creds.c' object='pts_creds.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 pts_creds.lo `test -f 'pts/pts_creds.c' || echo '$(srcdir)/'`pts/pts_creds.c
+
+pts_database.lo: pts/pts_database.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_database.lo -MD -MP -MF $(DEPDIR)/pts_database.Tpo -c -o pts_database.lo `test -f 'pts/pts_database.c' || echo '$(srcdir)/'`pts/pts_database.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_database.Tpo $(DEPDIR)/pts_database.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/pts_database.c' object='pts_database.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 pts_database.lo `test -f 'pts/pts_database.c' || echo '$(srcdir)/'`pts/pts_database.c
+
+pts_dh_group.lo: pts/pts_dh_group.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_dh_group.lo -MD -MP -MF $(DEPDIR)/pts_dh_group.Tpo -c -o pts_dh_group.lo `test -f 'pts/pts_dh_group.c' || echo '$(srcdir)/'`pts/pts_dh_group.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_dh_group.Tpo $(DEPDIR)/pts_dh_group.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/pts_dh_group.c' object='pts_dh_group.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 pts_dh_group.lo `test -f 'pts/pts_dh_group.c' || echo '$(srcdir)/'`pts/pts_dh_group.c
+
+pts_file_meas.lo: pts/pts_file_meas.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_file_meas.lo -MD -MP -MF $(DEPDIR)/pts_file_meas.Tpo -c -o pts_file_meas.lo `test -f 'pts/pts_file_meas.c' || echo '$(srcdir)/'`pts/pts_file_meas.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_file_meas.Tpo $(DEPDIR)/pts_file_meas.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/pts_file_meas.c' object='pts_file_meas.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 pts_file_meas.lo `test -f 'pts/pts_file_meas.c' || echo '$(srcdir)/'`pts/pts_file_meas.c
+
+pts_file_meta.lo: pts/pts_file_meta.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_file_meta.lo -MD -MP -MF $(DEPDIR)/pts_file_meta.Tpo -c -o pts_file_meta.lo `test -f 'pts/pts_file_meta.c' || echo '$(srcdir)/'`pts/pts_file_meta.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_file_meta.Tpo $(DEPDIR)/pts_file_meta.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/pts_file_meta.c' object='pts_file_meta.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 pts_file_meta.lo `test -f 'pts/pts_file_meta.c' || echo '$(srcdir)/'`pts/pts_file_meta.c
+
+pts_file_type.lo: pts/pts_file_type.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_file_type.lo -MD -MP -MF $(DEPDIR)/pts_file_type.Tpo -c -o pts_file_type.lo `test -f 'pts/pts_file_type.c' || echo '$(srcdir)/'`pts/pts_file_type.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_file_type.Tpo $(DEPDIR)/pts_file_type.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/pts_file_type.c' object='pts_file_type.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 pts_file_type.lo `test -f 'pts/pts_file_type.c' || echo '$(srcdir)/'`pts/pts_file_type.c
+
+pts_meas_algo.lo: pts/pts_meas_algo.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_meas_algo.lo -MD -MP -MF $(DEPDIR)/pts_meas_algo.Tpo -c -o pts_meas_algo.lo `test -f 'pts/pts_meas_algo.c' || echo '$(srcdir)/'`pts/pts_meas_algo.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_meas_algo.Tpo $(DEPDIR)/pts_meas_algo.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/pts_meas_algo.c' object='pts_meas_algo.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 pts_meas_algo.lo `test -f 'pts/pts_meas_algo.c' || echo '$(srcdir)/'`pts/pts_meas_algo.c
+
+pts_component_manager.lo: pts/components/pts_component_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 pts_component_manager.lo -MD -MP -MF $(DEPDIR)/pts_component_manager.Tpo -c -o pts_component_manager.lo `test -f 'pts/components/pts_component_manager.c' || echo '$(srcdir)/'`pts/components/pts_component_manager.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_component_manager.Tpo $(DEPDIR)/pts_component_manager.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/components/pts_component_manager.c' object='pts_component_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 pts_component_manager.lo `test -f 'pts/components/pts_component_manager.c' || echo '$(srcdir)/'`pts/components/pts_component_manager.c
+
+pts_comp_evidence.lo: pts/components/pts_comp_evidence.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_comp_evidence.lo -MD -MP -MF $(DEPDIR)/pts_comp_evidence.Tpo -c -o pts_comp_evidence.lo `test -f 'pts/components/pts_comp_evidence.c' || echo '$(srcdir)/'`pts/components/pts_comp_evidence.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_comp_evidence.Tpo $(DEPDIR)/pts_comp_evidence.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/components/pts_comp_evidence.c' object='pts_comp_evidence.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 pts_comp_evidence.lo `test -f 'pts/components/pts_comp_evidence.c' || echo '$(srcdir)/'`pts/components/pts_comp_evidence.c
+
+pts_comp_func_name.lo: pts/components/pts_comp_func_name.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_comp_func_name.lo -MD -MP -MF $(DEPDIR)/pts_comp_func_name.Tpo -c -o pts_comp_func_name.lo `test -f 'pts/components/pts_comp_func_name.c' || echo '$(srcdir)/'`pts/components/pts_comp_func_name.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_comp_func_name.Tpo $(DEPDIR)/pts_comp_func_name.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/components/pts_comp_func_name.c' object='pts_comp_func_name.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 pts_comp_func_name.lo `test -f 'pts/components/pts_comp_func_name.c' || echo '$(srcdir)/'`pts/components/pts_comp_func_name.c
+
+ita_comp_func_name.lo: pts/components/ita/ita_comp_func_name.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ita_comp_func_name.lo -MD -MP -MF $(DEPDIR)/ita_comp_func_name.Tpo -c -o ita_comp_func_name.lo `test -f 'pts/components/ita/ita_comp_func_name.c' || echo '$(srcdir)/'`pts/components/ita/ita_comp_func_name.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ita_comp_func_name.Tpo $(DEPDIR)/ita_comp_func_name.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/components/ita/ita_comp_func_name.c' object='ita_comp_func_name.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 ita_comp_func_name.lo `test -f 'pts/components/ita/ita_comp_func_name.c' || echo '$(srcdir)/'`pts/components/ita/ita_comp_func_name.c
+
+ita_comp_ima.lo: pts/components/ita/ita_comp_ima.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ita_comp_ima.lo -MD -MP -MF $(DEPDIR)/ita_comp_ima.Tpo -c -o ita_comp_ima.lo `test -f 'pts/components/ita/ita_comp_ima.c' || echo '$(srcdir)/'`pts/components/ita/ita_comp_ima.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ita_comp_ima.Tpo $(DEPDIR)/ita_comp_ima.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/components/ita/ita_comp_ima.c' object='ita_comp_ima.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 ita_comp_ima.lo `test -f 'pts/components/ita/ita_comp_ima.c' || echo '$(srcdir)/'`pts/components/ita/ita_comp_ima.c
+
+ita_comp_tboot.lo: pts/components/ita/ita_comp_tboot.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ita_comp_tboot.lo -MD -MP -MF $(DEPDIR)/ita_comp_tboot.Tpo -c -o ita_comp_tboot.lo `test -f 'pts/components/ita/ita_comp_tboot.c' || echo '$(srcdir)/'`pts/components/ita/ita_comp_tboot.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ita_comp_tboot.Tpo $(DEPDIR)/ita_comp_tboot.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/components/ita/ita_comp_tboot.c' object='ita_comp_tboot.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 ita_comp_tboot.lo `test -f 'pts/components/ita/ita_comp_tboot.c' || echo '$(srcdir)/'`pts/components/ita/ita_comp_tboot.c
+
+ita_comp_tgrub.lo: pts/components/ita/ita_comp_tgrub.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ita_comp_tgrub.lo -MD -MP -MF $(DEPDIR)/ita_comp_tgrub.Tpo -c -o ita_comp_tgrub.lo `test -f 'pts/components/ita/ita_comp_tgrub.c' || echo '$(srcdir)/'`pts/components/ita/ita_comp_tgrub.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ita_comp_tgrub.Tpo $(DEPDIR)/ita_comp_tgrub.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/components/ita/ita_comp_tgrub.c' object='ita_comp_tgrub.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 ita_comp_tgrub.lo `test -f 'pts/components/ita/ita_comp_tgrub.c' || echo '$(srcdir)/'`pts/components/ita/ita_comp_tgrub.c
+
+tcg_comp_func_name.lo: pts/components/tcg/tcg_comp_func_name.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_comp_func_name.lo -MD -MP -MF $(DEPDIR)/tcg_comp_func_name.Tpo -c -o tcg_comp_func_name.lo `test -f 'pts/components/tcg/tcg_comp_func_name.c' || echo '$(srcdir)/'`pts/components/tcg/tcg_comp_func_name.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_comp_func_name.Tpo $(DEPDIR)/tcg_comp_func_name.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/components/tcg/tcg_comp_func_name.c' object='tcg_comp_func_name.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 tcg_comp_func_name.lo `test -f 'pts/components/tcg/tcg_comp_func_name.c' || echo '$(srcdir)/'`pts/components/tcg/tcg_comp_func_name.c
+
+tcg_attr.lo: tcg/tcg_attr.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_attr.lo -MD -MP -MF $(DEPDIR)/tcg_attr.Tpo -c -o tcg_attr.lo `test -f 'tcg/tcg_attr.c' || echo '$(srcdir)/'`tcg/tcg_attr.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_attr.Tpo $(DEPDIR)/tcg_attr.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_attr.c' object='tcg_attr.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 tcg_attr.lo `test -f 'tcg/tcg_attr.c' || echo '$(srcdir)/'`tcg/tcg_attr.c
+
+tcg_pts_attr_proto_caps.lo: tcg/tcg_pts_attr_proto_caps.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_proto_caps.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_proto_caps.Tpo -c -o tcg_pts_attr_proto_caps.lo `test -f 'tcg/tcg_pts_attr_proto_caps.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_proto_caps.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_proto_caps.Tpo $(DEPDIR)/tcg_pts_attr_proto_caps.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_proto_caps.c' object='tcg_pts_attr_proto_caps.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 tcg_pts_attr_proto_caps.lo `test -f 'tcg/tcg_pts_attr_proto_caps.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_proto_caps.c
+
+tcg_pts_attr_dh_nonce_params_req.lo: tcg/tcg_pts_attr_dh_nonce_params_req.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_dh_nonce_params_req.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_dh_nonce_params_req.Tpo -c -o tcg_pts_attr_dh_nonce_params_req.lo `test -f 'tcg/tcg_pts_attr_dh_nonce_params_req.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_dh_nonce_params_req.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_dh_nonce_params_req.Tpo $(DEPDIR)/tcg_pts_attr_dh_nonce_params_req.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_dh_nonce_params_req.c' object='tcg_pts_attr_dh_nonce_params_req.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 tcg_pts_attr_dh_nonce_params_req.lo `test -f 'tcg/tcg_pts_attr_dh_nonce_params_req.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_dh_nonce_params_req.c
+
+tcg_pts_attr_dh_nonce_params_resp.lo: tcg/tcg_pts_attr_dh_nonce_params_resp.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_dh_nonce_params_resp.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_dh_nonce_params_resp.Tpo -c -o tcg_pts_attr_dh_nonce_params_resp.lo `test -f 'tcg/tcg_pts_attr_dh_nonce_params_resp.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_dh_nonce_params_resp.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_dh_nonce_params_resp.Tpo $(DEPDIR)/tcg_pts_attr_dh_nonce_params_resp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_dh_nonce_params_resp.c' object='tcg_pts_attr_dh_nonce_params_resp.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 tcg_pts_attr_dh_nonce_params_resp.lo `test -f 'tcg/tcg_pts_attr_dh_nonce_params_resp.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_dh_nonce_params_resp.c
+
+tcg_pts_attr_dh_nonce_finish.lo: tcg/tcg_pts_attr_dh_nonce_finish.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_dh_nonce_finish.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_dh_nonce_finish.Tpo -c -o tcg_pts_attr_dh_nonce_finish.lo `test -f 'tcg/tcg_pts_attr_dh_nonce_finish.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_dh_nonce_finish.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_dh_nonce_finish.Tpo $(DEPDIR)/tcg_pts_attr_dh_nonce_finish.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_dh_nonce_finish.c' object='tcg_pts_attr_dh_nonce_finish.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 tcg_pts_attr_dh_nonce_finish.lo `test -f 'tcg/tcg_pts_attr_dh_nonce_finish.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_dh_nonce_finish.c
+
+tcg_pts_attr_meas_algo.lo: tcg/tcg_pts_attr_meas_algo.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_meas_algo.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_meas_algo.Tpo -c -o tcg_pts_attr_meas_algo.lo `test -f 'tcg/tcg_pts_attr_meas_algo.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_meas_algo.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_meas_algo.Tpo $(DEPDIR)/tcg_pts_attr_meas_algo.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_meas_algo.c' object='tcg_pts_attr_meas_algo.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 tcg_pts_attr_meas_algo.lo `test -f 'tcg/tcg_pts_attr_meas_algo.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_meas_algo.c
+
+tcg_pts_attr_get_tpm_version_info.lo: tcg/tcg_pts_attr_get_tpm_version_info.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_get_tpm_version_info.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_get_tpm_version_info.Tpo -c -o tcg_pts_attr_get_tpm_version_info.lo `test -f 'tcg/tcg_pts_attr_get_tpm_version_info.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_get_tpm_version_info.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_get_tpm_version_info.Tpo $(DEPDIR)/tcg_pts_attr_get_tpm_version_info.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_get_tpm_version_info.c' object='tcg_pts_attr_get_tpm_version_info.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 tcg_pts_attr_get_tpm_version_info.lo `test -f 'tcg/tcg_pts_attr_get_tpm_version_info.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_get_tpm_version_info.c
+
+tcg_pts_attr_tpm_version_info.lo: tcg/tcg_pts_attr_tpm_version_info.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_tpm_version_info.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_tpm_version_info.Tpo -c -o tcg_pts_attr_tpm_version_info.lo `test -f 'tcg/tcg_pts_attr_tpm_version_info.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_tpm_version_info.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_tpm_version_info.Tpo $(DEPDIR)/tcg_pts_attr_tpm_version_info.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_tpm_version_info.c' object='tcg_pts_attr_tpm_version_info.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 tcg_pts_attr_tpm_version_info.lo `test -f 'tcg/tcg_pts_attr_tpm_version_info.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_tpm_version_info.c
+
+tcg_pts_attr_get_aik.lo: tcg/tcg_pts_attr_get_aik.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_get_aik.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_get_aik.Tpo -c -o tcg_pts_attr_get_aik.lo `test -f 'tcg/tcg_pts_attr_get_aik.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_get_aik.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_get_aik.Tpo $(DEPDIR)/tcg_pts_attr_get_aik.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_get_aik.c' object='tcg_pts_attr_get_aik.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 tcg_pts_attr_get_aik.lo `test -f 'tcg/tcg_pts_attr_get_aik.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_get_aik.c
+
+tcg_pts_attr_aik.lo: tcg/tcg_pts_attr_aik.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_aik.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_aik.Tpo -c -o tcg_pts_attr_aik.lo `test -f 'tcg/tcg_pts_attr_aik.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_aik.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_aik.Tpo $(DEPDIR)/tcg_pts_attr_aik.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_aik.c' object='tcg_pts_attr_aik.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 tcg_pts_attr_aik.lo `test -f 'tcg/tcg_pts_attr_aik.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_aik.c
+
+tcg_pts_attr_req_func_comp_evid.lo: tcg/tcg_pts_attr_req_func_comp_evid.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_req_func_comp_evid.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_req_func_comp_evid.Tpo -c -o tcg_pts_attr_req_func_comp_evid.lo `test -f 'tcg/tcg_pts_attr_req_func_comp_evid.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_req_func_comp_evid.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_req_func_comp_evid.Tpo $(DEPDIR)/tcg_pts_attr_req_func_comp_evid.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_req_func_comp_evid.c' object='tcg_pts_attr_req_func_comp_evid.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 tcg_pts_attr_req_func_comp_evid.lo `test -f 'tcg/tcg_pts_attr_req_func_comp_evid.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_req_func_comp_evid.c
+
+tcg_pts_attr_gen_attest_evid.lo: tcg/tcg_pts_attr_gen_attest_evid.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_gen_attest_evid.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_gen_attest_evid.Tpo -c -o tcg_pts_attr_gen_attest_evid.lo `test -f 'tcg/tcg_pts_attr_gen_attest_evid.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_gen_attest_evid.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_gen_attest_evid.Tpo $(DEPDIR)/tcg_pts_attr_gen_attest_evid.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_gen_attest_evid.c' object='tcg_pts_attr_gen_attest_evid.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 tcg_pts_attr_gen_attest_evid.lo `test -f 'tcg/tcg_pts_attr_gen_attest_evid.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_gen_attest_evid.c
+
+tcg_pts_attr_simple_comp_evid.lo: tcg/tcg_pts_attr_simple_comp_evid.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_simple_comp_evid.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_simple_comp_evid.Tpo -c -o tcg_pts_attr_simple_comp_evid.lo `test -f 'tcg/tcg_pts_attr_simple_comp_evid.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_simple_comp_evid.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_simple_comp_evid.Tpo $(DEPDIR)/tcg_pts_attr_simple_comp_evid.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_simple_comp_evid.c' object='tcg_pts_attr_simple_comp_evid.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 tcg_pts_attr_simple_comp_evid.lo `test -f 'tcg/tcg_pts_attr_simple_comp_evid.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_simple_comp_evid.c
+
+tcg_pts_attr_simple_evid_final.lo: tcg/tcg_pts_attr_simple_evid_final.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_simple_evid_final.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_simple_evid_final.Tpo -c -o tcg_pts_attr_simple_evid_final.lo `test -f 'tcg/tcg_pts_attr_simple_evid_final.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_simple_evid_final.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_simple_evid_final.Tpo $(DEPDIR)/tcg_pts_attr_simple_evid_final.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_simple_evid_final.c' object='tcg_pts_attr_simple_evid_final.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 tcg_pts_attr_simple_evid_final.lo `test -f 'tcg/tcg_pts_attr_simple_evid_final.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_simple_evid_final.c
+
+tcg_pts_attr_req_file_meas.lo: tcg/tcg_pts_attr_req_file_meas.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_req_file_meas.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_req_file_meas.Tpo -c -o tcg_pts_attr_req_file_meas.lo `test -f 'tcg/tcg_pts_attr_req_file_meas.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_req_file_meas.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_req_file_meas.Tpo $(DEPDIR)/tcg_pts_attr_req_file_meas.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_req_file_meas.c' object='tcg_pts_attr_req_file_meas.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 tcg_pts_attr_req_file_meas.lo `test -f 'tcg/tcg_pts_attr_req_file_meas.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_req_file_meas.c
+
+tcg_pts_attr_file_meas.lo: tcg/tcg_pts_attr_file_meas.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_file_meas.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_file_meas.Tpo -c -o tcg_pts_attr_file_meas.lo `test -f 'tcg/tcg_pts_attr_file_meas.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_file_meas.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_file_meas.Tpo $(DEPDIR)/tcg_pts_attr_file_meas.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_file_meas.c' object='tcg_pts_attr_file_meas.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 tcg_pts_attr_file_meas.lo `test -f 'tcg/tcg_pts_attr_file_meas.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_file_meas.c
+
+tcg_pts_attr_req_file_meta.lo: tcg/tcg_pts_attr_req_file_meta.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_req_file_meta.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_req_file_meta.Tpo -c -o tcg_pts_attr_req_file_meta.lo `test -f 'tcg/tcg_pts_attr_req_file_meta.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_req_file_meta.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_req_file_meta.Tpo $(DEPDIR)/tcg_pts_attr_req_file_meta.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_req_file_meta.c' object='tcg_pts_attr_req_file_meta.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 tcg_pts_attr_req_file_meta.lo `test -f 'tcg/tcg_pts_attr_req_file_meta.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_req_file_meta.c
+
+tcg_pts_attr_unix_file_meta.lo: tcg/tcg_pts_attr_unix_file_meta.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tcg_pts_attr_unix_file_meta.lo -MD -MP -MF $(DEPDIR)/tcg_pts_attr_unix_file_meta.Tpo -c -o tcg_pts_attr_unix_file_meta.lo `test -f 'tcg/tcg_pts_attr_unix_file_meta.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_unix_file_meta.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcg_pts_attr_unix_file_meta.Tpo $(DEPDIR)/tcg_pts_attr_unix_file_meta.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcg/tcg_pts_attr_unix_file_meta.c' object='tcg_pts_attr_unix_file_meta.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 tcg_pts_attr_unix_file_meta.lo `test -f 'tcg/tcg_pts_attr_unix_file_meta.c' || echo '$(srcdir)/'`tcg/tcg_pts_attr_unix_file_meta.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+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: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ 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: ctags-recursive $(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
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(ipseclibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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-recursive
+
+clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-ipseclibLTLIBRARIES
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-ipseclibLTLIBRARIES
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic \
+ clean-ipseclibLTLIBRARIES clean-libtool ctags ctags-recursive \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-ipseclibLTLIBRARIES install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-ipseclibLTLIBRARIES
+
+
+# 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/libpts/libpts.c b/src/libpts/libpts.c
new file mode 100644
index 000000000..384ee4ed7
--- /dev/null
+++ b/src/libpts/libpts.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 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 "libpts.h"
+#include "tcg/tcg_attr.h"
+#include "pts/components/pts_component.h"
+#include "pts/components/pts_component_manager.h"
+#include "pts/components/tcg/tcg_comp_func_name.h"
+#include "pts/components/ita/ita_comp_func_name.h"
+#include "pts/components/ita/ita_comp_ima.h"
+#include "pts/components/ita/ita_comp_tboot.h"
+#include "pts/components/ita/ita_comp_tgrub.h"
+
+#include <imcv.h>
+#include <debug.h>
+
+/**
+ * PTS Functional Component manager
+ */
+pts_component_manager_t *pts_components;
+
+/**
+ * Reference count for IMC/IMV instances
+ */
+static refcount_t libpts_ref = 0;
+
+/**
+ * Described in header.
+ */
+bool libpts_init(void)
+{
+ if (libpts_ref == 0)
+ {
+ if (!imcv_pa_tnc_attributes)
+ {
+ return FALSE;
+ }
+ imcv_pa_tnc_attributes->add_vendor(imcv_pa_tnc_attributes, PEN_TCG,
+ tcg_attr_create_from_data, tcg_attr_names);
+
+ pts_components = pts_component_manager_create();
+ pts_components->add_vendor(pts_components, PEN_TCG,
+ pts_tcg_comp_func_names, PTS_TCG_QUALIFIER_TYPE_SIZE,
+ pts_tcg_qualifier_flag_names, pts_tcg_qualifier_type_names);
+ pts_components->add_vendor(pts_components, PEN_ITA,
+ pts_ita_comp_func_names, PTS_ITA_QUALIFIER_TYPE_SIZE,
+ pts_ita_qualifier_flag_names, pts_ita_qualifier_type_names);
+
+ pts_components->add_component(pts_components, PEN_ITA,
+ PTS_ITA_COMP_FUNC_NAME_TGRUB,
+ pts_ita_comp_tgrub_create);
+ pts_components->add_component(pts_components, PEN_ITA,
+ PTS_ITA_COMP_FUNC_NAME_TBOOT,
+ pts_ita_comp_tboot_create);
+ pts_components->add_component(pts_components, PEN_ITA,
+ PTS_ITA_COMP_FUNC_NAME_IMA,
+ pts_ita_comp_ima_create);
+
+ DBG1(DBG_LIB, "libpts initialized");
+ }
+ ref_get(&libpts_ref);
+
+ return TRUE;
+}
+
+/**
+ * Described in header.
+ */
+void libpts_deinit(void)
+{
+ if (ref_put(&libpts_ref))
+ {
+ pts_components->remove_vendor(pts_components, PEN_TCG);
+ pts_components->remove_vendor(pts_components, PEN_ITA);
+ pts_components->destroy(pts_components);
+
+ if (!imcv_pa_tnc_attributes)
+ {
+ return;
+ }
+ imcv_pa_tnc_attributes->remove_vendor(imcv_pa_tnc_attributes, PEN_TCG);
+ DBG1(DBG_LIB, "libpts terminated");
+ }
+}
+
diff --git a/src/libpts/libpts.h b/src/libpts/libpts.h
new file mode 100644
index 000000000..7b2959728
--- /dev/null
+++ b/src/libpts/libpts.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 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 libpts libpts
+ *
+ * @defgroup iplugins plugins
+ * @ingroup libpts
+ *
+ * @addtogroup libpts
+ * @{
+ */
+
+#ifndef LIBPTS_H_
+#define LIBPTS_H_
+
+#include "pts/components/pts_component_manager.h"
+
+#include <library.h>
+
+/**
+ * Initialize libpts.
+ *
+ * @return FALSE if initialization failed
+ */
+bool libpts_init(void);
+
+/**
+ * Deinitialize libpts.
+ */
+void libpts_deinit(void);
+
+/**
+ * PTS Functional Component manager
+ */
+extern pts_component_manager_t* pts_components;
+
+#endif /** LIBPTS_H_ @}*/
diff --git a/src/libpts/plugins/imc_attestation/Makefile.am b/src/libpts/plugins/imc_attestation/Makefile.am
new file mode 100644
index 000000000..9d78b935a
--- /dev/null
+++ b/src/libpts/plugins/imc_attestation/Makefile.am
@@ -0,0 +1,18 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libimcv -I$(top_srcdir)/src/libpts
+
+AM_CFLAGS = -rdynamic
+
+imcv_LTLIBRARIES = imc-attestation.la
+
+imc_attestation_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libpts/libpts.la
+
+imc_attestation_la_SOURCES = imc_attestation.c \
+ imc_attestation_state.h imc_attestation_state.c \
+ imc_attestation_process.h imc_attestation_process.c
+
+imc_attestation_la_LDFLAGS = -module -avoid-version
+
diff --git a/src/libpts/plugins/imc_attestation/Makefile.in b/src/libpts/plugins/imc_attestation/Makefile.in
new file mode 100644
index 000000000..583d2dfee
--- /dev/null
+++ b/src/libpts/plugins/imc_attestation/Makefile.in
@@ -0,0 +1,608 @@
+# 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/libpts/plugins/imc_attestation
+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)$(imcvdir)"
+LTLIBRARIES = $(imcv_LTLIBRARIES)
+imc_attestation_la_DEPENDENCIES = \
+ $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libpts/libpts.la
+am_imc_attestation_la_OBJECTS = imc_attestation.lo \
+ imc_attestation_state.lo imc_attestation_process.lo
+imc_attestation_la_OBJECTS = $(am_imc_attestation_la_OBJECTS)
+imc_attestation_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(imc_attestation_la_LDFLAGS) $(LDFLAGS) -o $@
+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 = $(imc_attestation_la_SOURCES)
+DIST_SOURCES = $(imc_attestation_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libtncif \
+ -I$(top_srcdir)/src/libimcv -I$(top_srcdir)/src/libpts
+
+AM_CFLAGS = -rdynamic
+imcv_LTLIBRARIES = imc-attestation.la
+imc_attestation_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libpts/libpts.la
+
+imc_attestation_la_SOURCES = imc_attestation.c \
+ imc_attestation_state.h imc_attestation_state.c \
+ imc_attestation_process.h imc_attestation_process.c
+
+imc_attestation_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/libpts/plugins/imc_attestation/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libpts/plugins/imc_attestation/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):
+install-imcvLTLIBRARIES: $(imcv_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(imcvdir)" || $(MKDIR_P) "$(DESTDIR)$(imcvdir)"
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || 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)$(imcvdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(imcvdir)"; \
+ }
+
+uninstall-imcvLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(imcvdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(imcvdir)/$$f"; \
+ done
+
+clean-imcvLTLIBRARIES:
+ -test -z "$(imcv_LTLIBRARIES)" || rm -f $(imcv_LTLIBRARIES)
+ @list='$(imcv_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
+imc-attestation.la: $(imc_attestation_la_OBJECTS) $(imc_attestation_la_DEPENDENCIES)
+ $(imc_attestation_la_LINK) -rpath $(imcvdir) $(imc_attestation_la_OBJECTS) $(imc_attestation_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imc_attestation.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imc_attestation_process.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imc_attestation_state.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)$(imcvdir)"; 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-imcvLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-imcvLTLIBRARIES
+
+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-imcvLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-imcvLTLIBRARIES clean-libtool 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-imcvLTLIBRARIES install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-imcvLTLIBRARIES
+
+
+# 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/libpts/plugins/imc_attestation/imc_attestation.c b/src/libpts/plugins/imc_attestation/imc_attestation.c
new file mode 100644
index 000000000..4f77ba093
--- /dev/null
+++ b/src/libpts/plugins/imc_attestation/imc_attestation.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "imc_attestation_state.h"
+#include "imc_attestation_process.h"
+
+#include <imc/imc_agent.h>
+#include <pa_tnc/pa_tnc_msg.h>
+#include <ietf/ietf_attr.h>
+#include <ietf/ietf_attr_pa_tnc_error.h>
+#include <ietf/ietf_attr_product_info.h>
+
+#include <libpts.h>
+
+#include <pts/pts_error.h>
+
+#include <tcg/tcg_pts_attr_proto_caps.h>
+#include <tcg/tcg_pts_attr_meas_algo.h>
+
+#include <tncif_pa_subtypes.h>
+
+#include <pen/pen.h>
+#include <debug.h>
+#include <utils/linked_list.h>
+
+/* IMC definitions */
+
+static const char imc_name[] = "Attestation";
+
+#define IMC_VENDOR_ID PEN_TCG
+#define IMC_SUBTYPE PA_SUBTYPE_TCG_PTS
+
+static imc_agent_t *imc_attestation;
+
+/**
+ * Supported PTS measurement algorithms
+ */
+static pts_meas_algorithms_t supported_algorithms = PTS_MEAS_ALGO_NONE;
+
+/**
+ * Supported PTS Diffie Hellman Groups
+ */
+static pts_dh_group_t supported_dh_groups = PTS_DH_GROUP_NONE;
+
+/**
+ * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
+ TNC_Version min_version,
+ TNC_Version max_version,
+ TNC_Version *actual_version)
+{
+ if (imc_attestation)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has already been initialized", imc_name);
+ return TNC_RESULT_ALREADY_INITIALIZED;
+ }
+ if (!pts_meas_algo_probe(&supported_algorithms) ||
+ !pts_dh_group_probe(&supported_dh_groups))
+ {
+ return TNC_RESULT_FATAL;
+ }
+ imc_attestation = imc_agent_create(imc_name, IMC_VENDOR_ID, IMC_SUBTYPE,
+ imc_id, actual_version);
+ if (!imc_attestation)
+ {
+ return TNC_RESULT_FATAL;
+ }
+
+ libpts_init();
+
+ if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
+ {
+ DBG1(DBG_IMC, "no common IF-IMC version");
+ return TNC_RESULT_NO_COMMON_VERSION;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.2 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_ConnectionState new_state)
+{
+ imc_state_t *state;
+
+ if (!imc_attestation)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ switch (new_state)
+ {
+ case TNC_CONNECTION_STATE_CREATE:
+ state = imc_attestation_state_create(connection_id);
+ return imc_attestation->create_state(imc_attestation, state);
+ case TNC_CONNECTION_STATE_DELETE:
+ return imc_attestation->delete_state(imc_attestation, connection_id);
+ case TNC_CONNECTION_STATE_HANDSHAKE:
+ case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
+ case TNC_CONNECTION_STATE_ACCESS_NONE:
+ default:
+ return imc_attestation->change_state(imc_attestation, connection_id,
+ new_state, NULL);
+ }
+}
+
+
+/**
+ * see section 3.8.3 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id)
+{
+ imc_state_t *state;
+ imc_attestation_state_t *attestation_state;
+ pts_t *pts;
+ char *platform_info;
+ TNC_Result result = TNC_RESULT_SUCCESS;
+
+ if (!imc_attestation)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+
+ /* get current IMC state */
+ if (!imc_attestation->get_state(imc_attestation, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+ attestation_state = (imc_attestation_state_t*)state;
+ pts = attestation_state->get_pts(attestation_state);
+
+ platform_info = pts->get_platform_info(pts);
+ if (platform_info)
+ {
+ pa_tnc_msg_t *pa_tnc_msg;
+ pa_tnc_attr_t *attr;
+
+ pa_tnc_msg = pa_tnc_msg_create();
+ attr = ietf_attr_product_info_create(0, 0, platform_info);
+ pa_tnc_msg->add_attribute(pa_tnc_msg, attr);
+ pa_tnc_msg->build(pa_tnc_msg);
+ result = imc_attestation->send_message(imc_attestation, connection_id,
+ FALSE, 0, TNC_IMVID_ANY,
+ pa_tnc_msg->get_encoding(pa_tnc_msg));
+ pa_tnc_msg->destroy(pa_tnc_msg);
+ }
+
+ return result;
+}
+
+static TNC_Result receive_message(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ chunk_t msg,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imv_id,
+ TNC_UInt32 dst_imc_id)
+{
+ pa_tnc_msg_t *pa_tnc_msg;
+ pa_tnc_attr_t *attr;
+ linked_list_t *attr_list;
+ imc_state_t *state;
+ imc_attestation_state_t *attestation_state;
+ enumerator_t *enumerator;
+ TNC_Result result;
+
+ if (!imc_attestation)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+
+ /* get current IMC state */
+ if (!imc_attestation->get_state(imc_attestation, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+ attestation_state = (imc_attestation_state_t*)state;
+
+ /* parse received PA-TNC message and automatically handle any errors */
+ result = imc_attestation->receive_message(imc_attestation, state, msg,
+ msg_vid, msg_subtype, src_imv_id, dst_imc_id, &pa_tnc_msg);
+
+ /* no parsed PA-TNC attributes available if an error occurred */
+ if (!pa_tnc_msg)
+ {
+ return result;
+ }
+
+ /* preprocess any IETF standard error attributes */
+ result = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg) ?
+ TNC_RESULT_FATAL : TNC_RESULT_SUCCESS;
+
+ attr_list = linked_list_create();
+
+ /* analyze PA-TNC attributes */
+ enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ if (attr->get_vendor_id(attr) == PEN_IETF &&
+ attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR)
+ {
+ ietf_attr_pa_tnc_error_t *error_attr;
+ pen_t error_vendor_id;
+ pa_tnc_error_code_t error_code;
+ chunk_t msg_info;
+
+ error_attr = (ietf_attr_pa_tnc_error_t*)attr;
+ error_vendor_id = error_attr->get_vendor_id(error_attr);
+
+ if (error_vendor_id == PEN_TCG)
+ {
+ error_code = error_attr->get_error_code(error_attr);
+ msg_info = error_attr->get_msg_info(error_attr);
+
+ DBG1(DBG_IMC, "received TCG-PTS error '%N'",
+ pts_error_code_names, error_code);
+ DBG1(DBG_IMC, "error information: %B", &msg_info);
+
+ result = TNC_RESULT_FATAL;
+ }
+ }
+ else if (attr->get_vendor_id(attr) == PEN_TCG)
+ {
+ if (!imc_attestation_process(attr, attr_list, attestation_state,
+ supported_algorithms, supported_dh_groups))
+ {
+ result = TNC_RESULT_FATAL;
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ pa_tnc_msg->destroy(pa_tnc_msg);
+
+ if (result == TNC_RESULT_SUCCESS && attr_list->get_count(attr_list))
+ {
+ pa_tnc_msg = pa_tnc_msg_create();
+
+ enumerator = attr_list->create_enumerator(attr_list);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ pa_tnc_msg->add_attribute(pa_tnc_msg, attr);
+ }
+ enumerator->destroy(enumerator);
+
+ pa_tnc_msg->build(pa_tnc_msg);
+ result = imc_attestation->send_message(imc_attestation, connection_id,
+ FALSE, 0, TNC_IMVID_ANY,
+ pa_tnc_msg->get_encoding(pa_tnc_msg));
+ pa_tnc_msg->destroy(pa_tnc_msg);
+ }
+
+ attr_list->destroy(attr_list);
+ return result;
+}
+
+/**
+ * see section 3.8.4 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type)
+{
+ TNC_VendorID msg_vid;
+ TNC_MessageSubtype msg_subtype;
+
+ msg_vid = msg_type >> 8;
+ msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+
+ return receive_message(imc_id, connection_id, 0, chunk_create(msg, msg_len),
+ msg_vid, msg_subtype, 0, TNC_IMCID_ANY);
+}
+
+/**
+ * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imv_id,
+ TNC_UInt32 dst_imc_id)
+{
+ return receive_message(imc_id, connection_id, msg_flags,
+ chunk_create(msg, msg_len), msg_vid, msg_subtype,
+ src_imv_id, dst_imc_id);
+}
+
+/**
+ * see section 3.8.7 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_BatchEnding(TNC_IMCID imc_id,
+ TNC_ConnectionID connection_id)
+{
+ if (!imc_attestation)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.8 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
+{
+ if (!imc_attestation)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+
+ libpts_deinit();
+
+ imc_attestation->destroy(imc_attestation);
+ imc_attestation = NULL;
+
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.3
+ */
+TNC_Result TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id,
+ TNC_TNCC_BindFunctionPointer bind_function)
+{
+ if (!imc_attestation)
+ {
+ DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return imc_attestation->bind_functions(imc_attestation, bind_function);
+}
diff --git a/src/libpts/plugins/imc_attestation/imc_attestation_process.c b/src/libpts/plugins/imc_attestation/imc_attestation_process.c
new file mode 100644
index 000000000..b70c05370
--- /dev/null
+++ b/src/libpts/plugins/imc_attestation/imc_attestation_process.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+/* for isdigit */
+#include <ctype.h>
+
+#include "imc_attestation_process.h"
+
+#include <ietf/ietf_attr_pa_tnc_error.h>
+
+#include <libpts.h>
+#include <pts/pts.h>
+
+#include <tcg/tcg_pts_attr_proto_caps.h>
+#include <tcg/tcg_pts_attr_meas_algo.h>
+#include <tcg/tcg_pts_attr_dh_nonce_params_req.h>
+#include <tcg/tcg_pts_attr_dh_nonce_params_resp.h>
+#include <tcg/tcg_pts_attr_dh_nonce_finish.h>
+#include <tcg/tcg_pts_attr_get_tpm_version_info.h>
+#include <tcg/tcg_pts_attr_tpm_version_info.h>
+#include <tcg/tcg_pts_attr_get_aik.h>
+#include <tcg/tcg_pts_attr_aik.h>
+#include <tcg/tcg_pts_attr_req_func_comp_evid.h>
+#include <tcg/tcg_pts_attr_gen_attest_evid.h>
+#include <tcg/tcg_pts_attr_simple_comp_evid.h>
+#include <tcg/tcg_pts_attr_simple_evid_final.h>
+#include <tcg/tcg_pts_attr_req_file_meas.h>
+#include <tcg/tcg_pts_attr_file_meas.h>
+#include <tcg/tcg_pts_attr_req_file_meta.h>
+#include <tcg/tcg_pts_attr_unix_file_meta.h>
+
+#include <debug.h>
+#include <utils/lexparser.h>
+
+#define DEFAULT_NONCE_LEN 20
+
+bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
+ imc_attestation_state_t *attestation_state,
+ pts_meas_algorithms_t supported_algorithms,
+ pts_dh_group_t supported_dh_groups)
+{
+ chunk_t attr_info;
+ pts_t *pts;
+ pts_error_code_t pts_error;
+ bool valid_path;
+
+ pts = attestation_state->get_pts(attestation_state);
+ switch (attr->get_type(attr))
+ {
+ case TCG_PTS_REQ_PROTO_CAPS:
+ {
+ tcg_pts_attr_proto_caps_t *attr_cast;
+ pts_proto_caps_flag_t imc_caps, imv_caps;
+
+ attr_cast = (tcg_pts_attr_proto_caps_t*)attr;
+ imv_caps = attr_cast->get_flags(attr_cast);
+ imc_caps = pts->get_proto_caps(pts);
+ pts->set_proto_caps(pts, imc_caps & imv_caps);
+
+ /* Send PTS Protocol Capabilities attribute */
+ attr = tcg_pts_attr_proto_caps_create(imc_caps & imv_caps, FALSE);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ case TCG_PTS_MEAS_ALGO:
+ {
+ tcg_pts_attr_meas_algo_t *attr_cast;
+ pts_meas_algorithms_t offered_algorithms, selected_algorithm;
+
+ attr_cast = (tcg_pts_attr_meas_algo_t*)attr;
+ offered_algorithms = attr_cast->get_algorithms(attr_cast);
+ selected_algorithm = pts_meas_algo_select(supported_algorithms,
+ offered_algorithms);
+ if (selected_algorithm == PTS_MEAS_ALGO_NONE)
+ {
+ attr = pts_hash_alg_error_create(supported_algorithms);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+
+ /* Send Measurement Algorithm Selection attribute */
+ pts->set_meas_algorithm(pts, selected_algorithm);
+ attr = tcg_pts_attr_meas_algo_create(selected_algorithm, TRUE);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ case TCG_PTS_DH_NONCE_PARAMS_REQ:
+ {
+ tcg_pts_attr_dh_nonce_params_req_t *attr_cast;
+ pts_dh_group_t offered_dh_groups, selected_dh_group;
+ chunk_t responder_value, responder_nonce;
+ int nonce_len, min_nonce_len;
+
+ nonce_len = lib->settings->get_int(lib->settings,
+ "libimcv.plugins.imc-attestation.nonce_len",
+ DEFAULT_NONCE_LEN);
+
+ attr_cast = (tcg_pts_attr_dh_nonce_params_req_t*)attr;
+ min_nonce_len = attr_cast->get_min_nonce_len(attr_cast);
+ if (nonce_len < PTS_MIN_NONCE_LEN ||
+ (min_nonce_len > 0 && nonce_len < min_nonce_len))
+ {
+ attr = pts_dh_nonce_error_create(nonce_len, PTS_MAX_NONCE_LEN);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+
+ offered_dh_groups = attr_cast->get_dh_groups(attr_cast);
+ selected_dh_group = pts_dh_group_select(supported_dh_groups,
+ offered_dh_groups);
+ if (selected_dh_group == PTS_DH_GROUP_NONE)
+ {
+ attr = pts_dh_group_error_create(supported_dh_groups);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+
+ /* Create own DH factor and nonce */
+ if (!pts->create_dh_nonce(pts, selected_dh_group, nonce_len))
+ {
+ return FALSE;
+ }
+ pts->get_my_public_value(pts, &responder_value, &responder_nonce);
+
+ /* Send DH Nonce Parameters Response attribute */
+ attr = tcg_pts_attr_dh_nonce_params_resp_create(selected_dh_group,
+ supported_algorithms, responder_nonce, responder_value);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ case TCG_PTS_DH_NONCE_FINISH:
+ {
+ tcg_pts_attr_dh_nonce_finish_t *attr_cast;
+ pts_meas_algorithms_t selected_algorithm;
+ chunk_t initiator_nonce, initiator_value;
+ int nonce_len;
+
+ attr_cast = (tcg_pts_attr_dh_nonce_finish_t*)attr;
+ selected_algorithm = attr_cast->get_hash_algo(attr_cast);
+ if (!(selected_algorithm & supported_algorithms))
+ {
+ DBG1(DBG_IMC, "PTS-IMV selected unsupported DH hash algorithm");
+ return FALSE;
+ }
+ pts->set_dh_hash_algorithm(pts, selected_algorithm);
+
+ initiator_value = attr_cast->get_initiator_value(attr_cast);
+ initiator_nonce = attr_cast->get_initiator_nonce(attr_cast);
+
+ nonce_len = lib->settings->get_int(lib->settings,
+ "libimcv.plugins.imc-attestation.nonce_len",
+ DEFAULT_NONCE_LEN);
+ if (nonce_len != initiator_nonce.len)
+ {
+ DBG1(DBG_IMC, "initiator and responder DH nonces "
+ "have differing lengths");
+ return FALSE;
+ }
+
+ pts->set_peer_public_value(pts, initiator_value, initiator_nonce);
+ if (!pts->calculate_secret(pts))
+ {
+ return FALSE;
+ }
+ break;
+ }
+ case TCG_PTS_GET_TPM_VERSION_INFO:
+ {
+ chunk_t tpm_version_info, attr_info;
+
+ if (!pts->get_tpm_version_info(pts, &tpm_version_info))
+ {
+ attr_info = attr->get_value(attr);
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+ TCG_PTS_TPM_VERS_NOT_SUPPORTED, attr_info);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+
+ /* Send TPM Version Info attribute */
+ attr = tcg_pts_attr_tpm_version_info_create(tpm_version_info);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ case TCG_PTS_GET_AIK:
+ {
+ certificate_t *aik;
+
+ aik = pts->get_aik(pts);
+ if (!aik)
+ {
+ DBG1(DBG_IMC, "no AIK certificate or public key available");
+ break;
+ }
+
+ /* Send AIK attribute */
+ attr = tcg_pts_attr_aik_create(aik);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ case TCG_PTS_REQ_FILE_MEAS:
+ {
+ tcg_pts_attr_req_file_meas_t *attr_cast;
+ char *pathname;
+ u_int16_t request_id;
+ bool is_directory;
+ u_int32_t delimiter;
+ pts_file_meas_t *measurements;
+
+ attr_info = attr->get_value(attr);
+ attr_cast = (tcg_pts_attr_req_file_meas_t*)attr;
+ is_directory = attr_cast->get_directory_flag(attr_cast);
+ request_id = attr_cast->get_request_id(attr_cast);
+ delimiter = attr_cast->get_delimiter(attr_cast);
+ pathname = attr_cast->get_pathname(attr_cast);
+ valid_path = pts->is_path_valid(pts, pathname, &pts_error);
+
+ if (valid_path && pts_error)
+ {
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+ pts_error, attr_info);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ else if (!valid_path)
+ {
+ break;
+ }
+
+ if (delimiter != SOLIDUS_UTF && delimiter != REVERSE_SOLIDUS_UTF)
+ {
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+ TCG_PTS_INVALID_DELIMITER, attr_info);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+
+ /* Do PTS File Measurements and send them to PTS-IMV */
+ DBG2(DBG_IMC, "measurement request %d for %s '%s'",
+ request_id, is_directory ? "directory" : "file",
+ pathname);
+ measurements = pts->do_measurements(pts, request_id,
+ pathname, is_directory);
+ if (!measurements)
+ {
+ /* TODO handle error codes from measurements */
+ return FALSE;
+ }
+ attr = tcg_pts_attr_file_meas_create(measurements);
+ attr->set_noskip_flag(attr, TRUE);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ case TCG_PTS_REQ_FILE_META:
+ {
+ tcg_pts_attr_req_file_meta_t *attr_cast;
+ char *pathname;
+ bool is_directory;
+ u_int8_t delimiter;
+ pts_file_meta_t *metadata;
+
+ attr_info = attr->get_value(attr);
+ attr_cast = (tcg_pts_attr_req_file_meta_t*)attr;
+ is_directory = attr_cast->get_directory_flag(attr_cast);
+ delimiter = attr_cast->get_delimiter(attr_cast);
+ pathname = attr_cast->get_pathname(attr_cast);
+
+ valid_path = pts->is_path_valid(pts, pathname, &pts_error);
+ if (valid_path && pts_error)
+ {
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+ pts_error, attr_info);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ else if (!valid_path)
+ {
+ break;
+ }
+ if (delimiter != SOLIDUS_UTF && delimiter != REVERSE_SOLIDUS_UTF)
+ {
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+ TCG_PTS_INVALID_DELIMITER, attr_info);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ /* Get File Metadata and send them to PTS-IMV */
+ DBG2(DBG_IMC, "metadata request for %s '%s'",
+ is_directory ? "directory" : "file",
+ pathname);
+ metadata = pts->get_metadata(pts, pathname, is_directory);
+
+ if (!metadata)
+ {
+ /* TODO handle error codes from measurements */
+ return FALSE;
+ }
+ attr = tcg_pts_attr_unix_file_meta_create(metadata);
+ attr->set_noskip_flag(attr, TRUE);
+ attr_list->insert_last(attr_list, attr);
+
+ break;
+ }
+ case TCG_PTS_REQ_FUNC_COMP_EVID:
+ {
+ tcg_pts_attr_req_func_comp_evid_t *attr_cast;
+ pts_proto_caps_flag_t negotiated_caps;
+ pts_comp_func_name_t *name;
+ pts_comp_evidence_t *evid;
+ pts_component_t *comp;
+ u_int32_t depth;
+ u_int8_t flags;
+ status_t status;
+ enumerator_t *e;
+
+ attr_info = attr->get_value(attr);
+ attr_cast = (tcg_pts_attr_req_func_comp_evid_t*)attr;
+
+ DBG1(DBG_IMC, "evidence requested for %d functional components",
+ attr_cast->get_count(attr_cast));
+
+ e = attr_cast->create_enumerator(attr_cast);
+ while (e->enumerate(e, &flags, &depth, &name))
+ {
+ name->log(name, "* ");
+ negotiated_caps = pts->get_proto_caps(pts);
+
+ if (flags & PTS_REQ_FUNC_COMP_EVID_TTC)
+ {
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+ TCG_PTS_UNABLE_DET_TTC, attr_info);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ if (flags & PTS_REQ_FUNC_COMP_EVID_VER &&
+ !(negotiated_caps & PTS_PROTO_CAPS_V))
+ {
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+ TCG_PTS_UNABLE_LOCAL_VAL, attr_info);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ if (flags & PTS_REQ_FUNC_COMP_EVID_CURR &&
+ !(negotiated_caps & PTS_PROTO_CAPS_C))
+ {
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+ TCG_PTS_UNABLE_CUR_EVID, attr_info);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ if (flags & PTS_REQ_FUNC_COMP_EVID_PCR &&
+ !(negotiated_caps & PTS_PROTO_CAPS_T))
+ {
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
+ TCG_PTS_UNABLE_DET_PCR, attr_info);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ if (depth > 0)
+ {
+ DBG1(DBG_IMC, "the Attestation IMC currently does not "
+ "support sub component measurements");
+ return FALSE;
+ }
+ comp = pts_components->create(pts_components, name, depth, NULL);
+ if (!comp)
+ {
+ DBG2(DBG_IMC, " not registered: no evidence provided");
+ continue;
+ }
+
+ /* do the component evidence measurement[s] */
+ do
+ {
+ status = comp->measure(comp, pts, &evid);
+ if (status == FAILED)
+ {
+ break;
+ }
+ attestation_state->add_evidence(attestation_state, evid);
+ }
+ while (status == NEED_MORE);
+ comp->destroy(comp);
+ }
+ e->destroy(e);
+ break;
+ }
+ case TCG_PTS_GEN_ATTEST_EVID:
+ {
+ pts_simple_evid_final_flag_t flags;
+ pts_meas_algorithms_t comp_hash_algorithm;
+ pts_comp_evidence_t *evid;
+ chunk_t pcr_composite, quote_sig;
+ bool use_quote2;
+
+ /* Send buffered Simple Component Evidences */
+ while (attestation_state->next_evidence(attestation_state, &evid))
+ {
+ pts->select_pcr(pts, evid->get_extended_pcr(evid));
+
+ /* Send Simple Component Evidence */
+ attr = tcg_pts_attr_simple_comp_evid_create(evid);
+ attr_list->insert_last(attr_list, attr);
+ }
+
+ use_quote2 = lib->settings->get_bool(lib->settings,
+ "libimcv.plugins.imc-attestation.use_quote2", TRUE);
+ if (!pts->quote_tpm(pts, use_quote2, &pcr_composite, &quote_sig))
+ {
+ DBG1(DBG_IMC, "error occurred during TPM quote operation");
+ return FALSE;
+ }
+
+ /* Send Simple Evidence Final attribute */
+ flags = use_quote2 ? PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2 :
+ PTS_SIMPLE_EVID_FINAL_QUOTE_INFO;
+ comp_hash_algorithm = PTS_MEAS_ALGO_SHA1;
+
+ attr = tcg_pts_attr_simple_evid_final_create(flags,
+ comp_hash_algorithm, pcr_composite, quote_sig);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ /* TODO: Not implemented yet */
+ case TCG_PTS_REQ_INTEG_MEAS_LOG:
+ /* Attributes using XML */
+ case TCG_PTS_REQ_TEMPL_REF_MANI_SET_META:
+ case TCG_PTS_UPDATE_TEMPL_REF_MANI:
+ /* On Windows only*/
+ case TCG_PTS_REQ_REGISTRY_VALUE:
+ /* Received on IMV side only*/
+ case TCG_PTS_PROTO_CAPS:
+ case TCG_PTS_DH_NONCE_PARAMS_RESP:
+ case TCG_PTS_MEAS_ALGO_SELECTION:
+ case TCG_PTS_TPM_VERSION_INFO:
+ case TCG_PTS_TEMPL_REF_MANI_SET_META:
+ case TCG_PTS_AIK:
+ case TCG_PTS_SIMPLE_COMP_EVID:
+ case TCG_PTS_SIMPLE_EVID_FINAL:
+ case TCG_PTS_VERIFICATION_RESULT:
+ case TCG_PTS_INTEG_REPORT:
+ case TCG_PTS_UNIX_FILE_META:
+ case TCG_PTS_FILE_MEAS:
+ case TCG_PTS_INTEG_MEAS_LOG:
+ default:
+ DBG1(DBG_IMC, "received unsupported attribute '%N'",
+ tcg_attr_names, attr->get_type(attr));
+ break;
+ }
+ return TRUE;
+}
diff --git a/src/libpts/plugins/imc_attestation/imc_attestation_process.h b/src/libpts/plugins/imc_attestation/imc_attestation_process.h
new file mode 100644
index 000000000..b6dca1f56
--- /dev/null
+++ b/src/libpts/plugins/imc_attestation/imc_attestation_process.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 imc_attestation_process_t imc_attestation_process
+ * @{ @ingroup imc_attestation_process
+ */
+
+#ifndef IMC_ATTESTATION_PROCESS_H_
+#define IMC_ATTESTATION_PROCESS_H_
+
+#include "imc_attestation_state.h"
+
+#include <library.h>
+
+#include <pa_tnc/pa_tnc_attr.h>
+
+#include <pts/pts_dh_group.h>
+#include <pts/pts_meas_algo.h>
+
+/**
+ * Process a TCG PTS attribute
+ *
+ * @param attr PA-TNC attribute to be processed
+ * @param attr_list list with PA-TNC error attributes
+ * @param attestation_state attestation state of a given connection
+ * @param supported_algorithms supported PTS measurement algorithms
+ * @param supported_dh_groups supported DH groups
+ * @return TRUE if successful
+ */
+bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
+ imc_attestation_state_t *attestation_state,
+ pts_meas_algorithms_t supported_algorithms,
+ pts_dh_group_t supported_dh_groups);
+
+#endif /** IMC_ATTESTATION_PROCESS_H_ @}*/
diff --git a/src/libpts/plugins/imc_attestation/imc_attestation_state.c b/src/libpts/plugins/imc_attestation/imc_attestation_state.c
new file mode 100644
index 000000000..72a55f60e
--- /dev/null
+++ b/src/libpts/plugins/imc_attestation/imc_attestation_state.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "imc_attestation_state.h"
+
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_imc_attestation_state_t private_imc_attestation_state_t;
+
+/**
+ * Private data of an imc_attestation_state_t object.
+ */
+struct private_imc_attestation_state_t {
+
+ /**
+ * Public members of imc_attestation_state_t
+ */
+ imc_attestation_state_t public;
+
+ /**
+ * TNCCS connection ID
+ */
+ TNC_ConnectionID connection_id;
+
+ /**
+ * TNCCS connection state
+ */
+ TNC_ConnectionState state;
+
+ /**
+ * Does the TNCCS connection support long message types?
+ */
+ bool has_long;
+
+ /**
+ * Does the TNCCS connection support exclusive delivery?
+ */
+ bool has_excl;
+
+ /**
+ * PTS object
+ */
+ pts_t *pts;
+
+ /**
+ * PTS Component Evidence list
+ */
+ linked_list_t *list;
+
+};
+
+METHOD(imc_state_t, get_connection_id, TNC_ConnectionID,
+ private_imc_attestation_state_t *this)
+{
+ return this->connection_id;
+}
+
+METHOD(imc_state_t, has_long, bool,
+ private_imc_attestation_state_t *this)
+{
+ return this->has_long;
+}
+
+METHOD(imc_state_t, has_excl, bool,
+ private_imc_attestation_state_t *this)
+{
+ return this->has_excl;
+}
+
+METHOD(imc_state_t, set_flags, void,
+ private_imc_attestation_state_t *this, bool has_long, bool has_excl)
+{
+ this->has_long = has_long;
+ this->has_excl = has_excl;
+}
+
+METHOD(imc_state_t, change_state, void,
+ private_imc_attestation_state_t *this, TNC_ConnectionState new_state)
+{
+ this->state = new_state;
+}
+
+
+METHOD(imc_state_t, destroy, void,
+ private_imc_attestation_state_t *this)
+{
+ this->pts->destroy(this->pts);
+ this->list->destroy_offset(this->list, offsetof(pts_comp_evidence_t, destroy));
+ free(this);
+}
+
+METHOD(imc_attestation_state_t, get_pts, pts_t*,
+ private_imc_attestation_state_t *this)
+{
+ return this->pts;
+}
+
+METHOD(imc_attestation_state_t, add_evidence, void,
+ private_imc_attestation_state_t *this, pts_comp_evidence_t *evidence)
+{
+ this->list->insert_last(this->list, evidence);
+}
+
+METHOD(imc_attestation_state_t, next_evidence, bool,
+ private_imc_attestation_state_t *this, pts_comp_evidence_t **evid)
+{
+ return this->list->remove_first(this->list, (void**)evid) == SUCCESS;
+}
+
+/**
+ * Described in header.
+ */
+imc_state_t *imc_attestation_state_create(TNC_ConnectionID connection_id)
+{
+ private_imc_attestation_state_t *this;
+ char *platform_info;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .get_connection_id = _get_connection_id,
+ .has_long = _has_long,
+ .has_excl = _has_excl,
+ .set_flags = _set_flags,
+ .change_state = _change_state,
+ .destroy = _destroy,
+ },
+ .get_pts = _get_pts,
+ .add_evidence = _add_evidence,
+ .next_evidence = _next_evidence,
+ },
+ .connection_id = connection_id,
+ .state = TNC_CONNECTION_STATE_CREATE,
+ .pts = pts_create(TRUE),
+ .list = linked_list_create(),
+ );
+
+ platform_info = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.platform_info", NULL);
+ if (platform_info)
+ {
+ this->pts->set_platform_info(this->pts, platform_info);
+ }
+
+ return &this->public.interface;
+}
+
+
diff --git a/src/libpts/plugins/imc_attestation/imc_attestation_state.h b/src/libpts/plugins/imc_attestation/imc_attestation_state.h
new file mode 100644
index 000000000..22b0bba23
--- /dev/null
+++ b/src/libpts/plugins/imc_attestation/imc_attestation_state.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 imc_attestation_state_t imc_attestation_state
+ * @{ @ingroup imc_attestation_state
+ */
+
+#ifndef IMC_ATTESTATION_STATE_H_
+#define IMC_ATTESTATION_STATE_H_
+
+#include <imc/imc_state.h>
+#include <pts/pts.h>
+#include <pts/components/pts_comp_evidence.h>
+#include <library.h>
+
+typedef struct imc_attestation_state_t imc_attestation_state_t;
+
+/**
+ * Internal state of an imc_attestation_t connection instance
+ */
+struct imc_attestation_state_t {
+
+ /**
+ * imc_state_t interface
+ */
+ imc_state_t interface;
+
+ /**
+ * Get the PTS object
+ *
+ * @return PTS object
+ */
+ pts_t* (*get_pts)(imc_attestation_state_t *this);
+
+ /**
+ * Add an entry to the Component Evidence list
+ *
+ * @param entry Component Evidence entry
+ */
+ void (*add_evidence)(imc_attestation_state_t *this, pts_comp_evidence_t *entry);
+
+ /**
+ * Removes next Component Evidence entry from list and returns it
+ *
+ * @param evid Next Component Evidence entry
+ * @return TRUE if next entry is available
+ */
+ bool (*next_evidence)(imc_attestation_state_t *this, pts_comp_evidence_t** evid);
+
+};
+
+/**
+ * Create an imc_attestation_state_t instance
+ *
+ * @param id connection ID
+ */
+imc_state_t* imc_attestation_state_create(TNC_ConnectionID id);
+
+#endif /** IMC_ATTESTATION_STATE_H_ @}*/
diff --git a/src/libpts/plugins/imv_attestation/Makefile.am b/src/libpts/plugins/imv_attestation/Makefile.am
new file mode 100644
index 000000000..a550a3552
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/Makefile.am
@@ -0,0 +1,33 @@
+
+INCLUDES = \
+ -I$(top_srcdir)/src/libstrongswan \
+ -I$(top_srcdir)/src/libtncif \
+ -I$(top_srcdir)/src/libimcv \
+ -I$(top_srcdir)/src/libpts
+
+AM_CFLAGS = -rdynamic -DPLUGINS=\""${attest_plugins}\""
+
+imcv_LTLIBRARIES = imv-attestation.la
+
+imv_attestation_la_LIBADD = \
+ $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libpts/libpts.la
+
+imv_attestation_la_SOURCES = imv_attestation.c \
+ imv_attestation_state.h imv_attestation_state.c \
+ imv_attestation_process.h imv_attestation_process.c \
+ imv_attestation_build.h imv_attestation_build.c
+
+imv_attestation_la_LDFLAGS = -module -avoid-version
+
+ipsec_PROGRAMS = attest
+attest_SOURCES = attest.c \
+ attest_usage.h attest_usage.c \
+ attest_db.h attest_db.c \
+ tables.sql data.sql
+attest_LDADD = \
+ $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libpts/libpts.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+attest.o : $(top_builddir)/config.status
diff --git a/src/libpts/plugins/imv_attestation/Makefile.in b/src/libpts/plugins/imv_attestation/Makefile.in
new file mode 100644
index 000000000..989a173b5
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/Makefile.in
@@ -0,0 +1,686 @@
+# 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@
+ipsec_PROGRAMS = attest$(EXEEXT)
+subdir = src/libpts/plugins/imv_attestation
+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)$(imcvdir)" "$(DESTDIR)$(ipsecdir)"
+LTLIBRARIES = $(imcv_LTLIBRARIES)
+imv_attestation_la_DEPENDENCIES = \
+ $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libpts/libpts.la
+am_imv_attestation_la_OBJECTS = imv_attestation.lo \
+ imv_attestation_state.lo imv_attestation_process.lo \
+ imv_attestation_build.lo
+imv_attestation_la_OBJECTS = $(am_imv_attestation_la_OBJECTS)
+imv_attestation_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(imv_attestation_la_LDFLAGS) $(LDFLAGS) -o $@
+PROGRAMS = $(ipsec_PROGRAMS)
+am_attest_OBJECTS = attest.$(OBJEXT) attest_usage.$(OBJEXT) \
+ attest_db.$(OBJEXT)
+attest_OBJECTS = $(am_attest_OBJECTS)
+attest_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libpts/libpts.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+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 = $(imv_attestation_la_SOURCES) $(attest_SOURCES)
+DIST_SOURCES = $(imv_attestation_la_SOURCES) $(attest_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libtncif \
+ -I$(top_srcdir)/src/libimcv \
+ -I$(top_srcdir)/src/libpts
+
+AM_CFLAGS = -rdynamic -DPLUGINS=\""${attest_plugins}\""
+imcv_LTLIBRARIES = imv-attestation.la
+imv_attestation_la_LIBADD = \
+ $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libpts/libpts.la
+
+imv_attestation_la_SOURCES = imv_attestation.c \
+ imv_attestation_state.h imv_attestation_state.c \
+ imv_attestation_process.h imv_attestation_process.c \
+ imv_attestation_build.h imv_attestation_build.c
+
+imv_attestation_la_LDFLAGS = -module -avoid-version
+attest_SOURCES = attest.c \
+ attest_usage.h attest_usage.c \
+ attest_db.h attest_db.c \
+ tables.sql data.sql
+
+attest_LDADD = \
+ $(top_builddir)/src/libimcv/libimcv.la \
+ $(top_builddir)/src/libpts/libpts.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libpts/plugins/imv_attestation/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libpts/plugins/imv_attestation/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):
+install-imcvLTLIBRARIES: $(imcv_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(imcvdir)" || $(MKDIR_P) "$(DESTDIR)$(imcvdir)"
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || 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)$(imcvdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(imcvdir)"; \
+ }
+
+uninstall-imcvLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(imcv_LTLIBRARIES)'; test -n "$(imcvdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(imcvdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(imcvdir)/$$f"; \
+ done
+
+clean-imcvLTLIBRARIES:
+ -test -z "$(imcv_LTLIBRARIES)" || rm -f $(imcv_LTLIBRARIES)
+ @list='$(imcv_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
+imv-attestation.la: $(imv_attestation_la_OBJECTS) $(imv_attestation_la_DEPENDENCIES)
+ $(imv_attestation_la_LINK) -rpath $(imcvdir) $(imv_attestation_la_OBJECTS) $(imv_attestation_la_LIBADD) $(LIBS)
+install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipsecdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsecdir)"
+ @list='$(ipsec_PROGRAMS)'; test -n "$(ipsecdir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(ipsecdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(ipsecdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-ipsecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipsec_PROGRAMS)'; test -n "$(ipsecdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(ipsecdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(ipsecdir)" && rm -f $$files
+
+clean-ipsecPROGRAMS:
+ @list='$(ipsec_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+attest$(EXEEXT): $(attest_OBJECTS) $(attest_DEPENDENCIES)
+ @rm -f attest$(EXEEXT)
+ $(LINK) $(attest_OBJECTS) $(attest_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attest_db.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attest_usage.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_attestation.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_attestation_build.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_attestation_process.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_attestation_state.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) $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(imcvdir)" "$(DESTDIR)$(ipsecdir)"; 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-imcvLTLIBRARIES clean-ipsecPROGRAMS \
+ clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-imcvLTLIBRARIES install-ipsecPROGRAMS
+
+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-imcvLTLIBRARIES uninstall-ipsecPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-imcvLTLIBRARIES clean-ipsecPROGRAMS clean-libtool 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-imcvLTLIBRARIES install-info install-info-am \
+ install-ipsecPROGRAMS install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-imcvLTLIBRARIES \
+ uninstall-ipsecPROGRAMS
+
+attest.o : $(top_builddir)/config.status
+
+# 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/libpts/plugins/imv_attestation/attest.c b/src/libpts/plugins/imv_attestation/attest.c
new file mode 100644
index 000000000..9200820e8
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/attest.c
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define _GNU_SOURCE
+#include <getopt.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <syslog.h>
+
+#include <library.h>
+#include <debug.h>
+
+#include <imcv.h>
+#include <libpts.h>
+#include <pts/pts_meas_algo.h>
+
+#include "attest_db.h"
+#include "attest_usage.h"
+
+/**
+ * global debug output variables
+ */
+static int debug_level = 2;
+static bool stderr_quiet = TRUE;
+
+/**
+ * attest dbg function
+ */
+static void attest_dbg(debug_t group, level_t level, char *fmt, ...)
+{
+ int priority = LOG_INFO;
+ char buffer[8192];
+ char *current = buffer, *next;
+ va_list args;
+
+ if (level <= debug_level)
+ {
+ if (!stderr_quiet)
+ {
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+ va_end(args);
+ }
+
+ /* write in memory buffer first */
+ va_start(args, fmt);
+ vsnprintf(buffer, sizeof(buffer), fmt, args);
+ va_end(args);
+
+ /* do a syslog with every line */
+ while (current)
+ {
+ next = strchr(current, '\n');
+ if (next)
+ {
+ *(next++) = '\0';
+ }
+ syslog(priority, "%s\n", current);
+ current = next;
+ }
+ }
+}
+
+/**
+ * global attestation database object
+ */
+attest_db_t *attest;
+
+/**
+ * atexit handler to close db on shutdown
+ */
+static void cleanup(void)
+{
+ attest->destroy(attest);
+ libpts_deinit();
+ libimcv_deinit();
+ closelog();
+}
+
+static void do_args(int argc, char *argv[])
+{
+ enum {
+ OP_UNDEF,
+ OP_USAGE,
+ OP_KEYS,
+ OP_COMPONENTS,
+ OP_FILES,
+ OP_HASHES,
+ OP_MEASUREMENTS,
+ OP_PRODUCTS,
+ OP_ADD,
+ OP_DEL,
+ } op = OP_UNDEF;
+
+ /* reinit getopt state */
+ optind = 0;
+
+ while (TRUE)
+ {
+ int c;
+
+ struct option long_opts[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "components", no_argument, NULL, 'c' },
+ { "files", no_argument, NULL, 'f' },
+ { "keys", no_argument, NULL, 'k' },
+ { "products", no_argument, NULL, 'p' },
+ { "hashes", no_argument, NULL, 'H' },
+ { "measurements", no_argument, NULL, 'm' },
+ { "add", no_argument, NULL, 'a' },
+ { "delete", no_argument, NULL, 'd' },
+ { "del", no_argument, NULL, 'd' },
+ { "aik", required_argument, NULL, 'A' },
+ { "component", required_argument, NULL, 'C' },
+ { "comp", required_argument, NULL, 'C' },
+ { "directory", required_argument, NULL, 'D' },
+ { "dir", required_argument, NULL, 'D' },
+ { "file", required_argument, NULL, 'F' },
+ { "key", required_argument, NULL, 'K' },
+ { "owner", required_argument, NULL, 'O' },
+ { "product", required_argument, NULL, 'P' },
+ { "sha1", no_argument, NULL, '1' },
+ { "sha256", no_argument, NULL, '2' },
+ { "sha384", no_argument, NULL, '3' },
+ { "did", required_argument, NULL, '4' },
+ { "fid", required_argument, NULL, '5' },
+ { "pid", required_argument, NULL, '6' },
+ { "cid", required_argument, NULL, '7' },
+ { "kid", required_argument, NULL, '8' },
+ { 0,0,0,0 }
+ };
+
+ c = getopt_long(argc, argv, "", long_opts, NULL);
+ switch (c)
+ {
+ case EOF:
+ break;
+ case 'h':
+ op = OP_USAGE;
+ break;
+ case 'c':
+ op = OP_COMPONENTS;
+ continue;
+ case 'f':
+ op = OP_FILES;
+ continue;
+ case 'k':
+ op = OP_KEYS;
+ continue;
+ case 'p':
+ op = OP_PRODUCTS;
+ continue;
+ case 'H':
+ op = OP_HASHES;
+ continue;
+ case 'm':
+ op = OP_MEASUREMENTS;
+ continue;
+ case 'a':
+ op = OP_ADD;
+ continue;
+ case 'd':
+ op = OP_DEL;
+ continue;
+ case 'A':
+ {
+ certificate_t *aik_cert;
+ public_key_t *aik_key;
+ chunk_t aik;
+
+ aik_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE,
+ CERT_X509, BUILD_FROM_FILE, optarg, BUILD_END);
+ if (!aik_cert)
+ {
+ printf("AIK certificate '%s' could not be loaded\n", optarg);
+ exit(EXIT_FAILURE);
+ }
+ aik_key = aik_cert->get_public_key(aik_cert);
+ aik_cert->destroy(aik_cert);
+
+ if (!aik_key)
+ {
+ printf("AIK public key could not be retrieved\n");
+ exit(EXIT_FAILURE);
+ }
+ if (!aik_key->get_fingerprint(aik_key, KEYID_PUBKEY_INFO_SHA1,
+ &aik))
+ {
+ printf("AIK fingerprint could not be computed\n");
+ aik_key->destroy(aik_key);
+ exit(EXIT_FAILURE);
+ }
+ aik = chunk_clone(aik);
+ aik_key->destroy(aik_key);
+
+ if (!attest->set_key(attest, aik, op == OP_ADD))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ }
+ case 'C':
+ if (!attest->set_component(attest, optarg, op == OP_ADD))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ case 'D':
+ if (!attest->set_directory(attest, optarg, op == OP_ADD))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ case 'F':
+ if (!attest->set_file(attest, optarg, op == OP_ADD))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ case 'K':
+ {
+ chunk_t aik;
+
+ aik = chunk_from_hex(chunk_create(optarg, strlen(optarg)), NULL);
+ if (!attest->set_key(attest, aik, op == OP_ADD))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ }
+ case 'O':
+ attest->set_owner(attest, optarg);
+ continue;
+ case 'P':
+ if (!attest->set_product(attest, optarg, op == OP_ADD))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ case '1':
+ attest->set_algo(attest, PTS_MEAS_ALGO_SHA1);
+ continue;
+ case '2':
+ attest->set_algo(attest, PTS_MEAS_ALGO_SHA256);
+ continue;
+ case '3':
+ attest->set_algo(attest, PTS_MEAS_ALGO_SHA384);
+ continue;
+ case '4':
+ if (!attest->set_did(attest, atoi(optarg)))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ case '5':
+ if (!attest->set_fid(attest, atoi(optarg)))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ case '6':
+ if (!attest->set_pid(attest, atoi(optarg)))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ case '7':
+ if (!attest->set_cid(attest, atoi(optarg)))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ case '8':
+ if (!attest->set_kid(attest, atoi(optarg)))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ }
+ break;
+ }
+
+ switch (op)
+ {
+ case OP_USAGE:
+ usage();
+ break;
+ case OP_PRODUCTS:
+ attest->list_products(attest);
+ break;
+ case OP_KEYS:
+ attest->list_keys(attest);
+ break;
+ case OP_COMPONENTS:
+ attest->list_components(attest);
+ break;
+ case OP_FILES:
+ attest->list_files(attest);
+ break;
+ case OP_HASHES:
+ attest->list_hashes(attest);
+ break;
+ case OP_MEASUREMENTS:
+ attest->list_measurements(attest);
+ break;
+ case OP_ADD:
+ attest->add(attest);
+ break;
+ case OP_DEL:
+ attest->delete(attest);
+ break;
+ default:
+ usage();
+ exit(EXIT_FAILURE);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ char *uri;
+
+ /* enable attest debugging hook */
+ dbg = attest_dbg;
+ openlog("attest", 0, LOG_DEBUG);
+
+ atexit(library_deinit);
+
+ /* initialize library */
+ if (!library_init(NULL))
+ {
+ exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
+ }
+ if (!lib->plugins->load(lib->plugins, NULL,
+ lib->settings->get_str(lib->settings, "attest.load", PLUGINS)))
+ {
+ exit(SS_RC_INITIALIZATION_FAILED);
+ }
+
+ uri = lib->settings->get_str(lib->settings, "attest.database", NULL);
+ if (!uri)
+ {
+ fprintf(stderr, "database URI attest.database not set.\n");
+ exit(SS_RC_INITIALIZATION_FAILED);
+ }
+ attest = attest_db_create(uri);
+ if (!attest)
+ {
+ exit(SS_RC_INITIALIZATION_FAILED);
+ }
+ atexit(cleanup);
+ libimcv_init();
+ libpts_init();
+
+ do_args(argc, argv);
+
+ exit(EXIT_SUCCESS);
+}
+
diff --git a/src/libpts/plugins/imv_attestation/attest_db.c b/src/libpts/plugins/imv_attestation/attest_db.c
new file mode 100644
index 000000000..88d19eee1
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/attest_db.c
@@ -0,0 +1,1200 @@
+/*
+ * Copyright (C) 2011 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 "attest_db.h"
+
+#include "libpts.h"
+#include "pts/components/pts_comp_func_name.h"
+
+typedef struct private_attest_db_t private_attest_db_t;
+
+/**
+ * Private data of an attest_db_t object.
+ */
+struct private_attest_db_t {
+
+ /**
+ * Public members of attest_db_state_t
+ */
+ attest_db_t public;
+
+ /**
+ * Component Functional Name to be queried
+ */
+ pts_comp_func_name_t *cfn;
+
+ /**
+ * Primary key of the Component Functional Name to be queried
+ */
+ int cid;
+
+ /**
+ * TRUE if Component Functional Name has been set
+ */
+ bool comp_set;
+
+ /**
+ * Directory containing the Measurement file to be queried
+ */
+ char *dir;
+
+ /**
+ * Primary key of the directory to be queried
+ */
+ int did;
+
+ /**
+ * TRUE if directory has been set
+ */
+ bool dir_set;
+
+ /**
+ * Measurement file to be queried
+ */
+ char *file;
+
+ /**
+ * Primary key of measurement file to be queried
+ */
+ int fid;
+
+ /**
+ * TRUE if file has been set
+ */
+ bool file_set;
+
+ /**
+ * AIK to be queried
+ */
+ chunk_t key;
+
+ /**
+ * Primary key of the AIK to be queried
+ */
+ int kid;
+
+ /**
+ * TRUE if AIK has been set
+ */
+ bool key_set;
+
+ /**
+ * Software product to be queried
+ */
+ char *product;
+
+ /**
+ * Primary key of software product to be queried
+ */
+ int pid;
+
+ /**
+ * TRUE if product has been set
+ */
+ bool product_set;
+
+ /**
+ * File measurement hash algorithm
+ */
+ pts_meas_algorithms_t algo;
+
+ /**
+ * Optional owner (user/host name)
+ */
+ char *owner;
+
+ /**
+ * Attestation database
+ */
+ database_t *db;
+
+};
+
+char* print_cfn(pts_comp_func_name_t *cfn)
+{
+ static char buf[BUF_LEN];
+ char flags[8];
+ int type, vid, name, qualifier, n;
+ enum_name_t *names, *types;
+
+ vid = cfn->get_vendor_id(cfn),
+ name = cfn->get_name(cfn);
+ qualifier = cfn->get_qualifier(cfn);
+ n = snprintf(buf, BUF_LEN, "0x%06x/0x%08x-0x%02x", vid, name, qualifier);
+
+ names = pts_components->get_comp_func_names(pts_components, vid);
+ types = pts_components->get_qualifier_type_names(pts_components, vid);
+ type = pts_components->get_qualifier(pts_components, cfn, flags);
+ if (names && types)
+ {
+ n = snprintf(buf + n, BUF_LEN - n, " %N/%N [%s] %N",
+ pen_names, vid, names, name, flags, types, type);
+ }
+ return buf;
+}
+
+METHOD(attest_db_t, set_component, bool,
+ private_attest_db_t *this, char *comp, bool create)
+{
+ enumerator_t *e;
+ char *pos1, *pos2;
+ int vid, name, qualifier;
+ pts_comp_func_name_t *cfn;
+
+ if (this->comp_set)
+ {
+ printf("component has already been set\n");
+ return FALSE;
+ }
+
+ /* parse component string */
+ pos1 = strchr(comp, '/');
+ pos2 = strchr(comp, '-');
+ if (!pos1 || !pos2)
+ {
+ printf("component string must have the form \"vendor_id/name-qualifier\"\n");
+ return FALSE;
+ }
+ vid = atoi(comp);
+ name = atoi(pos1 + 1);
+ qualifier = atoi(pos2 + 1);
+ cfn = pts_comp_func_name_create(vid, name, qualifier);
+
+ e = this->db->query(this->db,
+ "SELECT id FROM components "
+ "WHERE vendor_id = ? AND name = ? AND qualifier = ?",
+ DB_INT, vid, DB_INT, name, DB_INT, qualifier, DB_INT);
+ if (e)
+ {
+ if (e->enumerate(e, &this->cid))
+ {
+ this->comp_set = TRUE;
+ this->cfn = cfn;
+ }
+ e->destroy(e);
+ }
+ if (this->comp_set)
+ {
+ return TRUE;
+ }
+
+ if (!create)
+ {
+ printf("component '%s' not found in database\n", print_cfn(cfn));
+ cfn->destroy(cfn);
+ return FALSE;
+ }
+
+ /* Add a new database entry */
+ this->comp_set = this->db->execute(this->db, &this->cid,
+ "INSERT INTO components (vendor_id, name, qualifier) "
+ "VALUES (?, ?, ?)",
+ DB_INT, vid, DB_INT, name, DB_INT, qualifier) == 1;
+
+ printf("component '%s' %sinserted into database\n", print_cfn(cfn),
+ this->comp_set ? "" : "could not be ");
+ if (this->comp_set)
+ {
+ this->cfn = cfn;
+ }
+ else
+ {
+ cfn->destroy(cfn);
+ }
+ return this->comp_set;
+}
+
+METHOD(attest_db_t, set_cid, bool,
+ private_attest_db_t *this, int cid)
+{
+ enumerator_t *e;
+ int vid, name, qualifier;
+
+ if (this->comp_set)
+ {
+ printf("component has already been set\n");
+ return FALSE;
+ }
+ this->cid = cid;
+
+ e = this->db->query(this->db, "SELECT vendor_id, name, qualifier "
+ "FROM components WHERE id = ?",
+ DB_INT, cid, DB_INT, DB_INT, DB_INT);
+ if (e)
+ {
+ if (e->enumerate(e, &vid, &name, &qualifier))
+ {
+ this->cfn = pts_comp_func_name_create(vid, name, qualifier);
+ this->comp_set = TRUE;
+ }
+ else
+ {
+ printf("no component found with cid %d\n", cid);
+ }
+ e->destroy(e);
+ }
+ return this->comp_set;
+}
+
+METHOD(attest_db_t, set_directory, bool,
+ private_attest_db_t *this, char *dir, bool create)
+{
+ enumerator_t *e;
+
+ if (this->dir_set)
+ {
+ printf("directory has already been set\n");
+ return FALSE;
+ }
+ free(this->dir);
+ this->dir = strdup(dir);
+
+ e = this->db->query(this->db,
+ "SELECT id FROM files WHERE type = 1 AND path = ?",
+ DB_TEXT, dir, DB_INT);
+ if (e)
+ {
+ if (e->enumerate(e, &this->did))
+ {
+ this->dir_set = TRUE;
+ }
+ e->destroy(e);
+ }
+ if (this->dir_set)
+ {
+ return TRUE;
+ }
+
+ if (!create)
+ {
+ printf("directory '%s' not found in database\n", dir);
+ return FALSE;
+ }
+
+ /* Add a new database entry */
+ this->dir_set = this->db->execute(this->db, &this->did,
+ "INSERT INTO files (type, path) VALUES (1, ?)",
+ DB_TEXT, dir) == 1;
+
+ printf("directory '%s' %sinserted into database\n", dir,
+ this->dir_set ? "" : "could not be ");
+
+ return this->dir_set;
+}
+
+METHOD(attest_db_t, set_did, bool,
+ private_attest_db_t *this, int did)
+{
+ enumerator_t *e;
+ char *dir;
+
+ if (this->dir_set)
+ {
+ printf("directory has already been set\n");
+ return FALSE;
+ }
+ this->did = did;
+
+ e = this->db->query(this->db, "SELECT path FROM files WHERE id = ?",
+ DB_INT, did, DB_TEXT);
+ if (e)
+ {
+ if (e->enumerate(e, &dir))
+ {
+ free(this->dir);
+ this->dir = strdup(dir);
+ this->dir_set = TRUE;
+ }
+ else
+ {
+ printf("no directory found with did %d\n", did);
+ }
+ e->destroy(e);
+ }
+ return this->dir_set;
+}
+
+METHOD(attest_db_t, set_file, bool,
+ private_attest_db_t *this, char *file, bool create)
+{
+ enumerator_t *e;
+
+ if (this->file_set)
+ {
+ printf("file has already been set\n");
+ return FALSE;
+ }
+ this->file = strdup(file);
+
+ e = this->db->query(this->db, "SELECT id FROM files WHERE path = ?",
+ DB_TEXT, file, DB_INT);
+ if (e)
+ {
+ if (e->enumerate(e, &this->fid))
+ {
+ this->file_set = TRUE;
+ }
+ e->destroy(e);
+ }
+ if (this->file_set)
+ {
+ return TRUE;
+ }
+
+ if (!create)
+ {
+ printf("file '%s' not found in database\n", file);
+ return FALSE;
+ }
+
+ /* Add a new database entry */
+ this->file_set = this->db->execute(this->db, &this->fid,
+ "INSERT INTO files (type, path) VALUES (0, ?)",
+ DB_TEXT, file) == 1;
+
+ printf("file '%s' %sinserted into database\n", file,
+ this->file_set ? "" : "could not be ");
+
+ return this->file_set;
+}
+
+METHOD(attest_db_t, set_fid, bool,
+ private_attest_db_t *this, int fid)
+{
+ enumerator_t *e;
+ char *file;
+
+ if (this->file_set)
+ {
+ printf("file has already been set\n");
+ return FALSE;
+ }
+ this->fid = fid;
+
+ e = this->db->query(this->db, "SELECT path FROM files WHERE id = ?",
+ DB_INT, fid, DB_TEXT);
+ if (e)
+ {
+ if (e->enumerate(e, &file))
+ {
+ this->file = strdup(file);
+ this->file_set = TRUE;
+ }
+ else
+ {
+ printf("no file found with fid %d\n", fid);
+ }
+ e->destroy(e);
+ }
+ return this->file_set;
+}
+
+METHOD(attest_db_t, set_key, bool,
+ private_attest_db_t *this, chunk_t key, bool create)
+{
+ enumerator_t *e;
+ char *owner;
+
+ if (this->key_set)
+ {
+ printf("key has already been set\n");
+ return FALSE;
+ }
+ this->key = key;
+
+ e = this->db->query(this->db, "SELECT id, owner FROM keys WHERE keyid= ?",
+ DB_BLOB, this->key, DB_INT, DB_TEXT);
+ if (e)
+ {
+ if (e->enumerate(e, &this->kid, &owner))
+ {
+ free(this->owner);
+ this->owner = strdup(owner);
+ this->key_set = TRUE;
+ }
+ e->destroy(e);
+ }
+ if (this->key_set)
+ {
+ return TRUE;
+ }
+
+ if (!create)
+ {
+ printf("key '%#B' not found in database\n", &this->key);
+ return FALSE;
+ }
+
+ /* Add a new database entry */
+ if (!this->owner)
+ {
+ this->owner = strdup("");
+ }
+ this->key_set = this->db->execute(this->db, &this->kid,
+ "INSERT INTO keys (keyid, owner) VALUES (?, ?)",
+ DB_BLOB, this->key, DB_TEXT, this->owner) == 1;
+
+ printf("key '%#B' %sinserted into database\n", &this->key,
+ this->key_set ? "" : "could not be ");
+
+ return this->key_set;
+
+};
+
+METHOD(attest_db_t, set_kid, bool,
+ private_attest_db_t *this, int kid)
+{
+ enumerator_t *e;
+ chunk_t key;
+ char *owner;
+
+ if (this->key_set)
+ {
+ printf("key has already been set\n");
+ return FALSE;
+ }
+ this->kid = kid;
+
+ e = this->db->query(this->db, "SELECT keyid, owner FROM keys WHERE id = ?",
+ DB_INT, kid, DB_BLOB, DB_TEXT);
+ if (e)
+ {
+ if (e->enumerate(e, &key, &owner))
+ {
+ this->owner = strdup(owner);
+ this->key = chunk_clone(key);
+ this->key_set = TRUE;
+ }
+ else
+ {
+ printf("no key found with kid %d\n", kid);
+ }
+ e->destroy(e);
+ }
+ return this->key_set;
+
+};
+
+METHOD(attest_db_t, set_product, bool,
+ private_attest_db_t *this, char *product, bool create)
+{
+ enumerator_t *e;
+
+ if (this->product_set)
+ {
+ printf("product has already been set\n");
+ return FALSE;
+ }
+ this->product = strdup(product);
+
+ e = this->db->query(this->db, "SELECT id FROM products WHERE name = ?",
+ DB_TEXT, product, DB_INT);
+ if (e)
+ {
+ if (e->enumerate(e, &this->pid))
+ {
+ this->product_set = TRUE;
+ }
+ e->destroy(e);
+ }
+ if (this->product_set)
+ {
+ return TRUE;
+ }
+
+ if (!create)
+ {
+ printf("product '%s' not found in database\n", product);
+ return FALSE;
+ }
+
+ /* Add a new database entry */
+ this->product_set = this->db->execute(this->db, &this->pid,
+ "INSERT INTO products (name) VALUES (?)",
+ DB_TEXT, product) == 1;
+
+ printf("product '%s' %sinserted into database\n", product,
+ this->product_set ? "" : "could not be ");
+
+ return this->product_set;
+}
+
+METHOD(attest_db_t, set_pid, bool,
+ private_attest_db_t *this, int pid)
+{
+ enumerator_t *e;
+ char *product;
+
+ if (this->product_set)
+ {
+ printf("product has already been set\n");
+ return FALSE;
+ }
+ this->pid = pid;
+
+ e = this->db->query(this->db, "SELECT name FROM products WHERE id = ?",
+ DB_INT, pid, DB_TEXT);
+ if (e)
+ {
+ if (e->enumerate(e, &product))
+ {
+ this->product = strdup(product);
+ this->product_set = TRUE;
+ }
+ else
+ {
+ printf("no product found with pid %d in database\n", pid);
+ }
+ e->destroy(e);
+ }
+ return this->product_set;
+}
+
+METHOD(attest_db_t, set_algo, void,
+ private_attest_db_t *this, pts_meas_algorithms_t algo)
+{
+ this->algo = algo;
+}
+
+METHOD(attest_db_t, set_owner, void,
+ private_attest_db_t *this, char *owner)
+{
+ free(this->owner);
+ this->owner = strdup(owner);
+}
+
+METHOD(attest_db_t, list_components, void,
+ private_attest_db_t *this)
+{
+ enumerator_t *e;
+ pts_comp_func_name_t *cfn;
+ int cid, vid, name, qualifier, count = 0;
+
+ if (this->kid)
+ {
+ e = this->db->query(this->db,
+ "SELECT c.id, c.vendor_id, c.name, c.qualifier "
+ "FROM components AS c "
+ "JOIN key_component AS kc ON c.id = kc.component "
+ "WHERE kc.key = ? ORDER BY c.vendor_id, c.name, c.qualifier",
+ DB_INT, this->kid, DB_INT, DB_INT, DB_INT, DB_INT);
+ }
+ else
+ {
+ e = this->db->query(this->db,
+ "SELECT id, vendor_id, name, qualifier FROM components "
+ "ORDER BY vendor_id, name, qualifier",
+ DB_INT, DB_INT, DB_INT, DB_INT);
+ }
+ if (e)
+ {
+ while (e->enumerate(e, &cid, &vid, &name, &qualifier))
+ {
+ cfn = pts_comp_func_name_create(vid, name, qualifier);
+ printf("%3d: %s\n", cid, print_cfn(cfn));
+ cfn->destroy(cfn);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d component%s found", count, (count == 1) ? "" : "s");
+ if (this->key_set)
+ {
+ printf(" for key %#B", &this->key);
+ }
+ printf("\n");
+ }
+}
+
+METHOD(attest_db_t, list_keys, void,
+ private_attest_db_t *this)
+{
+ enumerator_t *e;
+ chunk_t keyid;
+ char *owner;
+ int kid, count = 0;
+
+ if (this->cid)
+ {
+ e = this->db->query(this->db,
+ "SELECT k.id, k.keyid, k.owner FROM keys AS k "
+ "JOIN key_component AS kc ON k.id = kc.key "
+ "WHERE kc.component = ? ORDER BY k.keyid",
+ DB_INT, this->cid, DB_INT, DB_BLOB, DB_TEXT);
+ if (e)
+ {
+ while (e->enumerate(e, &kid, &keyid, &owner))
+ {
+ printf("%3d: %#B '%s'\n", kid, &keyid, owner);
+ count++;
+ }
+ e->destroy(e);
+ }
+ }
+ else
+ {
+ e = this->db->query(this->db, "SELECT id, keyid, owner FROM keys "
+ "ORDER BY keyid",
+ DB_INT, DB_BLOB, DB_TEXT);
+ if (e)
+ {
+ while (e->enumerate(e, &kid, &keyid, &owner))
+ {
+ printf("%3d: %#B '%s'\n", kid, &keyid, owner);
+ count++;
+ }
+ e->destroy(e);
+ }
+ }
+
+ printf("%d key%s found", count, (count == 1) ? "" : "s");
+ if (this->comp_set)
+ {
+ printf(" for component '%s'", print_cfn(this->cfn));
+ }
+ printf("\n");
+}
+
+METHOD(attest_db_t, list_files, void,
+ private_attest_db_t *this)
+{
+ enumerator_t *e;
+ char *file, *file_type[] = { " ", "d", "r" };
+ int fid, type, meas, meta, count = 0;
+
+ if (this->pid)
+ {
+ e = this->db->query(this->db,
+ "SELECT f.id, f.type, f.path, pf.measurement, pf.metadata "
+ "FROM files AS f "
+ "JOIN product_file AS pf ON f.id = pf.file "
+ "WHERE pf.product = ? ORDER BY f.path",
+ DB_INT, this->pid, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_INT);
+ if (e)
+ {
+ while (e->enumerate(e, &fid, &type, &file, &meas, &meta))
+ {
+ type = (type < 0 || type > 2) ? 0 : type;
+ printf("%3d: |%s%s| %s %s\n", fid, meas ? "M":" ", meta ? "T":" ",
+ file_type[type], file);
+ count++;
+ }
+ e->destroy(e);
+ }
+ }
+ else
+ {
+ e = this->db->query(this->db,
+ "SELECT id, type, path FROM files "
+ "ORDER BY path",
+ DB_INT, DB_INT, DB_TEXT);
+ if (e)
+ {
+ while (e->enumerate(e, &fid, &type, &file))
+ {
+ type = (type < 0 || type > 2) ? 0 : type;
+ printf("%3d: %s %s\n", fid, file_type[type], file);
+ count++;
+ }
+ e->destroy(e);
+ }
+ }
+
+ printf("%d file%s found", count, (count == 1) ? "" : "s");
+ if (this->product_set)
+ {
+ printf(" for product '%s'", this->product);
+ }
+ printf("\n");
+}
+
+METHOD(attest_db_t, list_products, void,
+ private_attest_db_t *this)
+{
+ enumerator_t *e;
+ char *product;
+ int pid, meas, meta, count = 0;
+
+ if (this->fid)
+ {
+ e = this->db->query(this->db,
+ "SELECT p.id, p.name, pf.measurement, pf.metadata "
+ "FROM products AS p "
+ "JOIN product_file AS pf ON p.id = pf.product "
+ "WHERE pf.file = ? ORDER BY p.name",
+ DB_INT, this->fid, DB_INT, DB_TEXT, DB_INT, DB_INT);
+ if (e)
+ {
+ while (e->enumerate(e, &pid, &product, &meas, &meta))
+ {
+ printf("%3d: |%s%s| %s\n", pid, meas ? "M":" ", meta ? "T":" ",
+ product);
+ count++;
+ }
+ e->destroy(e);
+ }
+ }
+ else
+ {
+ e = this->db->query(this->db, "SELECT id, name FROM products "
+ "ORDER BY name",
+ DB_INT, DB_TEXT);
+ if (e)
+ {
+ while (e->enumerate(e, &pid, &product))
+ {
+ printf("%3d: %s\n", pid, product);
+ count++;
+ }
+ e->destroy(e);
+ }
+ }
+
+ printf("%d product%s found", count, (count == 1) ? "" : "s");
+ if (this->file_set)
+ {
+ printf(" for file '%s'", this->file);
+ }
+ printf("\n");
+}
+
+/**
+ * get the directory if there is one from the files tables
+ */
+static void get_directory(private_attest_db_t *this, int did, char **directory)
+{
+ enumerator_t *e;
+ char *dir;
+
+ free(*directory);
+ *directory = strdup("");
+
+ if (did)
+ {
+ e = this->db->query(this->db,
+ "SELECT path from files WHERE id = ?",
+ DB_INT, did, DB_TEXT);
+ if (e)
+ {
+ if (e->enumerate(e, &dir))
+ {
+ free(*directory);
+ *directory = strdup(dir);
+ }
+ e->destroy(e);
+ }
+ }
+}
+
+static bool slash(char *directory, char *file)
+{
+ return *file != '/' && directory[max(0, strlen(directory)-1)] != '/';
+}
+
+METHOD(attest_db_t, list_hashes, void,
+ private_attest_db_t *this)
+{
+ enumerator_t *e;
+ chunk_t hash;
+ char *file, *dir, *product;
+ int fid, fid_old = 0, did, did_old = 0, count = 0;
+
+ dir = strdup("");
+
+ if (this->pid && this->fid)
+ {
+ e = this->db->query(this->db,
+ "SELECT hash FROM file_hashes "
+ "WHERE algo = ? AND file = ? AND directory = ? AND product = ?",
+ DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->did,
+ DB_INT, this->pid, DB_BLOB);
+ if (e)
+ {
+ while (e->enumerate(e, &hash))
+ {
+ if (this->fid != fid_old)
+ {
+ printf("%3d: %s%s%s\n", this->fid, this->dir,
+ slash(this->dir, this->file) ? "/" : "", this->file);
+ fid_old = this->fid;
+ }
+ printf(" %#B\n", &hash);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d %N value%s found for product '%s'\n", count,
+ hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ (count == 1) ? "" : "s", this->product);
+ }
+ }
+ else if (this->pid)
+ {
+ e = this->db->query(this->db,
+ "SELECT f.id, f. f.path, fh.hash, fh.directory "
+ "FROM file_hashes AS fh "
+ "JOIN files AS f ON f.id = fh.file "
+ "WHERE fh.algo = ? AND fh.product = ? "
+ "ORDER BY fh.directory, f.path",
+ DB_INT, this->algo, DB_INT, this->pid,
+ DB_INT, DB_TEXT, DB_BLOB, DB_INT);
+ if (e)
+ {
+ while (e->enumerate(e, &fid, &file, &hash, &did))
+ {
+ if (fid != fid_old || did != did_old)
+ {
+ if (did != did_old)
+ {
+ get_directory(this, did, &dir);
+ }
+ printf("%3d: %s%s%s\n", fid,
+ dir, slash(dir, file) ? "/" : "", file);
+ fid_old = fid;
+ did_old = did;
+ }
+ printf(" %#B\n", &hash);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d %N value%s found for product '%s'\n", count,
+ hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ (count == 1) ? "" : "s", this->product);
+ }
+ }
+ else if (this->fid)
+ {
+ e = this->db->query(this->db,
+ "SELECT p.name, fh.hash, fh.directory "
+ "FROM file_hashes AS fh "
+ "JOIN products AS p ON p.id = fh.product "
+ "WHERE fh.algo = ? AND fh.file = ? AND fh.directory = ?"
+ "ORDER BY p.name",
+ DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->did,
+ DB_TEXT, DB_BLOB, DB_INT);
+ if (e)
+ {
+ while (e->enumerate(e, &product, &hash, &did))
+ {
+ printf("%#B '%s'\n", &hash, product);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d %N value%s found for file '%s%s%s'\n",
+ count, hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ (count == 1) ? "" : "s", this->dir,
+ slash(this->dir, this->file) ? "/" : "", this->file);
+ }
+ }
+ else
+ {
+ e = this->db->query(this->db,
+ "SELECT f.id, f.path, p.name, fh.hash, fh.directory "
+ "FROM file_hashes AS fh "
+ "JOIN files AS f ON f.id = fh.file "
+ "JOIN products AS p ON p.id = fh.product "
+ "WHERE fh.algo = ? "
+ "ORDER BY fh.directory, f.path, p.name",
+ DB_INT, this->algo,
+ DB_INT, DB_TEXT, DB_TEXT, DB_BLOB, DB_INT);
+ if (e)
+ {
+ while (e->enumerate(e, &fid, &file, &product, &hash, &did))
+ {
+ if (fid != fid_old || did != did_old)
+ {
+ if (did != did_old)
+ {
+ get_directory(this, did, &dir);
+ did_old = did;
+ }
+ printf("%3d: %s%s%s\n", fid,
+ dir, slash(dir, file) ? "/" : "", file);
+ fid_old = fid;
+ }
+ printf(" %#B '%s'\n", &hash, product);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d %N value%s found\n", count, hash_algorithm_names,
+ pts_meas_algo_to_hash(this->algo), (count == 1) ? "" : "s");
+ }
+ }
+ free(dir);
+}
+
+METHOD(attest_db_t, list_measurements, void,
+ private_attest_db_t *this)
+{
+ enumerator_t *e;
+ chunk_t hash, keyid;
+ pts_comp_func_name_t *cfn;
+ char *owner;
+ int seq_no, pcr, vid, name, qualifier;
+ int cid, cid_old = 0, kid, kid_old = 0, count = 0;
+
+ if (this->kid && this->cid)
+ {
+ e = this->db->query(this->db,
+ "SELECT ch.seq_no, ch.pcr, ch.hash, k.owner "
+ "FROM component_hashes AS ch "
+ "JOIN keys AS k ON k.id = ch.key "
+ "WHERE ch.algo = ? AND ch.key = ? AND ch.component = ? "
+ "ORDER BY seq_no",
+ DB_INT, this->algo, DB_INT, this->kid, DB_INT, this->cid,
+ DB_INT, DB_INT, DB_BLOB, DB_TEXT);
+ if (e)
+ {
+ while (e->enumerate(e, &seq_no, &pcr, &hash, &owner))
+ {
+ if (this->kid != kid_old)
+ {
+ printf("%3d: %#B '%s'\n", this->kid, &this->key, owner);
+ kid_old = this->kid;
+ }
+ printf("%5d %02d %#B\n", seq_no, pcr, &hash);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d %N value%s found for component '%s'\n", count,
+ hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ (count == 1) ? "" : "s", print_cfn(this->cfn));
+ }
+ }
+ else if (this->cid)
+ {
+ e = this->db->query(this->db,
+ "SELECT ch.seq_no, ch.pcr, ch.hash, k.id, k.keyid, k.owner "
+ "FROM component_hashes AS ch "
+ "JOIN keys AS k ON k.id = ch.key "
+ "WHERE ch.algo = ? AND ch.component = ? "
+ "ORDER BY keyid, seq_no",
+ DB_INT, this->algo, DB_INT, this->cid,
+ DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB, DB_TEXT);
+ if (e)
+ {
+ while (e->enumerate(e, &seq_no, &pcr, &hash, &kid, &keyid, &owner))
+ {
+ if (kid != kid_old)
+ {
+ printf("%3d: %#B '%s'\n", kid, &keyid, owner);
+ kid_old = kid;
+ }
+ printf("%5d %02d %#B\n", seq_no, pcr, &hash);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d %N value%s found for component '%s'\n", count,
+ hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ (count == 1) ? "" : "s", print_cfn(this->cfn));
+ }
+
+ }
+ else if (this->kid)
+ {
+ e = this->db->query(this->db,
+ "SELECT ch.seq_no, ch.pcr, ch.hash, "
+ "c.id, c.vendor_id, c.name, c.qualifier "
+ "FROM component_hashes AS ch "
+ "JOIN components AS c ON c.id = ch.component "
+ "WHERE ch.algo = ? AND ch.key = ? "
+ "ORDER BY vendor_id, name, qualifier, seq_no",
+ DB_INT, this->algo, DB_INT, this->kid, DB_INT, DB_INT, DB_BLOB,
+ DB_INT, DB_INT, DB_INT, DB_INT);
+ if (e)
+ {
+ while (e->enumerate(e, &seq_no, &pcr, &hash, &cid, &vid, &name,
+ &qualifier))
+ {
+ if (cid != cid_old)
+ {
+ cfn = pts_comp_func_name_create(vid, name, qualifier);
+ printf("%3d: %s\n", cid, print_cfn(cfn));
+ cfn->destroy(cfn);
+ cid_old = cid;
+ }
+ printf("%5d %02d %#B\n", seq_no, pcr, &hash);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d %N value%s found for key %#B '%s'\n", count,
+ hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ (count == 1) ? "" : "s", &this->key, this->owner);
+ }
+ }
+}
+
+METHOD(attest_db_t, add, bool,
+ private_attest_db_t *this)
+{
+ bool success = FALSE;
+
+ if (this->kid && this->cid)
+ {
+ success = this->db->execute(this->db, NULL,
+ "INSERT INTO key_component (key, component) VALUES (?, ?)",
+ DB_UINT, this->kid, DB_UINT, this->cid) == 1;
+
+ printf("key/component pair (%d/%d) %sinserted into database\n",
+ this->kid, this->cid, success ? "" : "could not be ");
+ }
+ return success;
+}
+
+METHOD(attest_db_t, delete, bool,
+ private_attest_db_t *this)
+{
+ bool success;
+
+ if (this->pid && (this->fid || this->did))
+ {
+ printf("deletion of product/file entries not supported yet\n");
+ return FALSE;
+ }
+
+ if (this->kid && this->cid)
+ {
+ success = this->db->execute(this->db, NULL,
+ "DELETE FROM key_component "
+ "WHERE key = ? AND component = ?",
+ DB_UINT, this->kid, DB_UINT, this->cid) > 0;
+
+ printf("key/component pair (%d/%d) %sdeleted from database\n",
+ this->kid, this->cid, success ? "" : "could not be ");
+ return success;
+ }
+
+ if (this->cid)
+ {
+ success = this->db->execute(this->db, NULL,
+ "DELETE FROM components WHERE id = ?",
+ DB_UINT, this->cid) > 0;
+
+ printf("component '%s' %sdeleted from database\n", print_cfn(this->cfn),
+ success ? "" : "could not be ");
+ return success;
+ }
+
+ if (this->did)
+ {
+ success = this->db->execute(this->db, NULL,
+ "DELETE FROM files WHERE type = 1 AND id = ?",
+ DB_UINT, this->did) > 0;
+
+ printf("directory '%s' %sdeleted from database\n", this->dir,
+ success ? "" : "could not be ");
+ return success;
+ }
+
+ if (this->fid)
+ {
+ success = this->db->execute(this->db, NULL,
+ "DELETE FROM files WHERE id = ?",
+ DB_UINT, this->fid) > 0;
+
+ printf("file '%s' %sdeleted from database\n", this->file,
+ success ? "" : "could not be ");
+ return success;
+ }
+
+ if (this->kid)
+ {
+ success = this->db->execute(this->db, NULL,
+ "DELETE FROM keys WHERE id = ?",
+ DB_UINT, this->kid) > 0;
+
+ printf("key %#B %sdeleted from database\n", &this->key,
+ success ? "" : "could not be ");
+ return success;
+ }
+ if (this->pid)
+ {
+ success = this->db->execute(this->db, NULL,
+ "DELETE FROM products WHERE id = ?",
+ DB_UINT, this->pid) > 0;
+
+ printf("product '%s' %sdeleted from database\n", this->product,
+ success ? "" : "could not be ");
+ return success;
+ }
+
+ printf("empty delete command\n");
+ return FALSE;
+}
+
+METHOD(attest_db_t, destroy, void,
+ private_attest_db_t *this)
+{
+ DESTROY_IF(this->db);
+ DESTROY_IF(this->cfn);
+ free(this->product);
+ free(this->file);
+ free(this->dir);
+ free(this->owner);
+ free(this->key.ptr);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+attest_db_t *attest_db_create(char *uri)
+{
+ private_attest_db_t *this;
+
+ INIT(this,
+ .public = {
+ .set_component = _set_component,
+ .set_cid = _set_cid,
+ .set_directory = _set_directory,
+ .set_did = _set_did,
+ .set_file = _set_file,
+ .set_fid = _set_fid,
+ .set_key = _set_key,
+ .set_kid = _set_kid,
+ .set_product = _set_product,
+ .set_pid = _set_pid,
+ .set_algo = _set_algo,
+ .set_owner = _set_owner,
+ .list_products = _list_products,
+ .list_files = _list_files,
+ .list_components = _list_components,
+ .list_keys = _list_keys,
+ .list_hashes = _list_hashes,
+ .list_measurements = _list_measurements,
+ .add = _add,
+ .delete = _delete,
+ .destroy = _destroy,
+ },
+ .dir = strdup(""),
+ .algo = PTS_MEAS_ALGO_SHA256,
+ .db = lib->db->create(lib->db, uri),
+ );
+
+ if (!this->db)
+ {
+ fprintf(stderr, "opening database failed.\n");
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
diff --git a/src/libpts/plugins/imv_attestation/attest_db.h b/src/libpts/plugins/imv_attestation/attest_db.h
new file mode 100644
index 000000000..9c9a9dcba
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/attest_db.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2011 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 attest_db_t attest_db
+ * @{ @ingroup attest_db
+ */
+
+#ifndef ATTEST_DB_H_
+#define ATTEST_DB_H_
+
+#include <pts/pts_meas_algo.h>
+
+#include <library.h>
+
+typedef struct attest_db_t attest_db_t;
+
+/**
+ * Attestation database object
+ */
+struct attest_db_t {
+
+ /**
+ * Set functional component to be queried
+ *
+ * @param comp functional component
+ * @param create if TRUE create database entry if it doesn't exist
+ * @return TRUE if successful
+ */
+ bool (*set_component)(attest_db_t *this, char *comp, bool create);
+
+ /**
+ * Set primary key of the functional component to be queried
+ *
+ * @param fid primary key of functional component
+ * @return TRUE if successful
+ */
+ bool (*set_cid)(attest_db_t *this, int fid);
+
+ /**
+ * Set directory to be queried
+ *
+ * @param dir directory
+ * @param create if TRUE create database entry if it doesn't exist
+ * @return TRUE if successful
+ */
+ bool (*set_directory)(attest_db_t *this, char *dir, bool create);
+
+ /**
+ * Set primary key of the directory to be queried
+ *
+ * @param did primary key of directory
+ * @return TRUE if successful
+ */
+ bool (*set_did)(attest_db_t *this, int did);
+
+ /**
+ * Set measurement file to be queried
+ *
+ * @param file measurement file
+ * @param create if TRUE create database entry if it doesn't exist
+ * @return TRUE if successful
+ */
+ bool (*set_file)(attest_db_t *this, char *file, bool create);
+
+ /**
+ * Set primary key of the measurement file to be queried
+ *
+ * @param fid primary key of measurement file
+ * @return TRUE if successful
+ */
+ bool (*set_fid)(attest_db_t *this, int fid);
+
+ /**
+ * Set functional component to be queried
+ *
+ * @param key AIK
+ * @param create if TRUE create database entry if it doesn't exist
+ * @return TRUE if successful
+ */
+ bool (*set_key)(attest_db_t *this, chunk_t key, bool create);
+
+ /**
+ * Set primary key of the AIK to be queried
+ *
+ * @param kid primary key of AIK
+ * @return TRUE if successful
+ */
+ bool (*set_kid)(attest_db_t *this, int kid);
+
+ /**
+ * Set software product to be queried
+ *
+ * @param product software product
+ * @param create if TRUE create database entry if it doesn't exist
+ * @return TRUE if successful
+ */
+ bool (*set_product)(attest_db_t *this, char *product, bool create);
+
+ /**
+ * Set primary key of the software product to be queried
+ *
+ * @param pid primary key of software product
+ * @return TRUE if successful
+ */
+ bool (*set_pid)(attest_db_t *this, int pid);
+
+ /**
+ * Set measurement hash algorithm
+ *
+ * @param algo hash algorithm
+ */
+ void (*set_algo)(attest_db_t *this, pts_meas_algorithms_t algo);
+
+ /**
+ * Set owner [user/host] of an AIK
+ *
+ * @param owner user/host name
+ * @return TRUE if successful
+ */
+ void (*set_owner)(attest_db_t *this, char *owner);
+
+ /**
+ * List all products stored in the database
+ */
+ void (*list_products)(attest_db_t *this);
+
+ /**
+ * List selected files stored in the database
+ */
+ void (*list_files)(attest_db_t *this);
+
+ /**
+ * List all components stored in the database
+ */
+ void (*list_components)(attest_db_t *this);
+
+ /**
+ * List all AIKs stored in the database
+ */
+ void (*list_keys)(attest_db_t *this);
+
+ /**
+ * List selected measurement hashes stored in the database
+ */
+ void (*list_hashes)(attest_db_t *this);
+
+ /**
+ * List selected component measurement stored in the database
+ */
+ void (*list_measurements)(attest_db_t *this);
+
+ /**
+ * Add an entry to the database
+ */
+ bool (*add)(attest_db_t *this);
+
+ /**
+ * Delete an entry from the database
+ */
+ bool (*delete)(attest_db_t *this);
+
+ /**
+ * Destroy attest_db_t object
+ */
+ void (*destroy)(attest_db_t *this);
+
+};
+
+/**
+ * Create an attest_db_t instance
+ *
+ * @param uri database URI
+ */
+attest_db_t* attest_db_create(char *uri);
+
+#endif /** ATTEST_DB_H_ @}*/
diff --git a/src/libpts/plugins/imv_attestation/attest_usage.c b/src/libpts/plugins/imv_attestation/attest_usage.c
new file mode 100644
index 000000000..e58f821e0
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/attest_usage.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 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 <stdio.h>
+
+#include "attest_usage.h"
+
+/**
+ * print attest usage info
+ */
+void usage(void)
+{
+ printf("\
+Usage:\n\
+ ipsec attest --files|--products|--keys|--hashes [options]\n\
+ \n\
+ ipsec attest --components|-keys|--measurements|--add|--del [options]\n\
+ \n\
+ ipsec attest --files [--product <name>|--pid <id>]\n\
+ Show a list of files with a software product name or\n\
+ its primary key as an optional selector.\n\
+ \n\
+ ipsec attest --products [--file <path>|--fid <id>]\n\
+ Show a list of supported software products with a file path or\n\
+ its primary key as an optional selector.\n\
+ \n\
+ ipsec attest --hashes [--sha1|--sha256|--sha384] [--product <name>|--pid <id>]\n\
+ Show a list of measurement hashes for a given software product or\n\
+ its primary key as an optional selector.\n\
+ \n\
+ ipsec attest --hashes [--sha1|--sha256|--sha384] [--file <path>|--fid <id>]\n\
+ Show a list of measurement hashes for a given file or\n\
+ its primary key as an optional selector.\n\
+ \n\
+ ipsec attest --components [--key <digest>|--kid <id>]\n\
+ Show a list of components with an AIK digest or\n\
+ its primary key as an optional selector.\n\
+ \n\
+ ipsec attest --keys [--components <cfn>|--cid <id>]\n\
+ Show a list of AIK key digests with a component or\n\
+ its primary key as an optional selector.\n\
+ \n\
+ ipsec attest --measurements [--sha1|--sha256|--sha384] [--component <cfn>|--cid <id>]\n\
+ Show a list of component measurements for a given component or\n\
+ its primary key as an optional selector.\n\
+ \n\
+ ipsec attest --measurements [--sha1|--sha256|--sha384] [--key <digest>|--kid <id>|--aik <path>]\n\
+ Show a list of component measurements for a given AIK or\n\
+ its primary key as an optional selector.\n\
+ \n\
+ ipsec attest --add --file <path>|--dir <path>|--product <name>|--component <cfn>\n\
+ Add a file, directory, product or component entry\n\
+ Component <cfn> entries must be of the form <vendor_id>/<name>-<qualifier>\n\
+ \n\
+ ipsec attest --add [--owner <name>] --key <digest>|--aik <path>\n\
+ Add an AIK public key digest entry preceded by an optional owner name\n\
+ \n\
+ ipsec attest --del --file <path>|--fid <id>|--dir <path>|--did <id>\n\
+ Delete a file or directory entry referenced either by value or primary key\n\
+ \n\
+ ipsec attest --del --product <name>|--pid <id>|--component <cfn>|--cid <id>\n\
+ Delete a product or component entry referenced either by value or primary key\n\
+ \n\
+ ipsec attest --del --key <digest>|--kid <id>|--aik <path>\n\
+ Delete an AIK entry referenced either by value or primary key\n\
+ \n");
+}
+
diff --git a/src/libpts/plugins/imv_attestation/attest_usage.h b/src/libpts/plugins/imv_attestation/attest_usage.h
new file mode 100644
index 000000000..bce801e9d
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/attest_usage.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef ATTEST_USAGE_H_
+#define ATTEST_USAGE_H_
+
+/**
+ * print attest usage info
+ */
+void usage(void);
+
+
+#endif /* ATTEST_USAGE_H_ */
diff --git a/src/libpts/plugins/imv_attestation/data.sql b/src/libpts/plugins/imv_attestation/data.sql
new file mode 100644
index 000000000..e6e03627a
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/data.sql
@@ -0,0 +1,1305 @@
+/* Products */
+
+INSERT INTO products (
+ name
+) VALUES (
+ 'Ubuntu 11.04 i686'
+);
+
+INSERT INTO products (
+ name
+) VALUES (
+ 'Ubuntu 11.04 x86_64'
+);
+
+INSERT INTO products (
+ name
+) VALUES (
+ 'CentOS release 5.6 (Final) x86_64'
+);
+
+INSERT INTO products (
+ name
+) VALUES (
+ 'Ubuntu 10.10 x86_64'
+);
+
+INSERT INTO products (
+ name
+) VALUES (
+ 'Ubuntu 10.10 i686'
+);
+
+INSERT INTO products (
+ name
+) VALUES (
+ 'Gentoo Base System release 1.12.11.1 i686'
+);
+
+INSERT INTO products (
+ name
+) VALUES (
+ 'Ubuntu 11.10 i686'
+);
+
+/* Files */
+
+INSERT INTO files ( /* 1 */
+ type, path
+) VALUES (
+ 0, '/lib/i386-linux-gnu/libdl.so.2'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, '/lib/x86_64-linux-gnu/libdl.so.2'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, '/lib/libdl.so.2'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, '/sbin/iptables'
+);
+
+INSERT INTO files ( /* 5 */
+ type, path
+) VALUES (
+ 0, '/lib/libxtables.so.5'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, '/lib/libxtables.so.2'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 1, '/lib/xtables/'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, 'libxt_udp.so'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, 'libxt_tcp.so'
+);
+
+INSERT INTO files ( /* 10 */
+ type, path
+) VALUES (
+ 0, 'libxt_esp.so'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, 'libxt_policy.so'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, 'libxt_conntrack.so'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, 'libipt_SNAT.so'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, 'libipt_DNAT.so'
+);
+
+INSERT INTO files ( /* 15 */
+ type, path
+) VALUES (
+ 0, 'libipt_MASQUERADE.so'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, 'libipt_LOG.so'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, '/sbin/ip6tables'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, 'libip6t_LOG.so'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, 'libxt_mark.so'
+);
+
+INSERT INTO files ( /* 20 */
+ type, path
+) VALUES (
+ 0, 'libxt_MARK.so'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 1, '/lib/iptables'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, '/etc/tnc_config'
+);
+
+/* Product-File */
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 1, 1, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 1, 4, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 1, 5, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 1, 7, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 1, 17, 1
+);
+
+INSERT INTO product_file (
+ product, file, metadata
+) VALUES (
+ 1, 22, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 2, 2, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 2, 4, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 2, 5, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 2, 7, 1
+);
+
+INSERT INTO product_file (
+ product, file, metadata
+) VALUES (
+ 2, 22, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 3, 3, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 3, 4, 1
+);
+
+INSERT INTO product_file (
+ product, file, metadata
+) VALUES (
+ 3, 22, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 4, 3, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 4, 4, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 4, 6, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 4, 7, 1
+);
+
+INSERT INTO product_file (
+ product, file, metadata
+) VALUES (
+ 4, 22, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 5, 3, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 5, 4, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 5, 6, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 5, 7, 1
+);
+
+INSERT INTO product_file (
+ product, file, metadata
+) VALUES (
+ 5, 22, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 6, 3, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 6, 4, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 6, 17, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 6, 21, 1
+);
+
+INSERT INTO product_file (
+ product, file, metadata
+) VALUES (
+ 6, 22, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 7, 1, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 7, 4, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 7, 5, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 7, 7, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 7, 17, 1
+);
+
+INSERT INTO product_file (
+ product, file, metadata
+) VALUES (
+ 7, 22, 1
+);
+
+/* File Hashes */
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 1, 1, 32768, X'409bb1a97e26ea1144cdd6801b8159f17f376b8f'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 1, 1, 16384, X'675172775cfd2b73ed1e249e4a730921f06c2f86fffdce4c71674cc654f37ed7'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 1, 1, 8192, X'abc8ce3fc99b6dcec6745ffc2f59e35372b9b126491480d04b0f93076beded06cccb27b61f1170868fada8cddefa7be4'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 1, 7, 32768, X'40763935cdea25119002c42f984b994d8d2a6d75'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 1, 7, 16384, X'27c4f867d3f994a361e0b25d7846b3698d29f82b38662f233a97cafc60c44189'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 1, 7, 8192, X'301dad8829308f5a68c603a87bf961b91365f0346ac2f322de3ddcbb4645f56c0e6d2dc503ec2abff8fe8e895ce9304d'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 2, 2, 32768, X'2a4047437e6fb346e2d854fc415e16b80e75bf6b'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 2, 2, 16384, X'86aa0bf93dade999277d963338402ed437271f3436f594a49ffca85b6c487523'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 2, 2, 8192, X'6090441219c0b478d294ae88e006d85ac0d94464573bcca7d180618a612bd170e3ee47c1545861b0f06fe0db85544c59'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 3, 3, 32768, X'07d8c0218a5b3469b409dc95cf8f77a341a595fb'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 3, 3, 16384, X'b083699fbc4c9f9e0d463361118904a3832670ad2fe3d6b42f811061188d509f'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 3, 3, 8192, X'b14908de476467a11a7a98835d1cf8317c7b80a684692426ddd7b0014e00b70b3d1b4fc1dd02ad440447612ee9dadb52'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 3, 4, 32768, X'4350f082511c742cc05050d18a23d1da9fb09340'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 3, 4, 16384, X'f9e12408828b5842c45503342dc2af78bc74d701a19c5fd5483df0e203315e0a'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 3, 4, 8192, X'1a5ea36e4ab0cda550c0da2af6a62d9310981d2f170c9e75bff1770be2efb9ddccc451743ff4c3d76876364f19fdf8c1'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 3, 6, 32768, X'91f4bb52404ca26b3a797152076ca5d233b93c1d'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 3, 6, 16384, X'59bced619eabbde5dd3ef74b92ba660349e105d36be9756c8d1598abd4bc066c'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 3, 6, 8192, X'fc6b1350067d23fca711b8a674e0367ad255bae0ddb2efe10dca1b18b18985bd09a7459937fda729d349874bb2701df3'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 1, 32768, X'ff6deca0eeb7a257205c5f0ab5f5d821ea184098'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 1, 16384, X'5c84fdf7c529d3c65a001587eda641fe489f83961a621fe514e7852a842690d6'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 1, 8192, X'8bd699f85f5b3efb27204b4699c518f871ef245d03b4bf8d1cc00456025017546030c2f493525754cffcd24cdbc03b21'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 2, 32768, X'1118805b490051637e93e592f4c71e0ee78a2422'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 2, 16384, X'5ea7229ebef5dc8f9fb2118676b773dd62cf89dc21657e3b8fbbcbc70ee24bd3'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 2, 8192, X'3b8da9e704e644eb7b196981624a2f6826c401d689e00ba47e42ff46351d27c6b9e91b1e8351ee01f66e5244b4c2a9b0'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 3, 32768, X'b5cd500ec15d6bfcae15e0af1dc121df7114b97d'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 3, 16384, X'b94f1cba12abb0ec79d207142526388ec0d127c4f2aad4a46a623a1f69bac84f'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 3, 8192, X'6663d66ff0e93b1b8a1edcdbe45d64834e29dc9c2b1d23126fd370a85b2c56da5cadcbc65b6e8afbb1e18bea8e413bd1'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 4, 32768, X'86c4463293859874243d8374f7f3ef60f44f9309'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 4, 16384, X'348b711f16ee9810738857c8ffbc54f8e16a393df8635cb29b02fc62daeefc14'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 4, 8192, X'0cb6b7d91148b1bb1b9333bc71de01509cb6d12c646a6756e6942647046286fbbca92b25dc1999e8f81be1264061ee4d'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 6, 32768, X'e3cf3ef2ee5df0117972808bfa93b7795f5da873'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 6, 16384, X'fde81f544e49c44aabe0e312a00a7f8af01a0e3123dc5c54c65e3e78ba475b22'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 6, 8192, X'e0cc89d1f229f9f35109bef3b163badc0941ca0a957d09e397a8d06e2b32e737f1f1135ebf0c0546d3d4c5354aaca40f'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 7, 32768, X'ff6deca0eeb7a257205c5f0ab5f5d821ea184098'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 7, 16384, X'5c84fdf7c529d3c65a001587eda641fe489f83961a621fe514e7852a842690d6'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 4, 7, 8192, X'8bd699f85f5b3efb27204b4699c518f871ef245d03b4bf8d1cc00456025017546030c2f493525754cffcd24cdbc03b21'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 5, 1, 32768, X'7a3ca72158e60b0c91e48a420848f1b693aea26c'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 5, 1, 16384, X'f9693c7d36c087d51f5012897fa0e8bb94081854d080c84f831f4d693d22f645'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 5, 1, 8192, X'4ec135e54c8840ab575fcdf00c66f996f763863ad30800b0f0a0b02e7899697d6ab9ccfe185ccbc16c19f38d0a27becb'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 5, 2, 32768, X'5d36a26856021d68a42f8bd7ca22365579d43891'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 5, 2, 16384, X'411be0558ad0cef33b437dafeed40104917e2079646524145abf9d05ddc6c1c5'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 5, 2, 8192, X'237f4691f9b780bec7aff217d64a9780ceed2973a41e86c92e0d6dab81cc5d13a9b99ba408302264f5665de1f42ef6e1'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 5, 7, 32768, X'7a3ca72158e60b0c91e48a420848f1b693aea26c'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 5, 7, 16384, X'f9693c7d36c087d51f5012897fa0e8bb94081854d080c84f831f4d693d22f645'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 5, 7, 8192, X'4ec135e54c8840ab575fcdf00c66f996f763863ad30800b0f0a0b02e7899697d6ab9ccfe185ccbc16c19f38d0a27becb'
+);
+
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 6, 4, 32768, X'92e66ae282947f66544682039a33fd1dbd402244'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 6, 4, 16384, X'dc6bad544f72c4538fb92f777646fd734b49ce95f41b2c96b74a21addbc86ed8'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 6, 4, 8192, X'08fd91f9017763212d1491f178e4d7e41d34a21b0117ee3321d832f5b8e02d4c7152a6cdc53bb4ca7e8aad5b1f279d1f'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 7, 1, 32768, X'11ce3b45feb3e66a75490d42ba95071ac6f40a7f'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 7, 1, 16384, X'468ef70f19372bc4a2b1805ffa3621515061fc19fa361374788bd362d638ac02'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 7, 1, 8192, X'63076ae505ce52c37878c9b6891ac516320046403aec25bf347c7011c2d28d5db7e2946d1fae3006ab4ef43716ff4558'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 7, 4, 32768, X'200eab67377bf3d5a25372838c38841658a718e4'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 7, 4, 16384, X'31045af9a12efdc58155a177e9391dd28b93fa38af58ce00f49259cc26e97687'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 7, 4, 8192, X'e8c64b508171d947069382da58dc7e39a97ce878a07f494a6fb370efb09116d32f1d4cdddeef85f22e14d1c5d5a37625'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 7, 7, 32768, X'11ce3b45feb3e66a75490d42ba95071ac6f40a7f'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 7, 7, 16384, X'468ef70f19372bc4a2b1805ffa3621515061fc19fa361374788bd362d638ac02'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 7, 7, 8192, X'63076ae505ce52c37878c9b6891ac516320046403aec25bf347c7011c2d28d5db7e2946d1fae3006ab4ef43716ff4558'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 21, 6, 32768, X'010873de0d682a26e1c6795dd4992248cc47cdd1'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 21, 6, 16384, X'bfb45524d81a3645bf216a6cf52cd5624aadf6717012bf722afce2db3e31f712'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 21, 6, 8192, X'f69b3f60b904f2deb39ea1fb9b0132638f0aea27357e365297f6b2ec895d42b260143b5e912d00df1a4a1d75a1b508fa'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 7, 1, 32768, X'1d740abd38f9f4bc81ca434a0e25b6e21704248b'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 7, 1, 16384, X'e26bb7175956dc8747a81431e810f830413b6c63756bf5156ab51367fe4f48a0'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 7, 1, 8192, X'5d3637413b9e318d0e0be6a9da86121062b99d1bdb084dfda4222baa71b250de644b4024281760b4eae926e03fac4fdb'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 7, 4, 32768, X'd2bf3556a0b38cfba2962d058fa8ea777397e82d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 7, 4, 16384, X'4ec845e828af69dcbde3ecb981096ac1e25c9e3e607e9a24b27da7e44527edf9'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 7, 4, 8192, X'3204a34ca409730298f60361865dace24900827ee9f3bc87884d50827911b4b17beb4c09bad77e43f28938f10bc5138a'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 7, 7, 32768, X'1d740abd38f9f4bc81ca434a0e25b6e21704248b'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 7, 7, 16384, X'e26bb7175956dc8747a81431e810f830413b6c63756bf5156ab51367fe4f48a0'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 7, 7, 8192, X'5d3637413b9e318d0e0be6a9da86121062b99d1bdb084dfda4222baa71b250de644b4024281760b4eae926e03fac4fdb'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 21, 6, 32768, X'e1df4f3949b09c25e15b9c9b7088a60d683903a8'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 21, 6, 16384, X'46f0ec6b0a2c3a24157019ed60f03de2ec9160d07f12b7e0b3d3f02b609a151d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 21, 6, 8192, X'4f73eae305e01e9ad57b5b1271a16bb8518fb82135aeb27311aa390d0d3a564b596adb723137f15bbf1db38b8dcbbdae'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 10, 7, 1, 32768, X'339a58a1b313830c3cc74cb3fb52a5b8152f44e6'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 10, 7, 1, 16384, X'789f2c6a9382bb342964a12947ddf84735d3e3ed3aefbae407098738cdf7c686'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 10, 7, 1, 8192, X'858310a6e4b6311c491c4370990bfd6b9f03a49bb5ddf45b0d788f7043f130016e11be6bd95db66e49e2906a87adf8cb'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 10, 7, 7, 32768, X'339a58a1b313830c3cc74cb3fb52a5b8152f44e6'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 10, 7, 7, 16384, X'789f2c6a9382bb342964a12947ddf84735d3e3ed3aefbae407098738cdf7c686'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 10, 7, 7, 8192, X'858310a6e4b6311c491c4370990bfd6b9f03a49bb5ddf45b0d788f7043f130016e11be6bd95db66e49e2906a87adf8cb'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 10, 21, 6, 32768, X'87df2d01b85d8354819b431bae0a0a65bfc5d2db'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 10, 21, 6, 16384, X'a25fef11c899d826ea61996f0bc05330bc88428eafb792be0182ad97b6283aae'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 10, 21, 6, 8192, X'357e5756dbfa22c21d3666521e644eefdf532b7d371cca62fc099579f3c98b97cb51d005dcbaf805f8a7def26dfde142'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 11, 7, 1, 32768, X'2d32ef93126abf8c660d57c67e5076c6394cabe8'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 11, 7, 1, 16384, X'ced29aca7fc2dd0b01d5d544dfb2e1640a6a79c657f589e7dd6636cfd63eda3b'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 11, 7, 1, 8192, X'a2d33fa2d0ee7bffa5e628f88ccb83cd61bb4c5fe6d2edb8b853b83d8c43f498fa6e8da70510f0a1a3ddb36060bbd4d8'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 11, 7, 7, 32768, X'2d32ef93126abf8c660d57c67e5076c6394cabe8'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 11, 7, 7, 16384, X'ced29aca7fc2dd0b01d5d544dfb2e1640a6a79c657f589e7dd6636cfd63eda3b'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 11, 7, 7, 8192, X'a2d33fa2d0ee7bffa5e628f88ccb83cd61bb4c5fe6d2edb8b853b83d8c43f498fa6e8da70510f0a1a3ddb36060bbd4d8'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 12, 7, 1, 32768, X'6c0b2df4fc4c9122b5762ae140d53fdd1cf9e89b'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 12, 7, 1, 16384, X'53c3f2bd5aaf8ef4c40f9af92a67621f5e67840b5ff2db67d1bccbcb56f7eef1'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 12, 7, 1, 8192, X'1a4a6d91bda3ce59e6c444ccc1e758c9c6f0e223fd8c5aac369260cdfa83081c0e8f3753f100490910ec161902f10ba7'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 12, 7, 7, 32768, X'6c0b2df4fc4c9122b5762ae140d53fdd1cf9e89b'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 12, 7, 7, 16384, X'53c3f2bd5aaf8ef4c40f9af92a67621f5e67840b5ff2db67d1bccbcb56f7eef1'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 12, 7, 7, 8192, X'1a4a6d91bda3ce59e6c444ccc1e758c9c6f0e223fd8c5aac369260cdfa83081c0e8f3753f100490910ec161902f10ba7'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 13, 7, 1, 32768, X'e2f7b92abda769f82796f57a29801870585dcea3'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 13, 7, 1, 16384, X'6d3fe67a040dbb469ef498b26cece45806cb7ca04787bba53b7ba1c18e2abd0a'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 13, 7, 1, 8192, X'014852b73cd3eabfa955b7bd56b269d5a0590a2770cf3d656b3d68dbad30884327fc81ff96c6f661c9c4189c3aefa346'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 13, 7, 7, 32768, X'e2f7b92abda769f82796f57a29801870585dcea3'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 13, 7, 7, 16384, X'6d3fe67a040dbb469ef498b26cece45806cb7ca04787bba53b7ba1c18e2abd0a'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 13, 7, 7, 8192, X'014852b73cd3eabfa955b7bd56b269d5a0590a2770cf3d656b3d68dbad30884327fc81ff96c6f661c9c4189c3aefa346'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 14, 7, 1, 32768, X'160d2b04d11eb225fb148615b699081869e15b6c'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 14, 7, 1, 16384, X'1f5a2ceae1418f9c1fbf51eb7d84f74d488908cde5931a5461746d1e24682a25'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 14, 7, 1, 8192, X'f701cb25b0e9a9f32d3bba9b274ca0e8838363d13b7283b842d6c9673442890e538127c3b64ca4b177de1d243b44cf0d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 14, 7, 7, 32768, X'160d2b04d11eb225fb148615b699081869e15b6c'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 14, 7, 7, 16384, X'1f5a2ceae1418f9c1fbf51eb7d84f74d488908cde5931a5461746d1e24682a25'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 14, 7, 7, 8192, X'f701cb25b0e9a9f32d3bba9b274ca0e8838363d13b7283b842d6c9673442890e538127c3b64ca4b177de1d243b44cf0d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 15, 7, 1, 32768, X'5a0d07ab036603a76759e5f61f7d04f2d3c056cc'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 15, 7, 1, 16384, X'85491714e860062c441ff50d93ad79350449596b89b2e409b513c2d883321c9d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 15, 7, 1, 8192, X'8038830a994c779bc200e844d8768280feca9dd5d58de6cd359b87cc68846799edfd16e36e83002da4bb309cfd3b353d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 15, 7, 7, 32768, X'5a0d07ab036603a76759e5f61f7d04f2d3c056cc'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 15, 7, 7, 16384, X'85491714e860062c441ff50d93ad79350449596b89b2e409b513c2d883321c9d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 15, 7, 7, 8192, X'8038830a994c779bc200e844d8768280feca9dd5d58de6cd359b87cc68846799edfd16e36e83002da4bb309cfd3b353d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 16, 7, 1, 32768, X'd6c8dfbaae7ab28b5cef2626a2af3f99a6ea4365'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 16, 7, 1, 16384, X'd0d6f784e937227cce99e3be860be078d0397a6fb5a5bc9d95a19ef855609dbc'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 16, 7, 1, 8192, X'4be6e7978a6e4fb8a792815f2bbe28c2e66276401fb98ca90e49a5c2f2c94a1c7aac635d501d35d1db0fd53a0cb9d0fa'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 16, 7, 7, 32768, X'd6c8dfbaae7ab28b5cef2626a2af3f99a6ea4365'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 16, 7, 7, 16384, X'd0d6f784e937227cce99e3be860be078d0397a6fb5a5bc9d95a19ef855609dbc'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 16, 7, 7, 8192, X'4be6e7978a6e4fb8a792815f2bbe28c2e66276401fb98ca90e49a5c2f2c94a1c7aac635d501d35d1db0fd53a0cb9d0fa'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 17, 1, 32768, X'8a7c41167bc0fcc1dec8329a868ba265c23857f5'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 17, 1, 16384, X'f8eb857d7bb850f44c15363ba699442c2810663ac5a83a5f49e06e0fd8144b0e'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 17, 1, 8192, X'f40cb6e557ab18d70080e7995e3f96cc272842e822bf52bc1c59075313c2cd832f96cf03a8524905f3d3f7a61441c651'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 17, 6, 32768, X'8178f18dcb836e7f7432c4ad568bfd66b7ef4a96'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 17, 6, 16384, X'2d6aaed577bfac626ff4958ee1076bc343f8db46538aa6c381521bac94c5ca9e'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 17, 6, 8192, X'747bbaee322f9bf1849308f8907e2a43868eae8559a7be718113abb4ce535f6d509d005e51788cf3e83e148487fe7bf3'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 17, 7, 32768, X'8a7c41167bc0fcc1dec8329a868ba265c23857f5'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 17, 7, 16384, X'f8eb857d7bb850f44c15363ba699442c2810663ac5a83a5f49e06e0fd8144b0e'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 17, 7, 8192, X'f40cb6e557ab18d70080e7995e3f96cc272842e822bf52bc1c59075313c2cd832f96cf03a8524905f3d3f7a61441c651'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 18, 7, 1, 32768, X'23296f48276e160b6d99b1b42a9114df720bb1ab'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 18, 7, 1, 16384, X'78cd0a598080e31453f477e8d8a12ec794e859f4076ed92e53d2053d6d16762c'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 18, 7, 1, 8192, X'4da3955f1fd968ecf95cff825d42715b544e577f28f411a020a270834235125bc0c8872bac8dd3466349ac8ab0aa2d74'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 18, 7, 7, 32768, X'23296f48276e160b6d99b1b42a9114df720bb1ab'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 18, 7, 7, 16384, X'78cd0a598080e31453f477e8d8a12ec794e859f4076ed92e53d2053d6d16762c'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 18, 7, 7, 8192, X'4da3955f1fd968ecf95cff825d42715b544e577f28f411a020a270834235125bc0c8872bac8dd3466349ac8ab0aa2d74'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 19, 7, 1, 32768, X'd537d437f058136eb3d7be517dbe7647b623c619'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 19, 7, 1, 16384, X'6a837037ad3fc4d06270d99cee2714dcf96b91aeb54d3483009219337961f834'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 19, 7, 1, 8192, X'7b5b16840da590a995fab23533f41982c5b136bff8e9b9a90b3c919a12cee20d312091455057a8bba9d9fbe314e6203d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 19, 7, 7, 32768, X'd537d437f058136eb3d7be517dbe7647b623c619'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 19, 7, 7, 16384, X'6a837037ad3fc4d06270d99cee2714dcf96b91aeb54d3483009219337961f834'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 19, 7, 7, 8192, X'7b5b16840da590a995fab23533f41982c5b136bff8e9b9a90b3c919a12cee20d312091455057a8bba9d9fbe314e6203d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 20, 7, 1, 32768, X'f9e3531abb67a020cf667d46ca823675dd0a0dd4'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 20, 7, 1, 16384, X'569bafa2dabbcfa0ba9c7c411eacfeb8930f9d856a1a43cf8aa3662a67c13e35'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 20, 7, 1, 8192, X'84200bd318bb022915150842ddf4002e061ef593604ad0d07021dc662cc40bfa749cce084ddf25d0e5137f6380f613d8'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 20, 7, 7, 32768, X'f9e3531abb67a020cf667d46ca823675dd0a0dd4'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 20, 7, 7, 16384, X'569bafa2dabbcfa0ba9c7c411eacfeb8930f9d856a1a43cf8aa3662a67c13e35'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 20, 7, 7, 8192, X'84200bd318bb022915150842ddf4002e061ef593604ad0d07021dc662cc40bfa749cce084ddf25d0e5137f6380f613d8'
+);
+
+/* AIKs */
+
+INSERT INTO keys (
+ keyid, owner
+) VALUES (
+ X'b772a6730776b9f028e5adfccd40b55c320a13b6', 'Andreas, merthyr (Fujitsu Siemens Lifebook S6420)'
+);
+
+/* Components */
+
+INSERT INTO components (
+ vendor_id, name, qualifier
+) VALUES (
+ 36906, 1, 33 /* ITA TGRUB */
+);
+
+INSERT INTO components (
+ vendor_id, name, qualifier
+) VALUES (
+ 36906, 2, 33 /* ITA TBOOT */
+);
+
+INSERT INTO components (
+ vendor_id, name, qualifier
+) VALUES (
+ 36906, 3, 33 /* ITA IMA */
+);
+
+/* AIK Component */
+
+INSERT INTO key_component (
+ key, component, depth, seq_no
+) VALUES (
+ 2, 2, 0, 1
+);
+
+INSERT INTO key_component (
+ key, component, depth, seq_no
+) VALUES (
+ 1, 3, 0, 1
+);
+
+INSERT INTO key_component (
+ key, component, depth, seq_no
+) VALUES (
+ 1, 2, 0, 2
+);
+
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation.c b/src/libpts/plugins/imv_attestation/imv_attestation.c
new file mode 100644
index 000000000..51069b02d
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/imv_attestation.c
@@ -0,0 +1,520 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "imv_attestation_state.h"
+#include "imv_attestation_process.h"
+#include "imv_attestation_build.h"
+
+#include <imv/imv_agent.h>
+#include <pa_tnc/pa_tnc_msg.h>
+#include <ietf/ietf_attr.h>
+#include <ietf/ietf_attr_pa_tnc_error.h>
+#include <ietf/ietf_attr_product_info.h>
+
+#include <libpts.h>
+
+#include <pts/pts.h>
+#include <pts/pts_database.h>
+#include <pts/pts_creds.h>
+
+#include <tcg/tcg_attr.h>
+
+#include <tncif_pa_subtypes.h>
+
+#include <pen/pen.h>
+#include <debug.h>
+#include <credentials/credential_manager.h>
+#include <utils/linked_list.h>
+
+/* IMV definitions */
+
+static const char imv_name[] = "Attestation";
+
+#define IMV_VENDOR_ID PEN_TCG
+#define IMV_SUBTYPE PA_SUBTYPE_TCG_PTS
+
+static imv_agent_t *imv_attestation;
+
+/**
+ * Supported PTS measurement algorithms
+ */
+static pts_meas_algorithms_t supported_algorithms = PTS_MEAS_ALGO_NONE;
+
+/**
+ * Supported PTS Diffie Hellman Groups
+ */
+static pts_dh_group_t supported_dh_groups = PTS_DH_GROUP_NONE;
+
+/**
+ * PTS file measurement database
+ */
+static pts_database_t *pts_db;
+
+/**
+ * PTS credentials
+ */
+static pts_creds_t *pts_creds;
+
+/**
+ * PTS credential manager
+ */
+static credential_manager_t *pts_credmgr;
+
+/**
+ * see section 3.8.1 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id,
+ TNC_Version min_version,
+ TNC_Version max_version,
+ TNC_Version *actual_version)
+{
+ char *hash_alg, *dh_group, *uri, *cadir;
+
+ if (imv_attestation)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has already been initialized", imv_name);
+ return TNC_RESULT_ALREADY_INITIALIZED;
+ }
+ if (!pts_meas_algo_probe(&supported_algorithms) ||
+ !pts_dh_group_probe(&supported_dh_groups))
+ {
+ return TNC_RESULT_FATAL;
+ }
+ imv_attestation = imv_agent_create(imv_name, IMV_VENDOR_ID, IMV_SUBTYPE,
+ imv_id, actual_version);
+ if (!imv_attestation)
+ {
+ return TNC_RESULT_FATAL;
+ }
+
+ libpts_init();
+
+ if (min_version > TNC_IFIMV_VERSION_1 || max_version < TNC_IFIMV_VERSION_1)
+ {
+ DBG1(DBG_IMV, "no common IF-IMV version");
+ return TNC_RESULT_NO_COMMON_VERSION;
+ }
+
+ hash_alg = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imv-attestation.hash_algorithm", "sha256");
+ dh_group = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imv-attestation.dh_group", "ecp256");
+
+ if (!pts_meas_algo_update(hash_alg, &supported_algorithms) ||
+ !pts_dh_group_update(dh_group, &supported_dh_groups))
+ {
+ return TNC_RESULT_FATAL;
+ }
+
+ /* create a PTS credential manager */
+ pts_credmgr = credential_manager_create();
+
+ /* create PTS credential set */
+ cadir = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imv-attestation.cadir", NULL);
+ pts_creds = pts_creds_create(cadir);
+ if (pts_creds)
+ {
+ pts_credmgr->add_set(pts_credmgr, pts_creds->get_set(pts_creds));
+ }
+
+ /* attach file measurement database */
+ uri = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imv-attestation.database", NULL);
+ pts_db = pts_database_create(uri);
+
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.2 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_ConnectionState new_state)
+{
+ imv_state_t *state;
+
+ if (!imv_attestation)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ switch (new_state)
+ {
+ case TNC_CONNECTION_STATE_CREATE:
+ state = imv_attestation_state_create(connection_id);
+ return imv_attestation->create_state(imv_attestation, state);
+ case TNC_CONNECTION_STATE_DELETE:
+ return imv_attestation->delete_state(imv_attestation, connection_id);
+ case TNC_CONNECTION_STATE_HANDSHAKE:
+ default:
+ return imv_attestation->change_state(imv_attestation, connection_id,
+ new_state, NULL);
+ }
+}
+
+static TNC_Result send_message(TNC_ConnectionID connection_id)
+{
+ pa_tnc_msg_t *msg;
+ pa_tnc_attr_t *attr;
+ imv_state_t *state;
+ imv_attestation_state_t *attestation_state;
+ TNC_Result result;
+ linked_list_t *attr_list;
+ enumerator_t *enumerator;
+
+ if (!imv_attestation->get_state(imv_attestation, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+ attestation_state = (imv_attestation_state_t*)state;
+ attr_list = linked_list_create();
+
+ if (imv_attestation_build(attr_list, attestation_state, supported_algorithms,
+ supported_dh_groups, pts_db))
+ {
+ if (attr_list->get_count(attr_list))
+ {
+ msg = pa_tnc_msg_create();
+
+ /* move PA-TNC attributes to PA-TNC message */
+ enumerator = attr_list->create_enumerator(attr_list);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ msg->add_attribute(msg, attr);
+ }
+ enumerator->destroy(enumerator);
+
+ msg->build(msg);
+ result = imv_attestation->send_message(imv_attestation,
+ connection_id, FALSE, 0, TNC_IMCID_ANY,
+ msg->get_encoding(msg));
+ msg->destroy(msg);
+ }
+ else
+ {
+ result = TNC_RESULT_SUCCESS;
+ }
+ attr_list->destroy(attr_list);
+ }
+ else
+ {
+ attr_list->destroy_offset(attr_list, offsetof(pa_tnc_attr_t, destroy));
+ result = TNC_RESULT_FATAL;
+ }
+
+ return result;
+}
+
+static TNC_Result receive_message(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ chunk_t msg,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id)
+{
+ pa_tnc_msg_t *pa_tnc_msg;
+ pa_tnc_attr_t *attr;
+ linked_list_t *attr_list;
+ imv_state_t *state;
+ imv_attestation_state_t *attestation_state;
+ pts_t *pts;
+ enumerator_t *enumerator;
+ TNC_Result result;
+
+ if (!imv_attestation)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+
+ /* get current IMV state */
+ if (!imv_attestation->get_state(imv_attestation, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+ attestation_state = (imv_attestation_state_t*)state;
+ pts = attestation_state->get_pts(attestation_state);
+
+ /* parse received PA-TNC message and automatically handle any errors */
+ result = imv_attestation->receive_message(imv_attestation, state, msg,
+ msg_vid, msg_subtype, src_imc_id, dst_imv_id, &pa_tnc_msg);
+
+ /* no parsed PA-TNC attributes available if an error occurred */
+ if (!pa_tnc_msg)
+ {
+ return result;
+ }
+
+ /* preprocess any IETF standard error attributes */
+ result = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg) ?
+ TNC_RESULT_FATAL : TNC_RESULT_SUCCESS;
+
+ attr_list = linked_list_create();
+
+ /* analyze PA-TNC attributes */
+ enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ if (attr->get_vendor_id(attr) == PEN_IETF)
+ {
+ if (attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR)
+ {
+ ietf_attr_pa_tnc_error_t *error_attr;
+ pen_t error_vendor_id;
+ pa_tnc_error_code_t error_code;
+ chunk_t msg_info;
+
+ error_attr = (ietf_attr_pa_tnc_error_t*)attr;
+ error_vendor_id = error_attr->get_vendor_id(error_attr);
+
+ if (error_vendor_id == PEN_TCG)
+ {
+ error_code = error_attr->get_error_code(error_attr);
+ msg_info = error_attr->get_msg_info(error_attr);
+
+ DBG1(DBG_IMV, "received TCG-PTS error '%N'",
+ pts_error_code_names, error_code);
+ DBG1(DBG_IMV, "error information: %B", &msg_info);
+
+ result = TNC_RESULT_FATAL;
+ }
+ }
+ else if (attr->get_type(attr) == IETF_ATTR_PRODUCT_INFORMATION)
+ {
+ ietf_attr_product_info_t *attr_cast;
+ char *platform_info;
+
+ attr_cast = (ietf_attr_product_info_t*)attr;
+ platform_info = attr_cast->get_info(attr_cast, NULL, NULL);
+ pts->set_platform_info(pts, platform_info);
+ }
+ }
+ else if (attr->get_vendor_id(attr) == PEN_TCG)
+ {
+ if (!imv_attestation_process(attr, attr_list, attestation_state,
+ supported_algorithms,supported_dh_groups, pts_db, pts_credmgr))
+ {
+ result = TNC_RESULT_FATAL;
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ pa_tnc_msg->destroy(pa_tnc_msg);
+
+ if (result != TNC_RESULT_SUCCESS)
+ {
+ attr_list->destroy_offset(attr_list, offsetof(pa_tnc_attr_t, destroy));
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
+ TNC_IMV_EVALUATION_RESULT_ERROR);
+ return imv_attestation->provide_recommendation(imv_attestation,
+ connection_id);
+ }
+
+ if (attr_list->get_count(attr_list))
+ {
+ pa_tnc_msg = pa_tnc_msg_create();
+
+ /* move PA-TNC attributes to PA-TNC message */
+ enumerator = attr_list->create_enumerator(attr_list);
+ while (enumerator->enumerate(enumerator, &attr))
+ {
+ pa_tnc_msg->add_attribute(pa_tnc_msg, attr);
+ }
+ enumerator->destroy(enumerator);
+
+ pa_tnc_msg->build(pa_tnc_msg);
+ result = imv_attestation->send_message(imv_attestation, connection_id,
+ FALSE, 0, TNC_IMCID_ANY,
+ pa_tnc_msg->get_encoding(pa_tnc_msg));
+
+ pa_tnc_msg->destroy(pa_tnc_msg);
+ attr_list->destroy(attr_list);
+
+ return result;
+ }
+ attr_list->destroy(attr_list);
+
+ /* check the IMV state for the next PA-TNC attributes to send */
+ result = send_message(connection_id);
+ if (result != TNC_RESULT_SUCCESS)
+ {
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
+ TNC_IMV_EVALUATION_RESULT_ERROR);
+ return imv_attestation->provide_recommendation(imv_attestation,
+ connection_id);
+ }
+
+ if (attestation_state->get_handshake_state(attestation_state) ==
+ IMV_ATTESTATION_STATE_END)
+ {
+ if (attestation_state->get_file_meas_request_count(attestation_state))
+ {
+ DBG1(DBG_IMV, "failure due to %d pending file measurements",
+ attestation_state->get_file_meas_request_count(attestation_state));
+ attestation_state->set_measurement_error(attestation_state);
+ }
+ if (attestation_state->get_component_count(attestation_state))
+ {
+ DBG1(DBG_IMV, "failure due to %d components waiting for evidence",
+ attestation_state->get_component_count(attestation_state));
+ attestation_state->set_measurement_error(attestation_state);
+ }
+ if (attestation_state->get_measurement_error(attestation_state))
+ {
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
+ TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR);
+ }
+ else
+ {
+ state->set_recommendation(state,
+ TNC_IMV_ACTION_RECOMMENDATION_ALLOW,
+ TNC_IMV_EVALUATION_RESULT_COMPLIANT);
+ }
+ return imv_attestation->provide_recommendation(imv_attestation,
+ connection_id);
+ }
+
+ return result;
+}
+
+/**
+ * see section 3.8.4 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_MessageType msg_type)
+{
+ TNC_VendorID msg_vid;
+ TNC_MessageSubtype msg_subtype;
+
+ msg_vid = msg_type >> 8;
+ msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+
+ return receive_message(imv_id, connection_id, 0, chunk_create(msg, msg_len),
+ msg_vid, msg_subtype, 0, TNC_IMVID_ANY);
+}
+
+/**
+ * see section 3.8.6 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_ReceiveMessageLong(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id)
+{
+ return receive_message(imv_id, connection_id, msg_flags,
+ chunk_create(msg, msg_len), msg_vid, msg_subtype,
+ src_imc_id, dst_imv_id);
+}
+
+/**
+ * see section 3.8.7 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_SolicitRecommendation(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id)
+{
+ if (!imv_attestation)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return imv_attestation->provide_recommendation(imv_attestation,
+ connection_id);
+}
+
+/**
+ * see section 3.8.8 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_BatchEnding(TNC_IMVID imv_id,
+ TNC_ConnectionID connection_id)
+{
+ imv_state_t *state;
+ imv_attestation_state_t *attestation_state;
+
+ if (!imv_attestation)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ /* get current IMV state */
+ if (!imv_attestation->get_state(imv_attestation, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+ attestation_state = (imv_attestation_state_t*)state;
+
+ /* Check if IMV has to initiate the PA-TNC exchange */
+ if (attestation_state->get_handshake_state(attestation_state) ==
+ IMV_ATTESTATION_STATE_INIT)
+ {
+ return send_message(connection_id);
+ }
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 3.8.9 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_Terminate(TNC_IMVID imv_id)
+{
+ if (!imv_attestation)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ if (pts_creds)
+ {
+ pts_credmgr->remove_set(pts_credmgr, pts_creds->get_set(pts_creds));
+ pts_creds->destroy(pts_creds);
+ }
+ DESTROY_IF(pts_db);
+ DESTROY_IF(pts_credmgr);
+
+ libpts_deinit();
+
+ imv_attestation->destroy(imv_attestation);
+ imv_attestation = NULL;
+
+ return TNC_RESULT_SUCCESS;
+}
+
+/**
+ * see section 4.2.8.1 of TCG TNC IF-IMV Specification 1.3
+ */
+TNC_Result TNC_IMV_ProvideBindFunction(TNC_IMVID imv_id,
+ TNC_TNCS_BindFunctionPointer bind_function)
+{
+ if (!imv_attestation)
+ {
+ DBG1(DBG_IMV, "IMV \"%s\" has not been initialized", imv_name);
+ return TNC_RESULT_NOT_INITIALIZED;
+ }
+ return imv_attestation->bind_functions(imv_attestation, bind_function);
+}
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_build.c b/src/libpts/plugins/imv_attestation/imv_attestation_build.c
new file mode 100644
index 000000000..4f2cc1e95
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_build.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "imv_attestation_build.h"
+#include "imv_attestation_state.h"
+
+#include <libpts.h>
+#include <tcg/tcg_pts_attr_proto_caps.h>
+#include <tcg/tcg_pts_attr_meas_algo.h>
+#include <tcg/tcg_pts_attr_dh_nonce_params_req.h>
+#include <tcg/tcg_pts_attr_dh_nonce_finish.h>
+#include <tcg/tcg_pts_attr_get_tpm_version_info.h>
+#include <tcg/tcg_pts_attr_get_aik.h>
+#include <tcg/tcg_pts_attr_req_func_comp_evid.h>
+#include <tcg/tcg_pts_attr_gen_attest_evid.h>
+#include <tcg/tcg_pts_attr_req_file_meas.h>
+#include <tcg/tcg_pts_attr_req_file_meta.h>
+
+#include <debug.h>
+
+bool imv_attestation_build(linked_list_t *attr_list,
+ imv_attestation_state_t *attestation_state,
+ pts_meas_algorithms_t supported_algorithms,
+ pts_dh_group_t supported_dh_groups,
+ pts_database_t *pts_db)
+{
+ imv_attestation_handshake_state_t handshake_state;
+ pts_t *pts;
+ pa_tnc_attr_t *attr = NULL;
+
+ handshake_state = attestation_state->get_handshake_state(attestation_state);
+ pts = attestation_state->get_pts(attestation_state);
+
+ /**
+ * Skip DH Nonce Parameters Request attribute when
+ * DH Nonce Exchange is not selected by PTS-IMC side
+ */
+ if (handshake_state == IMV_ATTESTATION_STATE_NONCE_REQ &&
+ !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
+ {
+ DBG2(DBG_IMV, "PTS-IMC does not support DH Nonce negotiation - "
+ "advancing to TPM Initialization");
+ handshake_state = IMV_ATTESTATION_STATE_TPM_INIT;
+ }
+
+ /**
+ * Skip TPM Version Info and AIK attributes when
+ * no TPM is available on the PTS-IMC side
+ */
+ if (handshake_state == IMV_ATTESTATION_STATE_TPM_INIT &&
+ !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T))
+ {
+ DBG2(DBG_IMV, "PTS-IMC made no TPM available - "
+ "advancing to File Measurements");
+ handshake_state = IMV_ATTESTATION_STATE_MEAS;
+ }
+
+ switch (handshake_state)
+ {
+ case IMV_ATTESTATION_STATE_INIT:
+ {
+ pts_proto_caps_flag_t flags;
+
+ /* Send Request Protocol Capabilities attribute */
+ flags = pts->get_proto_caps(pts);
+ attr = tcg_pts_attr_proto_caps_create(flags, TRUE);
+ attr->set_noskip_flag(attr, TRUE);
+ attr_list->insert_last(attr_list, attr);
+
+ /* Send Measurement Algorithms attribute */
+ attr = tcg_pts_attr_meas_algo_create(supported_algorithms, FALSE);
+ attr->set_noskip_flag(attr, TRUE);
+ attr_list->insert_last(attr_list, attr);
+
+ attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_NONCE_REQ);
+ break;
+ }
+ case IMV_ATTESTATION_STATE_NONCE_REQ:
+ {
+ int min_nonce_len;
+
+ /* Send DH nonce parameters request attribute */
+ min_nonce_len = lib->settings->get_int(lib->settings,
+ "libimcv.plugins.imv-attestation.min_nonce_len", 0);
+ attr = tcg_pts_attr_dh_nonce_params_req_create(min_nonce_len,
+ supported_dh_groups);
+ attr->set_noskip_flag(attr, TRUE);
+ attr_list->insert_last(attr_list, attr);
+
+ attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_TPM_INIT);
+ break;
+ }
+ case IMV_ATTESTATION_STATE_TPM_INIT:
+ {
+ pts_meas_algorithms_t selected_algorithm;
+ chunk_t initiator_value, initiator_nonce;
+
+ if ((pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
+ {
+ /* Send DH nonce finish attribute */
+ selected_algorithm = pts->get_meas_algorithm(pts);
+ pts->get_my_public_value(pts, &initiator_value, &initiator_nonce);
+ attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm,
+ initiator_value, initiator_nonce);
+ attr->set_noskip_flag(attr, TRUE);
+ attr_list->insert_last(attr_list, attr);
+ }
+
+ /* Send Get TPM Version attribute */
+ attr = tcg_pts_attr_get_tpm_version_info_create();
+ attr->set_noskip_flag(attr, TRUE);
+ attr_list->insert_last(attr_list, attr);
+
+ /* Send Get AIK attribute */
+ attr = tcg_pts_attr_get_aik_create();
+ attr->set_noskip_flag(attr, TRUE);
+ attr_list->insert_last(attr_list, attr);
+
+ attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_MEAS);
+ break;
+ }
+ case IMV_ATTESTATION_STATE_MEAS:
+ {
+ enumerator_t *enumerator;
+ u_int32_t delimiter = SOLIDUS_UTF;
+ char *platform_info, *pathname;
+ u_int16_t request_id;
+ int id, type;
+ bool is_dir;
+
+ attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_COMP_EVID);
+
+ /* Get Platform and OS of the PTS-IMC */
+ platform_info = pts->get_platform_info(pts);
+
+ if (!pts_db || !platform_info)
+ {
+ DBG1(DBG_IMV, "%s%s%s not available",
+ (pts_db) ? "" : "pts database",
+ (!pts_db && !platform_info) ? "and" : "",
+ (platform_info) ? "" : "platform info");
+ break;
+ }
+ DBG1(DBG_IMV, "platform is '%s'", platform_info);
+
+ /* Send Request File Metadata attribute */
+ enumerator = pts_db->create_file_meta_enumerator(pts_db,
+ platform_info);
+ if (!enumerator)
+ {
+ break;
+ }
+ while (enumerator->enumerate(enumerator, &type, &pathname))
+ {
+ is_dir = (type != 0);
+ DBG2(DBG_IMV, "metadata request for %s '%s'",
+ is_dir ? "directory" : "file", pathname);
+ attr = tcg_pts_attr_req_file_meta_create(is_dir, delimiter,
+ pathname);
+ attr->set_noskip_flag(attr, TRUE);
+ attr_list->insert_last(attr_list, attr);
+ }
+ enumerator->destroy(enumerator);
+
+ /* Send Request File Measurement attribute */
+ enumerator = pts_db->create_file_meas_enumerator(pts_db,
+ platform_info);
+ if (!enumerator)
+ {
+ break;
+ }
+ while (enumerator->enumerate(enumerator, &id, &type, &pathname))
+ {
+ is_dir = (type != 0);
+ request_id = attestation_state->add_file_meas_request(
+ attestation_state, id, is_dir);
+ DBG2(DBG_IMV, "measurement request %d for %s '%s'",
+ request_id, is_dir ? "directory" : "file", pathname);
+ attr = tcg_pts_attr_req_file_meas_create(is_dir, request_id,
+ delimiter, pathname);
+ attr->set_noskip_flag(attr, TRUE);
+ attr_list->insert_last(attr_list, attr);
+ }
+ enumerator->destroy(enumerator);
+ break;
+ }
+ case IMV_ATTESTATION_STATE_COMP_EVID:
+ {
+ tcg_pts_attr_req_func_comp_evid_t *attr_cast;
+ enumerator_t *enumerator;
+ pts_component_t *comp;
+ pts_comp_func_name_t *comp_name;
+ chunk_t keyid;
+ int kid, vid, name, qualifier;
+ u_int8_t flags;
+ u_int32_t depth;
+ bool first = TRUE, first_component = TRUE;
+
+ attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_END);
+
+ if (!(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T) ||
+ !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_D))
+ {
+ DBG2(DBG_IMV, "PTS-IMC made no TPM available - "
+ "skipping Component Measurements");
+ break;
+ }
+ if (!pts->get_aik_keyid(pts, &keyid))
+ {
+ DBG1(DBG_IMV, "retrieval of AIK keyid failed");
+ return FALSE;
+ }
+ if (!pts_db)
+ {
+ DBG1(DBG_IMV, "pts database not available");
+ break;
+ }
+ if (pts_db->check_aik_keyid(pts_db, keyid, &kid) != SUCCESS)
+ {
+ return FALSE;
+ }
+ enumerator = pts_db->create_comp_evid_enumerator(pts_db, kid);
+ if (!enumerator)
+ {
+ break;
+ }
+ while (enumerator->enumerate(enumerator, &vid, &name,
+ &qualifier, &depth))
+ {
+ if (first)
+ {
+ DBG2(DBG_IMV, "evidence request by");
+ first = FALSE;
+ }
+ comp_name = pts_comp_func_name_create(vid, name, qualifier);
+ comp_name->log(comp_name, " ");
+
+ comp = pts_components->create(pts_components, comp_name,
+ depth, pts_db);
+ if (!comp)
+ {
+ DBG2(DBG_IMV, " not registered: removed from request");
+ comp_name->destroy(comp_name);
+ continue;
+ }
+ attestation_state->add_component(attestation_state, comp);
+ if (first_component)
+ {
+ attr = tcg_pts_attr_req_func_comp_evid_create();
+ attr->set_noskip_flag(attr, TRUE);
+ first_component = FALSE;
+ }
+ flags = comp->get_evidence_flags(comp);
+ /* TODO check flags against negotiated_caps */
+ attr_cast = (tcg_pts_attr_req_func_comp_evid_t *)attr;
+ attr_cast->add_component(attr_cast, flags, depth, comp_name);
+ }
+ enumerator->destroy(enumerator);
+
+ if (attr)
+ {
+ /* Send Request Functional Component Evidence attribute */
+ attr_list->insert_last(attr_list, attr);
+
+ /* Send Generate Attestation Evidence attribute */
+ attr = tcg_pts_attr_gen_attest_evid_create();
+ attr->set_noskip_flag(attr, TRUE);
+ attr_list->insert_last(attr_list, attr);
+
+ attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_EVID_FINAL);
+ }
+ break;
+ }
+ case IMV_ATTESTATION_STATE_EVID_FINAL:
+ attestation_state->set_handshake_state(attestation_state,
+ IMV_ATTESTATION_STATE_END);
+ break;
+ case IMV_ATTESTATION_STATE_END:
+ break;
+ }
+ return TRUE;
+}
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_build.h b/src/libpts/plugins/imv_attestation/imv_attestation_build.h
new file mode 100644
index 000000000..7f934fd09
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_build.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 imv_attestation_build_t imv_attestation_build
+ * @{ @ingroup imv_attestation_build
+ */
+
+#ifndef IMV_ATTESTATION_BUILD_H_
+#define IMV_ATTESTATION_BUILD_H_
+
+#include "imv_attestation_state.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <library.h>
+
+#include <pts/pts_database.h>
+#include <pts/pts_dh_group.h>
+#include <pts/pts_meas_algo.h>
+
+/**
+ * Process a TCG PTS attribute
+ *
+ * @param attr_list list of PA-TNC attriubutes to be built
+ * @param attestation_state attestation state of a given connection
+ * @param supported_algorithms supported PTS measurement algorithms
+ * @param supported_dh_groups supported DH groups
+ * @param pts_db PTS configuration database
+ * @return TRUE if successful
+ */
+bool imv_attestation_build(linked_list_t *attr_list,
+ imv_attestation_state_t *attestation_state,
+ pts_meas_algorithms_t supported_algorithms,
+ pts_dh_group_t supported_dh_groups,
+ pts_database_t *pts_db);
+
+#endif /** IMV_ATTESTATION_BUILD_H_ @}*/
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_process.c b/src/libpts/plugins/imv_attestation/imv_attestation_process.c
new file mode 100644
index 000000000..a742b6697
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_process.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "imv_attestation_process.h"
+
+#include <ietf/ietf_attr_pa_tnc_error.h>
+
+#include <pts/pts.h>
+
+#include <tcg/tcg_pts_attr_aik.h>
+#include <tcg/tcg_pts_attr_dh_nonce_params_resp.h>
+#include <tcg/tcg_pts_attr_file_meas.h>
+#include <tcg/tcg_pts_attr_meas_algo.h>
+#include <tcg/tcg_pts_attr_proto_caps.h>
+#include <tcg/tcg_pts_attr_simple_comp_evid.h>
+#include <tcg/tcg_pts_attr_simple_evid_final.h>
+#include <tcg/tcg_pts_attr_tpm_version_info.h>
+#include <tcg/tcg_pts_attr_unix_file_meta.h>
+
+#include <debug.h>
+#include <crypto/hashers/hasher.h>
+
+#include <inttypes.h>
+
+bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
+ imv_attestation_state_t *attestation_state,
+ pts_meas_algorithms_t supported_algorithms,
+ pts_dh_group_t supported_dh_groups,
+ pts_database_t *pts_db,
+ credential_manager_t *pts_credmgr)
+{
+ pts_t *pts;
+
+ pts = attestation_state->get_pts(attestation_state);
+
+ switch (attr->get_type(attr))
+ {
+ case TCG_PTS_PROTO_CAPS:
+ {
+ tcg_pts_attr_proto_caps_t *attr_cast;
+ pts_proto_caps_flag_t flags;
+
+ attr_cast = (tcg_pts_attr_proto_caps_t*)attr;
+ flags = attr_cast->get_flags(attr_cast);
+ pts->set_proto_caps(pts, flags);
+ break;
+ }
+ case TCG_PTS_MEAS_ALGO_SELECTION:
+ {
+ tcg_pts_attr_meas_algo_t *attr_cast;
+ pts_meas_algorithms_t selected_algorithm;
+
+ attr_cast = (tcg_pts_attr_meas_algo_t*)attr;
+ selected_algorithm = attr_cast->get_algorithms(attr_cast);
+ if (!(selected_algorithm & supported_algorithms))
+ {
+ DBG1(DBG_IMV, "PTS-IMC selected unsupported"
+ " measurement algorithm");
+ return FALSE;
+ }
+ pts->set_meas_algorithm(pts, selected_algorithm);
+ break;
+ }
+ case TCG_PTS_DH_NONCE_PARAMS_RESP:
+ {
+ tcg_pts_attr_dh_nonce_params_resp_t *attr_cast;
+ int nonce_len, min_nonce_len;
+ pts_dh_group_t dh_group;
+ pts_meas_algorithms_t offered_algorithms, selected_algorithm;
+ chunk_t responder_value, responder_nonce;
+
+ attr_cast = (tcg_pts_attr_dh_nonce_params_resp_t*)attr;
+ responder_nonce = attr_cast->get_responder_nonce(attr_cast);
+
+ /* check compliance of responder nonce length */
+ min_nonce_len = lib->settings->get_int(lib->settings,
+ "libimcv.plugins.imv-attestation.min_nonce_len", 0);
+ nonce_len = responder_nonce.len;
+ if (nonce_len < PTS_MIN_NONCE_LEN ||
+ (min_nonce_len > 0 && nonce_len < min_nonce_len))
+ {
+ attr = pts_dh_nonce_error_create(
+ max(PTS_MIN_NONCE_LEN, min_nonce_len),
+ PTS_MAX_NONCE_LEN);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+
+ dh_group = attr_cast->get_dh_group(attr_cast);
+ if (!(dh_group & supported_dh_groups))
+ {
+ DBG1(DBG_IMV, "PTS-IMC selected unsupported DH group");
+ return FALSE;
+ }
+
+ offered_algorithms = attr_cast->get_hash_algo_set(attr_cast);
+ selected_algorithm = pts_meas_algo_select(supported_algorithms,
+ offered_algorithms);
+ if (selected_algorithm == PTS_MEAS_ALGO_NONE)
+ {
+ attr = pts_hash_alg_error_create(supported_algorithms);
+ attr_list->insert_last(attr_list, attr);
+ break;
+ }
+ pts->set_dh_hash_algorithm(pts, selected_algorithm);
+
+ if (!pts->create_dh_nonce(pts, dh_group, nonce_len))
+ {
+ return FALSE;
+ }
+
+ responder_value = attr_cast->get_responder_value(attr_cast);
+ pts->set_peer_public_value(pts, responder_value,
+ responder_nonce);
+
+ /* Calculate secret assessment value */
+ if (!pts->calculate_secret(pts))
+ {
+ return FALSE;
+ }
+ break;
+ }
+ case TCG_PTS_TPM_VERSION_INFO:
+ {
+ tcg_pts_attr_tpm_version_info_t *attr_cast;
+ chunk_t tpm_version_info;
+
+ attr_cast = (tcg_pts_attr_tpm_version_info_t*)attr;
+ tpm_version_info = attr_cast->get_tpm_version_info(attr_cast);
+ pts->set_tpm_version_info(pts, tpm_version_info);
+ break;
+ }
+ case TCG_PTS_AIK:
+ {
+ tcg_pts_attr_aik_t *attr_cast;
+ certificate_t *aik, *issuer;
+ public_key_t *public;
+ chunk_t keyid;
+ enumerator_t *e;
+ bool trusted = FALSE;
+
+ attr_cast = (tcg_pts_attr_aik_t*)attr;
+ aik = attr_cast->get_aik(attr_cast);
+ if (!aik)
+ {
+ DBG1(DBG_IMV, "AIK unavailable");
+ return FALSE;
+ }
+ if (aik->get_type(aik) == CERT_X509)
+ {
+ public = aik->get_public_key(aik);
+ public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid);
+ DBG1(DBG_IMV, "verifying AIK certificate with keyid %#B", &keyid);
+ public->destroy(public);
+
+ e = pts_credmgr->create_trusted_enumerator(pts_credmgr,
+ KEY_ANY, aik->get_issuer(aik), FALSE);
+ while (e->enumerate(e, &issuer))
+ {
+ if (aik->issued_by(aik, issuer))
+ {
+ trusted = TRUE;
+ break;
+ }
+ }
+ e->destroy(e);
+ DBG1(DBG_IMV, "AIK certificate is %strusted",
+ trusted ? "" : "not ");
+ if (!trusted)
+ {
+ return FALSE;
+ }
+ }
+ pts->set_aik(pts, aik);
+ break;
+ }
+ case TCG_PTS_FILE_MEAS:
+ {
+ tcg_pts_attr_file_meas_t *attr_cast;
+ u_int16_t request_id;
+ int file_count, file_id;
+ pts_meas_algorithms_t algo;
+ pts_file_meas_t *measurements;
+ char *platform_info;
+ enumerator_t *e_hash;
+ bool is_dir;
+
+ platform_info = pts->get_platform_info(pts);
+ if (!pts_db || !platform_info)
+ {
+ DBG1(DBG_IMV, "%s%s%s not available",
+ (pts_db) ? "" : "pts database",
+ (!pts_db && !platform_info) ? "and" : "",
+ (platform_info) ? "" : "platform info");
+ break;
+ }
+
+ attr_cast = (tcg_pts_attr_file_meas_t*)attr;
+ measurements = attr_cast->get_measurements(attr_cast);
+ algo = pts->get_meas_algorithm(pts);
+ request_id = measurements->get_request_id(measurements);
+ file_count = measurements->get_file_count(measurements);
+
+ DBG1(DBG_IMV, "measurement request %d returned %d file%s:",
+ request_id, file_count, (file_count == 1) ? "":"s");
+
+ if (!attestation_state->check_off_file_meas_request(attestation_state,
+ request_id, &file_id, &is_dir))
+ {
+ DBG1(DBG_IMV, " no entry found for file measurement request %d",
+ request_id);
+ break;
+ }
+
+ /* check hashes from database against measurements */
+ e_hash = pts_db->create_file_hash_enumerator(pts_db,
+ platform_info, algo, file_id, is_dir);
+ if (!measurements->verify(measurements, e_hash, is_dir))
+ {
+ attestation_state->set_measurement_error(attestation_state);
+ }
+ e_hash->destroy(e_hash);
+ break;
+ }
+ case TCG_PTS_UNIX_FILE_META:
+ {
+ tcg_pts_attr_file_meta_t *attr_cast;
+ int file_count;
+ pts_file_meta_t *metadata;
+ pts_file_metadata_t *entry;
+ time_t created, modified, accessed;
+ bool utc = FALSE;
+ enumerator_t *e;
+
+ attr_cast = (tcg_pts_attr_file_meta_t*)attr;
+ metadata = attr_cast->get_metadata(attr_cast);
+ file_count = metadata->get_file_count(metadata);
+
+ DBG1(DBG_IMV, "metadata request returned %d file%s:",
+ file_count, (file_count == 1) ? "":"s");
+
+ e = metadata->create_enumerator(metadata);
+ while (e->enumerate(e, &entry))
+ {
+ DBG1(DBG_IMV, " '%s' (%"PRIu64" bytes)"
+ " owner %"PRIu64", group %"PRIu64", type %N",
+ entry->filename, entry->filesize, entry->owner,
+ entry->group, pts_file_type_names, entry->type);
+
+ created = entry->created;
+ modified = entry->modified;
+ accessed = entry->accessed;
+
+ DBG1(DBG_IMV, " created %T, modified %T, accessed %T",
+ &created, utc, &modified, utc, &accessed, utc);
+ }
+ e->destroy(e);
+ break;
+ }
+ case TCG_PTS_SIMPLE_COMP_EVID:
+ {
+ tcg_pts_attr_simple_comp_evid_t *attr_cast;
+ pts_comp_func_name_t *name;
+ pts_comp_evidence_t *evidence;
+ pts_component_t *comp;
+ u_int32_t depth;
+ status_t status;
+
+ attr_cast = (tcg_pts_attr_simple_comp_evid_t*)attr;
+ evidence = attr_cast->get_comp_evidence(attr_cast);
+ name = evidence->get_comp_func_name(evidence, &depth);
+
+ comp = attestation_state->check_off_component(attestation_state, name);
+ if (!comp)
+ {
+ DBG1(DBG_IMV, " no entry found for component evidence request");
+ break;
+ }
+ status = comp->verify(comp, pts, evidence);
+
+ switch (status)
+ {
+ default:
+ case FAILED:
+ attestation_state->set_measurement_error(attestation_state);
+ comp->destroy(comp);
+ break;
+ case SUCCESS:
+ name->log(name, " successfully measured ");
+ comp->destroy(comp);
+ break;
+ case NEED_MORE:
+ /* re-enter component into list */
+ attestation_state->add_component(attestation_state, comp);
+ }
+ break;
+ }
+ case TCG_PTS_SIMPLE_EVID_FINAL:
+ {
+ tcg_pts_attr_simple_evid_final_t *attr_cast;
+ u_int8_t flags;
+ pts_meas_algorithms_t comp_hash_algorithm;
+ chunk_t pcr_comp, tpm_quote_sig, evid_sig;
+ chunk_t pcr_composite, quote_info;
+ bool use_quote2, use_ver_info;
+
+ attr_cast = (tcg_pts_attr_simple_evid_final_t*)attr;
+ flags = attr_cast->get_quote_info(attr_cast, &comp_hash_algorithm,
+ &pcr_comp, &tpm_quote_sig);
+
+ if (flags != PTS_SIMPLE_EVID_FINAL_NO)
+ {
+ use_quote2 = (flags == PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2 ||
+ flags == PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2_CAP_VER);
+ use_ver_info = (flags == PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2_CAP_VER);
+
+ /* Construct PCR Composite and TPM Quote Info structures */
+ if (!pts->get_quote_info(pts, use_quote2, use_ver_info,
+ comp_hash_algorithm, &pcr_composite, &quote_info))
+ {
+ DBG1(DBG_IMV, "unable to construct TPM Quote Info");
+ return FALSE;
+ }
+
+ if (!chunk_equals(pcr_comp, pcr_composite))
+ {
+ DBG1(DBG_IMV, "received PCR Composite does not match "
+ "constructed one");
+ free(pcr_composite.ptr);
+ free(quote_info.ptr);
+ return FALSE;
+ }
+ DBG2(DBG_IMV, "received PCR Composite matches constructed one");
+ free(pcr_composite.ptr);
+
+ if (!pts->verify_quote_signature(pts, quote_info, tpm_quote_sig))
+ {
+ free(quote_info.ptr);
+ return FALSE;
+ }
+ DBG2(DBG_IMV, "TPM Quote Info signature verification successful");
+ free(quote_info.ptr);
+
+ /* Finalize any pending measurement registrations */
+ attestation_state->check_off_registrations(attestation_state);
+ }
+
+ if (attr_cast->get_evid_sig(attr_cast, &evid_sig))
+ {
+ /** TODO: What to do with Evidence Signature */
+ DBG1(DBG_IMV, "this version of the Attestation IMV can not "
+ "handle Evidence Signatures");
+ }
+ break;
+ }
+
+ /* TODO: Not implemented yet */
+ case TCG_PTS_INTEG_MEAS_LOG:
+ /* Attributes using XML */
+ case TCG_PTS_TEMPL_REF_MANI_SET_META:
+ case TCG_PTS_VERIFICATION_RESULT:
+ case TCG_PTS_INTEG_REPORT:
+ /* On Windows only*/
+ case TCG_PTS_WIN_FILE_META:
+ case TCG_PTS_REGISTRY_VALUE:
+ /* Received on IMC side only*/
+ case TCG_PTS_REQ_PROTO_CAPS:
+ case TCG_PTS_DH_NONCE_PARAMS_REQ:
+ case TCG_PTS_DH_NONCE_FINISH:
+ case TCG_PTS_MEAS_ALGO:
+ case TCG_PTS_GET_TPM_VERSION_INFO:
+ case TCG_PTS_REQ_TEMPL_REF_MANI_SET_META:
+ case TCG_PTS_UPDATE_TEMPL_REF_MANI:
+ case TCG_PTS_GET_AIK:
+ case TCG_PTS_REQ_FUNC_COMP_EVID:
+ case TCG_PTS_GEN_ATTEST_EVID:
+ case TCG_PTS_REQ_FILE_META:
+ case TCG_PTS_REQ_FILE_MEAS:
+ case TCG_PTS_REQ_INTEG_MEAS_LOG:
+ default:
+ DBG1(DBG_IMV, "received unsupported attribute '%N'",
+ tcg_attr_names, attr->get_type(attr));
+ break;
+ }
+ return TRUE;
+}
+
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_process.h b/src/libpts/plugins/imv_attestation/imv_attestation_process.h
new file mode 100644
index 000000000..4d4eeefbb
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_process.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 imv_attestation_process_t imv_attestation_process
+ * @{ @ingroup imv_attestation_process
+ */
+
+#ifndef IMV_ATTESTATION_PROCESS_H_
+#define IMV_ATTESTATION_PROCESS_H_
+
+#include "imv_attestation_state.h"
+
+#include <library.h>
+#include <utils/linked_list.h>
+#include <credentials/credential_manager.h>
+#include <crypto/hashers/hasher.h>
+
+#include <pa_tnc/pa_tnc_attr.h>
+
+#include <pts/pts_database.h>
+#include <pts/pts_dh_group.h>
+#include <pts/pts_meas_algo.h>
+
+/**
+ * Process a TCG PTS attribute
+ *
+ * @param attr PA-TNC attribute to be processed
+ * @param attr_list list with PA-TNC error attributes
+ * @param attestation_state attestation state of a given connection
+ * @param supported_algorithms supported PTS measurement algorithms
+ * @param supported_dh_groups supported DH groups
+ * @param pts_db PTS configuration database
+ * @param pts_credmgr PTS credential manager
+ * @return TRUE if successful
+ */
+bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
+ imv_attestation_state_t *attestation_state,
+ pts_meas_algorithms_t supported_algorithms,
+ pts_dh_group_t supported_dh_groups,
+ pts_database_t *pts_db,
+ credential_manager_t *pts_credmgr);
+
+#endif /** IMV_ATTESTATION_PROCESS_H_ @}*/
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_state.c b/src/libpts/plugins/imv_attestation/imv_attestation_state.c
new file mode 100644
index 000000000..a58fd3ec3
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_state.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "imv_attestation_state.h"
+
+#include <utils/lexparser.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_imv_attestation_state_t private_imv_attestation_state_t;
+typedef struct file_meas_request_t file_meas_request_t;
+
+/**
+ * PTS File/Directory Measurement request entry
+ */
+struct file_meas_request_t {
+ u_int16_t id;
+ int file_id;
+ bool is_dir;
+};
+
+/**
+ * Private data of an imv_attestation_state_t object.
+ */
+struct private_imv_attestation_state_t {
+
+ /**
+ * Public members of imv_attestation_state_t
+ */
+ imv_attestation_state_t public;
+
+ /**
+ * TNCCS connection ID
+ */
+ TNC_ConnectionID connection_id;
+
+ /**
+ * TNCCS connection state
+ */
+ TNC_ConnectionState state;
+
+ /**
+ * Does the TNCCS connection support long message types?
+ */
+ bool has_long;
+
+ /**
+ * Does the TNCCS connection support exclusive delivery?
+ */
+ bool has_excl;
+
+ /**
+ * IMV Attestation handshake state
+ */
+ imv_attestation_handshake_state_t handshake_state;
+
+ /**
+ * IMV action recommendation
+ */
+ TNC_IMV_Action_Recommendation rec;
+
+ /**
+ * IMV evaluation result
+ */
+ TNC_IMV_Evaluation_Result eval;
+
+ /**
+ * File Measurement Request counter
+ */
+ u_int16_t file_meas_request_counter;
+
+ /**
+ * List of PTS File/Directory Measurement requests
+ */
+ linked_list_t *file_meas_requests;
+
+ /**
+ * List of Functional Components
+ */
+ linked_list_t *components;
+
+ /**
+ * PTS object
+ */
+ pts_t *pts;
+
+ /**
+ * Measurement error
+ */
+ bool measurement_error;
+
+};
+
+typedef struct entry_t entry_t;
+
+/**
+ * Define an internal reason string entry
+ */
+struct entry_t {
+ char *lang;
+ char *string;
+};
+
+/**
+ * Table of multi-lingual reason string entries
+ */
+static entry_t reasons[] = {
+ { "en", "IMV Attestation: Incorrect/pending file measurement/component"
+ " evidence or invalid TPM Quote signature received" },
+ { "mn", "IMV Attestation: Буруу/хүлээгдэж байгаа файл/компонент хэмжилт "
+ "эсвэл буруу TPM Quote гарын үсэг" },
+ { "de", "IMV Attestation: Falsche/Fehlende Dateimessung/Komponenten Beweis "
+ "oder ungültige TPM Quote Unterschrift ist erhalten" },
+};
+
+METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
+ private_imv_attestation_state_t *this)
+{
+ return this->connection_id;
+}
+
+METHOD(imv_state_t, has_long, bool,
+ private_imv_attestation_state_t *this)
+{
+ return this->has_long;
+}
+
+METHOD(imv_state_t, has_excl, bool,
+ private_imv_attestation_state_t *this)
+{
+ return this->has_excl;
+}
+
+METHOD(imv_state_t, set_flags, void,
+ private_imv_attestation_state_t *this, bool has_long, bool has_excl)
+{
+ this->has_long = has_long;
+ this->has_excl = has_excl;
+}
+
+METHOD(imv_state_t, change_state, void,
+ private_imv_attestation_state_t *this, TNC_ConnectionState new_state)
+{
+ this->state = new_state;
+}
+
+METHOD(imv_state_t, get_recommendation, void,
+ private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation *rec,
+ TNC_IMV_Evaluation_Result *eval)
+{
+ *rec = this->rec;
+ *eval = this->eval;
+}
+
+METHOD(imv_state_t, set_recommendation, void,
+ private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation rec,
+ TNC_IMV_Evaluation_Result eval)
+{
+ this->rec = rec;
+ this->eval = eval;
+}
+
+METHOD(imv_state_t, get_reason_string, bool,
+ private_imv_attestation_state_t *this, chunk_t preferred_language,
+ chunk_t *reason_string, chunk_t *reason_language)
+{
+ chunk_t pref_lang, lang;
+ u_char *pos;
+ int i;
+
+ while (eat_whitespace(&preferred_language))
+ {
+ if (!extract_token(&pref_lang, ',', &preferred_language))
+ {
+ /* last entry in a comma-separated list or single entry */
+ pref_lang = preferred_language;
+ }
+
+ /* eat trailing whitespace */
+ pos = pref_lang.ptr + pref_lang.len - 1;
+ while (pref_lang.len && *pos-- == ' ')
+ {
+ pref_lang.len--;
+ }
+
+ for (i = 0 ; i < countof(reasons); i++)
+ {
+ lang = chunk_create(reasons[i].lang, strlen(reasons[i].lang));
+ if (chunk_equals(lang, pref_lang))
+ {
+ *reason_language = lang;
+ *reason_string = chunk_create(reasons[i].string,
+ strlen(reasons[i].string));
+ return TRUE;
+ }
+ }
+ }
+
+ /* no preferred language match found - use the default language */
+ *reason_string = chunk_create(reasons[0].string,
+ strlen(reasons[0].string));
+ *reason_language = chunk_create(reasons[0].lang,
+ strlen(reasons[0].lang));
+ return TRUE;
+}
+
+METHOD(imv_state_t, destroy, void,
+ private_imv_attestation_state_t *this)
+{
+ this->file_meas_requests->destroy_function(this->file_meas_requests, free);
+ this->components->destroy_offset(this->components,
+ offsetof(pts_component_t, destroy));
+ this->pts->destroy(this->pts);
+ free(this);
+}
+
+METHOD(imv_attestation_state_t, get_handshake_state,
+ imv_attestation_handshake_state_t, private_imv_attestation_state_t *this)
+{
+ return this->handshake_state;
+}
+
+METHOD(imv_attestation_state_t, set_handshake_state, void,
+ private_imv_attestation_state_t *this,
+ imv_attestation_handshake_state_t new_state)
+{
+ this->handshake_state = new_state;
+}
+
+METHOD(imv_attestation_state_t, get_pts, pts_t*,
+ private_imv_attestation_state_t *this)
+{
+ return this->pts;
+}
+
+METHOD(imv_attestation_state_t, add_file_meas_request, u_int16_t,
+ private_imv_attestation_state_t *this, int file_id, bool is_dir)
+{
+ file_meas_request_t *request;
+
+ request = malloc_thing(file_meas_request_t);
+ request->id = ++this->file_meas_request_counter;
+ request->file_id = file_id;
+ request->is_dir = is_dir;
+ this->file_meas_requests->insert_last(this->file_meas_requests, request);
+
+ return this->file_meas_request_counter;
+}
+
+METHOD(imv_attestation_state_t, check_off_file_meas_request, bool,
+ private_imv_attestation_state_t *this, u_int16_t id, int *file_id,
+ bool* is_dir)
+{
+ enumerator_t *enumerator;
+ file_meas_request_t *request;
+ bool found = FALSE;
+
+ enumerator = this->file_meas_requests->create_enumerator(this->file_meas_requests);
+ while (enumerator->enumerate(enumerator, &request))
+ {
+ if (request->id == id)
+ {
+ found = TRUE;
+ *file_id = request->file_id;
+ *is_dir = request->is_dir;
+ this->file_meas_requests->remove_at(this->file_meas_requests, enumerator);
+ free(request);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found;
+}
+
+METHOD(imv_attestation_state_t, get_file_meas_request_count, int,
+ private_imv_attestation_state_t *this)
+{
+ return this->file_meas_requests->get_count(this->file_meas_requests);
+}
+
+METHOD(imv_attestation_state_t, add_component, void,
+ private_imv_attestation_state_t *this, pts_component_t *entry)
+{
+ this->components->insert_last(this->components, entry);
+}
+
+METHOD(imv_attestation_state_t, check_off_component, pts_component_t*,
+ private_imv_attestation_state_t *this, pts_comp_func_name_t *name)
+{
+ enumerator_t *enumerator;
+ pts_component_t *entry, *found = NULL;
+
+ enumerator = this->components->create_enumerator(this->components);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (name->equals(name, entry->get_comp_func_name(entry)))
+ {
+ found = entry;
+ this->components->remove_at(this->components, enumerator);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return found;
+}
+
+METHOD(imv_attestation_state_t, check_off_registrations, void,
+ private_imv_attestation_state_t *this)
+{
+ enumerator_t *enumerator;
+ pts_component_t *entry;
+
+ enumerator = this->components->create_enumerator(this->components);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->check_off_registrations(entry))
+ {
+ this->components->remove_at(this->components, enumerator);
+ entry->destroy(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(imv_attestation_state_t, get_component_count, int,
+ private_imv_attestation_state_t *this)
+{
+ return this->components->get_count(this->components);
+}
+
+METHOD(imv_attestation_state_t, get_measurement_error, bool,
+ private_imv_attestation_state_t *this)
+{
+ return this->measurement_error;
+}
+
+METHOD(imv_attestation_state_t, set_measurement_error, void,
+ private_imv_attestation_state_t *this)
+{
+ this->measurement_error = TRUE;
+}
+
+/**
+ * Described in header.
+ */
+imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
+{
+ private_imv_attestation_state_t *this;
+ char *platform_info;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .get_connection_id = _get_connection_id,
+ .has_long = _has_long,
+ .has_excl = _has_excl,
+ .set_flags = _set_flags,
+ .change_state = _change_state,
+ .get_recommendation = _get_recommendation,
+ .set_recommendation = _set_recommendation,
+ .get_reason_string = _get_reason_string,
+ .destroy = _destroy,
+ },
+ .get_handshake_state = _get_handshake_state,
+ .set_handshake_state = _set_handshake_state,
+ .get_pts = _get_pts,
+ .add_file_meas_request = _add_file_meas_request,
+ .check_off_file_meas_request = _check_off_file_meas_request,
+ .get_file_meas_request_count = _get_file_meas_request_count,
+ .add_component = _add_component,
+ .check_off_component = _check_off_component,
+ .check_off_registrations = _check_off_registrations,
+ .get_component_count = _get_component_count,
+ .get_measurement_error = _get_measurement_error,
+ .set_measurement_error = _set_measurement_error,
+ },
+ .connection_id = connection_id,
+ .state = TNC_CONNECTION_STATE_CREATE,
+ .handshake_state = IMV_ATTESTATION_STATE_INIT,
+ .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
+ .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
+ .file_meas_requests = linked_list_create(),
+ .components = linked_list_create(),
+ .pts = pts_create(FALSE),
+ );
+
+ platform_info = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imv-attestation.platform_info", NULL);
+ if (platform_info)
+ {
+ this->pts->set_platform_info(this->pts, platform_info);
+ }
+
+ return &this->public.interface;
+}
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_state.h b/src/libpts/plugins/imv_attestation/imv_attestation_state.h
new file mode 100644
index 000000000..0e2c04da4
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_state.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 imv_attestation_state_t imv_attestation_state
+ * @{ @ingroup imv_attestation_state
+ */
+
+#ifndef IMV_ATTESTATION_STATE_H_
+#define IMV_ATTESTATION_STATE_H_
+
+#include <imv/imv_state.h>
+#include <pts/pts.h>
+#include <pts/components/pts_component.h>
+#include <library.h>
+
+typedef struct imv_attestation_state_t imv_attestation_state_t;
+typedef enum imv_attestation_handshake_state_t imv_attestation_handshake_state_t;
+
+/**
+ * IMV Attestation Handshake States (state machine)
+ */
+enum imv_attestation_handshake_state_t {
+ IMV_ATTESTATION_STATE_INIT,
+ IMV_ATTESTATION_STATE_NONCE_REQ,
+ IMV_ATTESTATION_STATE_TPM_INIT,
+ IMV_ATTESTATION_STATE_MEAS,
+ IMV_ATTESTATION_STATE_COMP_EVID,
+ IMV_ATTESTATION_STATE_EVID_FINAL,
+ IMV_ATTESTATION_STATE_END,
+};
+
+/**
+ * Internal state of an imv_attestation_t connection instance
+ */
+struct imv_attestation_state_t {
+
+ /**
+ * imv_state_t interface
+ */
+ imv_state_t interface;
+
+ /**
+ * Get state of the handshake
+ *
+ * @return the handshake state of IMV
+ */
+ imv_attestation_handshake_state_t (*get_handshake_state)(
+ imv_attestation_state_t *this);
+
+ /**
+ * Set state of the handshake
+ *
+ * @param new_state the handshake state of IMV
+ */
+ void (*set_handshake_state)(imv_attestation_state_t *this,
+ imv_attestation_handshake_state_t new_state);
+
+ /**
+ * Get the PTS object
+ *
+ * @return PTS object
+ */
+ pts_t* (*get_pts)(imv_attestation_state_t *this);
+
+ /**
+ * Add an entry to the list of pending file/directory measurement requests
+ *
+ * @param file_id primary key into file table
+ * @param is_dir TRUE if directory
+ * @return unique request ID
+ */
+ u_int16_t (*add_file_meas_request)(imv_attestation_state_t *this,
+ int file_id, bool is_dir);
+
+ /**
+ * Returns the number of pending file/directory measurement requests
+ *
+ * @return number of pending requests
+ */
+ int (*get_file_meas_request_count)(imv_attestation_state_t *this);
+
+ /**
+ * Check for presence of request_id and if found remove it from the list
+ *
+ * @param id unique request ID
+ * @param file_id primary key into file table
+ * @param is_dir return TRUE if request was for a directory
+ * @return TRUE if request ID found, FALSE otherwise
+ */
+ bool (*check_off_file_meas_request)(imv_attestation_state_t *this,
+ u_int16_t id, int *file_id, bool *is_dir);
+
+ /**
+ * Add an entry to the list of Functional Components waiting for evidence
+ *
+ * @param entry Functional Component
+ */
+ void (*add_component)(imv_attestation_state_t *this, pts_component_t *entry);
+
+ /**
+ * Returns the number of Functional Component waiting for evidence
+ *
+ * @return Number of waiting Functional Components
+ */
+ int (*get_component_count)(imv_attestation_state_t *this);
+
+ /**
+ * Check for presence of Functional Component and remove and return it
+ *
+ * @param name Name of the requested Functional Component
+ * @return Functional Component if found, NULL otherwise
+ */
+ pts_component_t* (*check_off_component)(imv_attestation_state_t *this,
+ pts_comp_func_name_t *name);
+
+ /**
+ * Tell the Functional Components to finalize any measurement registrations
+ */
+ void (*check_off_registrations)(imv_attestation_state_t *this);
+
+ /**
+ * Indicates if a file measurement error occurred
+ *
+ * @return TRUE in case of measurement error
+ */
+ bool (*get_measurement_error)(imv_attestation_state_t *this);
+
+ /**
+ * Call if a file measurement error is encountered
+ */
+ void (*set_measurement_error)(imv_attestation_state_t *this);
+
+};
+
+/**
+ * Create an imv_attestation_state_t instance
+ *
+ * @param id connection ID
+ */
+imv_state_t* imv_attestation_state_create(TNC_ConnectionID id);
+
+#endif /** IMV_ATTESTATION_STATE_H_ @}*/
diff --git a/src/libpts/plugins/imv_attestation/tables.sql b/src/libpts/plugins/imv_attestation/tables.sql
new file mode 100644
index 000000000..703557a07
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/tables.sql
@@ -0,0 +1,82 @@
+/* PTS SQLite database */
+
+DROP TABLE IF EXISTS files;
+CREATE TABLE files (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ type INTEGER NOT NULL,
+ path TEXT NOT NULL
+);
+
+DROP TABLE IF EXISTS products;
+CREATE TABLE products (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ name TEXT NOT NULL
+);
+DROP INDEX IF EXISTS products_name;
+CREATE INDEX products_name ON products (
+ name
+);
+
+DROP TABLE IF EXISTS product_file;
+CREATE TABLE product_file (
+ product INTEGER NOT NULL,
+ file INTEGER NOT NULL,
+ measurement INTEGER DEFAULT 0,
+ metadata INTEGER DEFAULT 0,
+ PRIMARY KEY (product, file)
+);
+
+DROP TABLE IF EXISTS file_hashes;
+CREATE TABLE file_hashes (
+ file INTEGER NOT NULL,
+ directory INTEGER DEFAULT 0,
+ product INTEGER NOT NULL,
+ algo INTEGER NOT NULL,
+ hash BLOB NOT NULL,
+ PRIMARY KEY(file, directory, product, algo)
+);
+
+DROP TABLE IF EXISTS keys;
+CREATE TABLE keys (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ keyid BLOB NOT NULL,
+ owner TEXT NOT NULL
+);
+DROP INDEX IF EXISTS keys_keyid;
+CREATE INDEX keys_keyid ON keys (
+ keyid
+);
+DROP INDEX IF EXISTS keys_owner;
+CREATE INDEX keys_owner ON keys (
+ owner
+);
+
+DROP TABLE IF EXISTS components;
+CREATE TABLE components (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ vendor_id INTEGER NOT NULL,
+ name INTEGER NOT NULL,
+ qualifier INTEGER DEFAULT 0
+);
+
+
+DROP TABLE IF EXISTS key_component;
+CREATE TABLE key_component (
+ key INTEGER NOT NULL,
+ component INTEGER NOT NULL,
+ depth INTEGER DEFAULT 0,
+ seq_no INTEGER DEFAULT 0,
+ PRIMARY KEY (key, component)
+);
+
+
+DROP TABLE IF EXISTS component_hashes;
+CREATE TABLE component_hashes (
+ component INTEGER NOT NULL,
+ key INTEGER NOT NULL,
+ seq_no INTEGER NOT NULL,
+ pcr INTEGER NOT NULL,
+ algo INTEGER NOT NULL,
+ hash BLOB NOT NULL,
+ PRIMARY KEY(component, key, seq_no, algo)
+);
diff --git a/src/libpts/pts/components/ita/ita_comp_func_name.c b/src/libpts/pts/components/ita/ita_comp_func_name.c
new file mode 100644
index 000000000..a593281ba
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_func_name.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 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 "ita_comp_func_name.h"
+
+char pts_ita_qualifier_flag_names[] = { 'K', 'S' };
+
+ENUM_BEGIN(pts_ita_qualifier_type_names, PTS_ITA_QUALIFIER_TYPE_UNKNOWN,
+ PTS_ITA_QUALIFIER_TYPE_TNC,
+ "Unknown",
+ "Trusted Platform",
+ "Operating System",
+ "Graphical User Interface",
+ "Application",
+ "Networking",
+ "Library",
+ "TNC Defined Component"
+);
+ENUM_NEXT(pts_ita_qualifier_type_names, PTS_ITA_QUALIFIER_TYPE_ALL,
+ PTS_ITA_QUALIFIER_TYPE_ALL,
+ PTS_ITA_QUALIFIER_TYPE_TNC,
+ "All Matching Components"
+);
+ENUM_END(pts_ita_qualifier_type_names, PTS_ITA_QUALIFIER_TYPE_ALL);
+
+ENUM(pts_ita_comp_func_names, PTS_ITA_COMP_FUNC_NAME_IGNORE,
+ PTS_ITA_COMP_FUNC_NAME_IMA,
+ "Ignore",
+ "Trusted GRUB Boot Loader",
+ "Trusted Boot",
+ "Linux IMA"
+);
+
diff --git a/src/libpts/pts/components/ita/ita_comp_func_name.h b/src/libpts/pts/components/ita/ita_comp_func_name.h
new file mode 100644
index 000000000..eb2f363f3
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_func_name.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_ita_comp_func_name pts_ita_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_ITA_COMP_FUNC_NAME_H_
+#define PTS_ITA_COMP_FUNC_NAME_H_
+
+typedef enum pts_ita_qualifier_type_t pts_ita_qualifier_type_t;
+typedef enum pts_ita_comp_func_name_t pts_ita_comp_func_name_t;
+
+#include <library.h>
+
+/**
+ * PTS Component Functional Name Qualifier Flags for the ITA namespace
+ */
+#define PTS_ITA_QUALIFIER_FLAG_KERNEL (1<<5)
+#define PTS_ITA_QUALIFIER_FLAG_SUB (1<<4)
+
+extern char pts_ita_qualifier_flag_names[];
+
+/**
+ * Size of the PTS Component Functional Name Qualifier Type field
+ */
+#define PTS_ITA_QUALIFIER_TYPE_SIZE 4
+
+/**
+ * PTS Component Functional Name Qualifier Types for the ITA namespace
+ * equal to section 5.2 of PTS Protocol: Binding to TNC IF-M Specification
+ */
+enum pts_ita_qualifier_type_t {
+ /** Unknown */
+ PTS_ITA_QUALIFIER_TYPE_UNKNOWN = 0x0,
+ /** Trusted Platform */
+ PTS_ITA_QUALIFIER_TYPE_TRUSTED = 0x1,
+ /** Operating System */
+ PTS_ITA_QUALIFIER_TYPE_OS = 0x2,
+ /** Graphical User Interface */
+ PTS_ITA_QUALIFIER_TYPE_GUI = 0x3,
+ /** Application */
+ PTS_ITA_QUALIFIER_TYPE_APP = 0x4,
+ /** Networking */
+ PTS_ITA_QUALIFIER_TYPE_NET = 0x5,
+ /** Library */
+ PTS_ITA_QUALIFIER_TYPE_LIB = 0x6,
+ /** TNC Defined Component */
+ PTS_ITA_QUALIFIER_TYPE_TNC = 0x7,
+ /** All Matching Components */
+ PTS_ITA_QUALIFIER_TYPE_ALL = 0xF,
+};
+
+extern enum_name_t *pts_ita_qualifier_type_names;
+
+/**
+ * PTS Component Functional Name Binary Enumeration for the ITA namespace
+ */
+enum pts_ita_comp_func_name_t {
+ /** Ignore */
+ PTS_ITA_COMP_FUNC_NAME_IGNORE = 0x0000,
+ /** Trusted GRUB Boot Loader */
+ PTS_ITA_COMP_FUNC_NAME_TGRUB = 0x0001,
+ /** Trusted Boot */
+ PTS_ITA_COMP_FUNC_NAME_TBOOT = 0x0002,
+ /** Linux Integrity Measurement Architecture */
+ PTS_ITA_COMP_FUNC_NAME_IMA = 0x0003,
+};
+
+extern enum_name_t *pts_ita_comp_func_names;
+
+#endif /** PTS_ITA_COMP_FUNC_NAME_H_ @}*/
diff --git a/src/libpts/pts/components/ita/ita_comp_ima.c b/src/libpts/pts/components/ita/ita_comp_ima.c
new file mode 100644
index 000000000..a7da76651
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_ima.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2011 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 "ita_comp_ima.h"
+#include "ita_comp_func_name.h"
+
+#include "libpts.h"
+#include "pts/components/pts_component.h"
+
+#include <debug.h>
+#include <pen/pen.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#define IMA_SECURITY_DIR "/sys/kernel/security/tpm0/"
+#define IMA_BIOS_MEASUREMENT_PATH IMA_SECURITY_DIR "binary_bios_measurements"
+#define IMA_PCR_MAX 16
+
+typedef struct pts_ita_comp_ima_t pts_ita_comp_ima_t;
+
+/**
+ * Private data of a pts_ita_comp_ima_t object.
+ *
+ */
+struct pts_ita_comp_ima_t {
+
+ /**
+ * Public pts_component_t interface.
+ */
+ pts_component_t public;
+
+ /**
+ * Component Functional Name
+ */
+ pts_comp_func_name_t *name;
+
+ /**
+ * AIK keyid
+ */
+ chunk_t keyid;
+
+ /**
+ * Sub-component depth
+ */
+ u_int32_t depth;
+
+ /**
+ * PTS measurement database
+ */
+ pts_database_t *pts_db;
+
+ /**
+ * Primary key for Component Functional Name database entry
+ */
+ int cid;
+
+ /**
+ * Primary key for AIK database entry
+ */
+ int kid;
+
+ /**
+ * Component is registering measurements
+ */
+ bool is_registering;
+
+ /**
+ * IMA BIOS measurement time
+ */
+ time_t bios_measurement_time;
+
+ /**
+ * IMA BIOS measurements
+ */
+ linked_list_t *list;
+
+ /**
+ * Expected measurement count
+ */
+ int count;
+
+ /**
+ * Measurement sequence number
+ */
+ int seq_no;
+
+ /**
+ * Shadow PCR registers
+ */
+ chunk_t pcrs[IMA_PCR_MAX];
+};
+
+typedef struct entry_t entry_t;
+
+/**
+ * Linux IMA measurement entry
+ */
+struct entry_t {
+
+ /**
+ * PCR register
+ */
+ u_int32_t pcr;
+
+ /**
+ * SHA1 measurement hash
+ */
+ chunk_t measurement;
+};
+
+/**
+ * Free an entry_t object
+ */
+static void free_entry(entry_t *this)
+{
+ free(this->measurement.ptr);
+ free(this);
+}
+
+/**
+ * Load a PCR measurement file and determine the creation date
+ */
+static bool load_measurements(char *file, linked_list_t *list, time_t *created)
+{
+ u_int32_t pcr, num, len;
+ entry_t *entry;
+ struct stat st;
+ ssize_t res;
+ int fd;
+
+ fd = open(file, O_RDONLY);
+ if (fd == -1)
+ {
+ DBG1(DBG_PTS, " opening '%s' failed: %s", file, strerror(errno));
+ return FALSE;
+ }
+
+ if (fstat(fd, &st) == -1)
+ {
+ DBG1(DBG_PTS, " getting statistics of '%s' failed: %s", file,
+ strerror(errno));
+ close(fd);
+ return FALSE;
+ }
+ *created = st.st_ctime;
+
+ while (TRUE)
+ {
+ res = read(fd, &pcr, 4);
+ if (res == 0)
+ {
+ DBG2(DBG_PTS, "loaded bios measurements '%s' (%d entries)",
+ file, list->get_count(list));
+ close(fd);
+ return TRUE;
+ }
+
+ entry = malloc_thing(entry_t);
+ entry->pcr = pcr;
+ entry->measurement = chunk_alloc(HASH_SIZE_SHA1);
+
+ if (res != 4)
+ {
+ break;
+ }
+ if (read(fd, &num, 4) != 4)
+ {
+ break;
+ }
+ if (read(fd, entry->measurement.ptr, HASH_SIZE_SHA1) != HASH_SIZE_SHA1)
+ {
+ break;
+ }
+ if (read(fd, &len, 4) != 4)
+ {
+ break;
+ }
+ if (lseek(fd, len, SEEK_CUR) == -1)
+ {
+ break;
+ }
+ list->insert_last(list, entry);
+ }
+
+ DBG1(DBG_PTS, "loading bios measurements '%s' failed: %s",
+ file, strerror(errno));
+ close(fd);
+ return FALSE;
+}
+
+METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
+ pts_ita_comp_ima_t *this)
+{
+ return this->name;
+}
+
+METHOD(pts_component_t, get_evidence_flags, u_int8_t,
+ pts_ita_comp_ima_t *this)
+{
+ return PTS_REQ_FUNC_COMP_EVID_PCR;
+}
+
+METHOD(pts_component_t, get_depth, u_int32_t,
+ pts_ita_comp_ima_t *this)
+{
+ return this->depth;
+}
+
+METHOD(pts_component_t, measure, status_t,
+ pts_ita_comp_ima_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+{
+ pts_comp_evidence_t *evid;
+ chunk_t pcr_before, pcr_after;
+ pts_pcr_transform_t pcr_transform;
+ pts_meas_algorithms_t hash_algo;
+ size_t pcr_len;
+ entry_t *entry;
+ hasher_t *hasher;
+
+ hash_algo = PTS_MEAS_ALGO_SHA1;
+ pcr_len = pts->get_pcr_len(pts);
+ pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
+
+ if (this->list->get_count(this->list) == 0)
+ {
+ if (!load_measurements(IMA_BIOS_MEASUREMENT_PATH, this->list,
+ &this->bios_measurement_time))
+ {
+ return FAILED;
+ }
+ }
+
+ if (this->list->remove_first(this->list, (void**)&entry) != SUCCESS)
+ {
+ DBG1(DBG_PTS, "could not retrieve measurement entry");
+ return FAILED;
+ }
+
+ pcr_before = chunk_clone(this->pcrs[entry->pcr]);
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ hasher->get_hash(hasher, pcr_before, NULL);
+ hasher->get_hash(hasher, entry->measurement, this->pcrs[entry->pcr].ptr);
+ hasher->destroy(hasher);
+
+ pcr_after = chunk_clone(this->pcrs[entry->pcr]);
+
+ evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
+ this->depth, entry->pcr, hash_algo, pcr_transform,
+ this->bios_measurement_time, entry->measurement);
+ evid->set_pcr_info(evid, pcr_before, pcr_after);
+
+ free(entry);
+
+ return (this->list->get_count(this->list)) ? NEED_MORE : SUCCESS;
+}
+
+METHOD(pts_component_t, verify, status_t,
+ pts_ita_comp_ima_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
+{
+ bool has_pcr_info;
+ u_int32_t extended_pcr, vid, name;
+ enum_name_t *names;
+ pts_meas_algorithms_t algo;
+ pts_pcr_transform_t transform;
+ time_t measurement_time;
+ chunk_t measurement, pcr_before, pcr_after;
+
+ measurement = evidence->get_measurement(evidence, &extended_pcr,
+ &algo, &transform, &measurement_time);
+
+ if (!this->keyid.ptr)
+ {
+ if (!pts->get_aik_keyid(pts, &this->keyid))
+ {
+ return FAILED;
+ }
+ this->keyid = chunk_clone(this->keyid);
+
+ if (!this->pts_db)
+ {
+ DBG1(DBG_PTS, "pts database not available");
+ return FAILED;
+ }
+ if (this->pts_db->get_comp_measurement_count(this->pts_db,
+ this->name, this->keyid, algo,
+ &this->cid, &this->kid, &this->count) != SUCCESS)
+ {
+ return FAILED;
+ }
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+
+ if (this->count)
+ {
+ DBG1(DBG_PTS, "checking %d %N '%N' functional component evidence "
+ "measurements", this->count, pen_names, vid, names, name);
+ }
+ else
+ {
+ DBG1(DBG_PTS, "registering %N '%N' functional component evidence "
+ "measurements", pen_names, vid, names, name);
+ this->is_registering = TRUE;
+ }
+ }
+
+ if (this->is_registering)
+ {
+ if (this->pts_db->insert_comp_measurement(this->pts_db, measurement,
+ this->cid, this->kid, ++this->seq_no,
+ extended_pcr, algo) != SUCCESS)
+ {
+ return FAILED;
+ }
+ this->count = this->seq_no + 1;
+ }
+ else
+ {
+ if (this->pts_db->check_comp_measurement(this->pts_db, measurement,
+ this->cid, this->kid, ++this->seq_no,
+ extended_pcr, algo) != SUCCESS)
+ {
+ return FAILED;
+ }
+ }
+
+ has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
+ if (has_pcr_info)
+ {
+ if (!pts->add_pcr(pts, extended_pcr, pcr_before, pcr_after))
+ {
+ return FAILED;
+ }
+ }
+
+ return (this->seq_no < this->count) ? NEED_MORE : SUCCESS;
+}
+
+METHOD(pts_component_t, check_off_registrations, bool,
+ pts_ita_comp_ima_t *this)
+{
+ u_int32_t vid, name;
+ enum_name_t *names;
+
+ if (!this->is_registering)
+ {
+ return FALSE;
+ }
+
+ /* Finalize registration */
+ this->is_registering = FALSE;
+
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+ DBG1(DBG_PTS, "registered %d %N '%N' functional component evidence "
+ "measurements", this->seq_no, pen_names, vid, names, name);
+ return TRUE;
+}
+
+METHOD(pts_component_t, destroy, void,
+ pts_ita_comp_ima_t *this)
+{
+ int i, count;
+ u_int32_t vid, name;
+ enum_name_t *names;
+
+ for (i = 0; i < IMA_PCR_MAX; i++)
+ {
+ free(this->pcrs[i].ptr);
+ }
+ if (this->is_registering)
+ {
+ count = this->pts_db->delete_comp_measurements(this->pts_db,
+ this->cid, this->kid);
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+ DBG1(DBG_PTS, "deleted %d registered %N '%N' functional component "
+ "evidence measurements", count, pen_names, vid, names, name);
+ }
+ this->list->destroy_function(this->list, (void *)free_entry);
+ this->name->destroy(this->name);
+ free(this->keyid.ptr);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_component_t *pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db)
+{
+ pts_ita_comp_ima_t *this;
+ int i;
+
+ INIT(this,
+ .public = {
+ .get_comp_func_name = _get_comp_func_name,
+ .get_evidence_flags = _get_evidence_flags,
+ .get_depth = _get_depth,
+ .measure = _measure,
+ .verify = _verify,
+ .check_off_registrations = _check_off_registrations,
+ .destroy = _destroy,
+ },
+ .name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_IMA,
+ qualifier),
+ .depth = depth,
+ .pts_db = pts_db,
+ .list = linked_list_create(),
+ );
+
+ for (i = 0; i < IMA_PCR_MAX; i++)
+ {
+ this->pcrs[i] = chunk_alloc(HASH_SIZE_SHA1);
+ memset(this->pcrs[i].ptr, 0x00, HASH_SIZE_SHA1);
+ }
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/components/ita/ita_comp_ima.h b/src/libpts/pts/components/ita/ita_comp_ima.h
new file mode 100644
index 000000000..1ca27e6f0
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_ima.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 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 pts_ita_comp_func_name pts_ita_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_ITA_COMP_IMA_H_
+#define PTS_ITA_COMP_IMA_H_
+
+#include "pts/components/pts_component.h"
+
+/**
+ * Create a PTS ITS Functional Component object
+ *
+ * @param qualifier PTS Component Functional Name Qualifier
+ * @param depth Sub-component depth
+ * @param pts_db PTS measurement database
+ */
+pts_component_t* pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db);
+
+#endif /** PTS_ITA_COMP_IMA_H_ @}*/
diff --git a/src/libpts/pts/components/ita/ita_comp_tboot.c b/src/libpts/pts/components/ita/ita_comp_tboot.c
new file mode 100644
index 000000000..a85de8cd8
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_tboot.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2011 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 "ita_comp_tboot.h"
+#include "ita_comp_func_name.h"
+
+#include "libpts.h"
+#include "pts/components/pts_component.h"
+
+#include <debug.h>
+#include <pen/pen.h>
+
+typedef struct pts_ita_comp_tboot_t pts_ita_comp_tboot_t;
+
+/**
+ * Private data of a pts_ita_comp_tboot_t object.
+ *
+ */
+struct pts_ita_comp_tboot_t {
+
+ /**
+ * Public pts_component_t interface.
+ */
+ pts_component_t public;
+
+ /**
+ * Component Functional Name
+ */
+ pts_comp_func_name_t *name;
+
+ /**
+ * AIK keyid
+ */
+ chunk_t keyid;
+
+ /**
+ * Sub-component depth
+ */
+ u_int32_t depth;
+
+ /**
+ * PTS measurement database
+ */
+ pts_database_t *pts_db;
+
+ /**
+ * Primary key for Component Functional Name database entry
+ */
+ int cid;
+
+ /**
+ * Primary key for AIK database entry
+ */
+ int kid;
+
+ /**
+ * Component is registering measurements
+ */
+ bool is_registering;
+
+ /**
+ * Time of TBOOT measurement
+ */
+ time_t measurement_time;
+
+ /**
+ * Expected measurement count
+ */
+ int count;
+
+ /**
+ * Measurement sequence number
+ */
+ int seq_no;
+
+};
+
+METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
+ pts_ita_comp_tboot_t *this)
+{
+ return this->name;
+}
+
+METHOD(pts_component_t, get_evidence_flags, u_int8_t,
+ pts_ita_comp_tboot_t *this)
+{
+ return PTS_REQ_FUNC_COMP_EVID_PCR;
+}
+
+METHOD(pts_component_t, get_depth, u_int32_t,
+ pts_ita_comp_tboot_t *this)
+{
+ return this->depth;
+}
+
+METHOD(pts_component_t, measure, status_t,
+ pts_ita_comp_tboot_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+{
+ pts_comp_evidence_t *evid;
+ char *meas_hex, *pcr_before_hex, *pcr_after_hex;
+ chunk_t measurement, pcr_before, pcr_after;
+ size_t hash_size, pcr_len;
+ u_int32_t extended_pcr;
+ pts_pcr_transform_t pcr_transform;
+ pts_meas_algorithms_t hash_algo;
+
+ switch (this->seq_no++)
+ {
+ case 0:
+ /* dummy data since currently the TBOOT log is not retrieved */
+ time(&this->measurement_time);
+ meas_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr17_meas", NULL);
+ pcr_before_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr17_before", NULL);
+ pcr_after_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr17_after", NULL);
+ extended_pcr = PCR_TBOOT_POLICY;
+ break;
+ case 1:
+ /* dummy data since currently the TBOOT log is not retrieved */
+ meas_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr18_meas", NULL);
+ pcr_before_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr18_before", NULL);
+ pcr_after_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr18_after", NULL);
+ extended_pcr = PCR_TBOOT_MLE;
+ break;
+ default:
+ return FAILED;
+ }
+
+ if (meas_hex == NULL || pcr_before_hex == NULL || pcr_after_hex == NULL)
+ {
+ return FAILED;
+ }
+
+ hash_algo = pts->get_meas_algorithm(pts);
+ hash_size = pts_meas_algo_hash_size(hash_algo);
+ pcr_len = pts->get_pcr_len(pts);
+ pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
+
+ /* get and check the measurement data */
+ measurement = chunk_from_hex(
+ chunk_create(meas_hex, strlen(meas_hex)), NULL);
+ pcr_before = chunk_from_hex(
+ chunk_create(pcr_before_hex, strlen(pcr_before_hex)), NULL);
+ pcr_after = chunk_from_hex(
+ chunk_create(pcr_after_hex, strlen(pcr_after_hex)), NULL);
+ if (pcr_before.len != pcr_len || pcr_after.len != pcr_len ||
+ measurement.len != hash_size)
+ {
+ DBG1(DBG_PTS, "TBOOT measurement or pcr data have the wrong size");
+ free(measurement.ptr);
+ free(pcr_before.ptr);
+ free(pcr_after.ptr);
+ return FAILED;
+ }
+
+ evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
+ this->depth, extended_pcr,
+ hash_algo, pcr_transform,
+ this->measurement_time, measurement);
+ evid->set_pcr_info(evid, pcr_before, pcr_after);
+
+ return (this->seq_no < 2) ? NEED_MORE : SUCCESS;
+}
+
+METHOD(pts_component_t, verify, status_t,
+ pts_ita_comp_tboot_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
+{
+ bool has_pcr_info;
+ u_int32_t extended_pcr, vid, name;
+ enum_name_t *names;
+ pts_meas_algorithms_t algo;
+ pts_pcr_transform_t transform;
+ time_t measurement_time;
+ chunk_t measurement, pcr_before, pcr_after;
+
+ measurement = evidence->get_measurement(evidence, &extended_pcr,
+ &algo, &transform, &measurement_time);
+
+ if (!this->keyid.ptr)
+ {
+ if (!pts->get_aik_keyid(pts, &this->keyid))
+ {
+ return FAILED;
+ }
+ this->keyid = chunk_clone(this->keyid);
+
+ if (!this->pts_db)
+ {
+ DBG1(DBG_PTS, "pts database not available");
+ return FAILED;
+ }
+ if (this->pts_db->get_comp_measurement_count(this->pts_db,
+ this->name, this->keyid, algo,
+ &this->cid, &this->kid, &this->count) != SUCCESS)
+ {
+ return FAILED;
+ }
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+
+ if (this->count)
+ {
+ DBG1(DBG_PTS, "checking %d %N '%N' functional component evidence "
+ "measurements", this->count, pen_names, vid, names, name);
+ }
+ else
+ {
+ DBG1(DBG_PTS, "registering %N '%N' functional component evidence "
+ "measurements", pen_names, vid, names, name);
+ this->is_registering = TRUE;
+ }
+ }
+
+ if (this->is_registering)
+ {
+ if (this->pts_db->insert_comp_measurement(this->pts_db, measurement,
+ this->cid, this->kid, ++this->seq_no,
+ extended_pcr, algo) != SUCCESS)
+ {
+ return FAILED;
+ }
+ this->count = this->seq_no + 1;
+ }
+ else
+ {
+ if (this->pts_db->check_comp_measurement(this->pts_db, measurement,
+ this->cid, this->kid, ++this->seq_no,
+ extended_pcr, algo) != SUCCESS)
+ {
+ return FAILED;
+ }
+ }
+
+ has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
+ if (has_pcr_info)
+ {
+ if (!pts->add_pcr(pts, extended_pcr, pcr_before, pcr_after))
+ {
+ return FAILED;
+ }
+ }
+
+ return (this->seq_no < this->count) ? NEED_MORE : SUCCESS;
+}
+
+METHOD(pts_component_t, check_off_registrations, bool,
+ pts_ita_comp_tboot_t *this)
+{
+ u_int32_t vid, name;
+ enum_name_t *names;
+
+ if (!this->is_registering)
+ {
+ return FALSE;
+ }
+
+ /* Finalize registration */
+ this->is_registering = FALSE;
+
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+ DBG1(DBG_PTS, "registered %d %N '%N' functional component evidence "
+ "measurements", this->seq_no, pen_names, vid, names, name);
+ return TRUE;
+}
+
+METHOD(pts_component_t, destroy, void,
+ pts_ita_comp_tboot_t *this)
+{
+ int count;
+ u_int32_t vid, name;
+ enum_name_t *names;
+
+ if (this->is_registering)
+ {
+ count = this->pts_db->delete_comp_measurements(this->pts_db,
+ this->cid, this->kid);
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+ DBG1(DBG_PTS, "deleted %d registered %N '%N' functional component "
+ "evidence measurements", count, pen_names, vid, names, name);
+ }
+ this->name->destroy(this->name);
+ free(this->keyid.ptr);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_component_t *pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db)
+{
+ pts_ita_comp_tboot_t *this;
+
+ INIT(this,
+ .public = {
+ .get_comp_func_name = _get_comp_func_name,
+ .get_evidence_flags = _get_evidence_flags,
+ .get_depth = _get_depth,
+ .measure = _measure,
+ .verify = _verify,
+ .check_off_registrations = _check_off_registrations,
+ .destroy = _destroy,
+ },
+ .name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TBOOT,
+ qualifier),
+ .depth = depth,
+ .pts_db = pts_db,
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/components/ita/ita_comp_tboot.h b/src/libpts/pts/components/ita/ita_comp_tboot.h
new file mode 100644
index 000000000..39554fbc7
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_tboot.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_ita_comp_func_name pts_ita_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_ITA_COMP_TBOOT_H_
+#define PTS_ITA_COMP_TBOOT_H_
+
+#include "pts/components/pts_component.h"
+
+/**
+ * Create a PTS ITS Functional Component object
+ *
+ * @param qualifier PTS Component Functional Name Qualifier
+ * @param depth Sub-component depth
+ * @param pts_db PTS measurement database
+ */
+pts_component_t* pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db);
+
+#endif /** PTS_ITA_COMP_TBOOT_H_ @}*/
diff --git a/src/libpts/pts/components/ita/ita_comp_tgrub.c b/src/libpts/pts/components/ita/ita_comp_tgrub.c
new file mode 100644
index 000000000..0dfd5fd41
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_tgrub.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2011 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 "ita_comp_tgrub.h"
+#include "ita_comp_func_name.h"
+
+#include "pts/components/pts_component.h"
+
+#include <debug.h>
+#include <pen/pen.h>
+
+typedef struct pts_ita_comp_tgrub_t pts_ita_comp_tgrub_t;
+
+/**
+ * Private data of a pts_ita_comp_tgrub_t object.
+ *
+ */
+struct pts_ita_comp_tgrub_t {
+
+ /**
+ * Public pts_component_t interface.
+ */
+ pts_component_t public;
+
+ /**
+ * Component Functional Name
+ */
+ pts_comp_func_name_t *name;
+
+ /**
+ * Sub-component depth
+ */
+ u_int32_t depth;
+
+ /**
+ * PTS measurement database
+ */
+ pts_database_t *pts_db;
+
+};
+
+METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
+ pts_ita_comp_tgrub_t *this)
+{
+ return this->name;
+}
+
+METHOD(pts_component_t, get_evidence_flags, u_int8_t,
+ pts_ita_comp_tgrub_t *this)
+{
+ return PTS_REQ_FUNC_COMP_EVID_PCR;
+}
+
+METHOD(pts_component_t, get_depth, u_int32_t,
+ pts_ita_comp_tgrub_t *this)
+{
+ return this->depth;
+}
+
+METHOD(pts_component_t, measure, status_t,
+ pts_ita_comp_tgrub_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+{
+ pts_comp_evidence_t *evid;
+ u_int32_t extended_pcr;
+ time_t measurement_time;
+ chunk_t measurement, pcr_before, pcr_after;
+ pts_pcr_transform_t pcr_transform;
+ pts_meas_algorithms_t hash_algo;
+ size_t hash_size, pcr_len;
+
+ /* Provisional implementation for TGRUB */
+ extended_pcr = PCR_DEBUG;
+ time(&measurement_time);
+
+ if (!pts->read_pcr(pts, extended_pcr, &pcr_after))
+ {
+ DBG1(DBG_PTS, "error occurred while reading PCR: %d", extended_pcr);
+ return FAILED;
+ }
+
+ hash_algo = pts->get_meas_algorithm(pts);
+ hash_size = pts_meas_algo_hash_size(hash_algo);
+ pcr_len = pts->get_pcr_len(pts);
+ pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
+
+ measurement = chunk_alloc(hash_size);
+ memset(measurement.ptr, 0x00, measurement.len);
+
+ pcr_before = chunk_alloc(pcr_len);
+ memset(pcr_before.ptr, 0x00, pcr_before.len);
+
+ evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
+ this->depth, extended_pcr,
+ hash_algo, pcr_transform,
+ measurement_time, measurement);
+ evid->set_pcr_info(evid, pcr_before, pcr_after);
+
+ return SUCCESS;
+}
+
+METHOD(pts_component_t, verify, status_t,
+ pts_ita_comp_tgrub_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
+{
+ bool has_pcr_info;
+ u_int32_t extended_pcr;
+ pts_meas_algorithms_t algo;
+ pts_pcr_transform_t transform;
+ time_t measurement_time;
+ chunk_t measurement, pcr_before, pcr_after;
+
+ measurement = evidence->get_measurement(evidence, &extended_pcr,
+ &algo, &transform, &measurement_time);
+ if (extended_pcr != PCR_DEBUG)
+ {
+ return FAILED;
+ }
+
+ /* TODO check measurement in database */
+
+ has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
+ if (has_pcr_info)
+ {
+ if (!pts->add_pcr(pts, extended_pcr, pcr_before, pcr_after))
+ {
+ return FAILED;
+ }
+ }
+
+ return SUCCESS;
+}
+
+METHOD(pts_component_t, check_off_registrations, bool,
+ pts_ita_comp_tgrub_t *this)
+{
+ return FALSE;
+}
+
+METHOD(pts_component_t, destroy, void,
+ pts_ita_comp_tgrub_t *this)
+{
+ this->name->destroy(this->name);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_component_t *pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db)
+{
+ pts_ita_comp_tgrub_t *this;
+
+ INIT(this,
+ .public = {
+ .get_comp_func_name = _get_comp_func_name,
+ .get_evidence_flags = _get_evidence_flags,
+ .get_depth = _get_depth,
+ .measure = _measure,
+ .verify = _verify,
+ .check_off_registrations = _check_off_registrations,
+ .destroy = _destroy,
+ },
+ .name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TGRUB,
+ qualifier),
+ .depth = depth,
+ .pts_db = pts_db,
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/components/ita/ita_comp_tgrub.h b/src/libpts/pts/components/ita/ita_comp_tgrub.h
new file mode 100644
index 000000000..52ecc325c
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_tgrub.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_ita_comp_func_name pts_ita_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_ITA_COMP_TGRUB_H_
+#define PTS_ITA_COMP_TGRUB_H_
+
+#include "pts/components/pts_component.h"
+
+/**
+ * Create a PTS ITS Functional Component object
+ *
+ * @param qualifier PTS Component Functional Name Qualifier
+ * @param depth Sub-component depth
+ * @param pts_db PTS measurement database
+ */
+pts_component_t* pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db);
+
+#endif /** PTS_ITA_COMP_TGRUB_H_ @}*/
diff --git a/src/libpts/pts/components/pts_comp_evidence.c b/src/libpts/pts/components/pts_comp_evidence.c
new file mode 100644
index 000000000..9eb8dae75
--- /dev/null
+++ b/src/libpts/pts/components/pts_comp_evidence.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu, 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 "pts/components/pts_comp_evidence.h"
+
+#include <debug.h>
+
+typedef struct private_pts_comp_evidence_t private_pts_comp_evidence_t;
+
+/**
+ * Private data of a pts_comp_evidence_t object.
+ */
+struct private_pts_comp_evidence_t {
+
+ /**
+ * Public pts_comp_evidence_t interface.
+ */
+ pts_comp_evidence_t public;
+
+ /**
+ * Component Functional Name
+ */
+ pts_comp_func_name_t *name;
+
+ /**
+ * Sub-Component Depth
+ */
+ u_int32_t depth;
+
+ /**
+ * Measurement Time
+ */
+ time_t measurement_time;
+
+ /**
+ * Measurement Time
+ */
+ chunk_t measurement;
+
+ /**
+ * Measurement Hash Algorithm
+ */
+ pts_meas_algorithms_t hash_algorithm;
+
+ /**
+ * Is PCR Information included?
+ */
+ bool has_pcr_info;
+
+ /**
+ * PCR the measurement was extended into
+ */
+ u_int32_t extended_pcr;
+
+ /**
+ * PCR value before extension
+ */
+ chunk_t pcr_before;
+
+ /**
+ * PCR value after extension
+ */
+ chunk_t pcr_after;
+
+ /**
+ * Transformation used for extending measurement into PCR
+ */
+ pts_pcr_transform_t transform;
+
+ /**
+ * Component Validation Result
+ */
+ pts_comp_evid_validation_t validation;
+
+ /**
+ * Verification Policy URI
+ */
+ chunk_t policy_uri;
+
+};
+
+METHOD(pts_comp_evidence_t, get_comp_func_name, pts_comp_func_name_t*,
+ private_pts_comp_evidence_t *this, u_int32_t *depth)
+{
+ if (depth)
+ {
+ *depth = this->depth;
+ }
+ return this->name;
+}
+
+METHOD(pts_comp_evidence_t, get_extended_pcr, u_int32_t,
+ private_pts_comp_evidence_t *this)
+{
+ return this->extended_pcr;
+}
+
+METHOD(pts_comp_evidence_t, get_measurement, chunk_t,
+ private_pts_comp_evidence_t *this, u_int32_t *extended_pcr,
+ pts_meas_algorithms_t *algo, pts_pcr_transform_t *transform,
+ time_t *measurement_time)
+{
+ if (extended_pcr)
+ {
+ *extended_pcr = this->extended_pcr;
+ }
+ if (algo)
+ {
+ *algo = this->hash_algorithm;
+ }
+ if (transform)
+ {
+ *transform = this->transform;
+ }
+ if (measurement_time)
+ {
+ *measurement_time = this->measurement_time;
+ }
+ return this->measurement;
+}
+
+METHOD(pts_comp_evidence_t, get_pcr_info, bool,
+ private_pts_comp_evidence_t *this, chunk_t *pcr_before, chunk_t *pcr_after)
+{
+ if (pcr_before)
+ {
+ *pcr_before = this->pcr_before;
+ }
+ if (pcr_after)
+ {
+ *pcr_after = this->pcr_after;
+ }
+ return this->has_pcr_info;
+}
+
+METHOD(pts_comp_evidence_t, set_pcr_info, void,
+ private_pts_comp_evidence_t *this, chunk_t pcr_before, chunk_t pcr_after)
+{
+ this->has_pcr_info = TRUE;
+ this->pcr_before = pcr_before;
+ this->pcr_after = pcr_after;
+
+ DBG2(DBG_PTS, "PCR %2d before value : %#B", this->extended_pcr, &pcr_before);
+ DBG2(DBG_PTS, "PCR %2d after value : %#B", this->extended_pcr, &pcr_after);
+}
+
+METHOD(pts_comp_evidence_t, get_validation, pts_comp_evid_validation_t,
+ private_pts_comp_evidence_t *this, chunk_t *uri)
+{
+ if (uri)
+ {
+ *uri = this->policy_uri;
+ }
+ return this->validation;
+}
+
+METHOD(pts_comp_evidence_t, set_validation, void,
+ private_pts_comp_evidence_t *this, pts_comp_evid_validation_t validation,
+ chunk_t uri)
+{
+ this->validation = validation;
+ this->policy_uri = chunk_clone(uri);
+}
+
+METHOD(pts_comp_evidence_t, destroy, void,
+ private_pts_comp_evidence_t *this)
+{
+ this->name->destroy(this->name);
+ free(this->measurement.ptr);
+ free(this->pcr_before.ptr);
+ free(this->pcr_after.ptr);
+ free(this->policy_uri.ptr);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_comp_evidence_t *pts_comp_evidence_create(pts_comp_func_name_t *name,
+ u_int32_t depth,
+ u_int32_t extended_pcr,
+ pts_meas_algorithms_t algo,
+ pts_pcr_transform_t transform,
+ time_t measurement_time,
+ chunk_t measurement)
+{
+ private_pts_comp_evidence_t *this;
+
+ INIT(this,
+ .public = {
+ .get_comp_func_name = _get_comp_func_name,
+ .get_extended_pcr = _get_extended_pcr,
+ .get_measurement = _get_measurement,
+ .get_pcr_info = _get_pcr_info,
+ .set_pcr_info = _set_pcr_info,
+ .get_validation = _get_validation,
+ .set_validation = _set_validation,
+ .destroy = _destroy,
+ },
+ .name = name,
+ .depth = depth,
+ .extended_pcr = extended_pcr,
+ .hash_algorithm = algo,
+ .transform = transform,
+ .measurement_time = measurement_time,
+ .measurement = measurement,
+ );
+
+ name->log(name, "");
+ DBG2(DBG_PTS, "measurement time: %T", &measurement_time, FALSE);
+ DBG2(DBG_PTS, "PCR %2d extended with: %#B", extended_pcr, &measurement);
+
+ return &this->public;
+}
+
+/**
+ * See header
+ */
+pts_pcr_transform_t pts_meas_algo_to_pcr_transform(pts_meas_algorithms_t algo,
+ size_t pcr_len)
+{
+ size_t hash_size;
+
+ hash_size = pts_meas_algo_hash_size(algo);
+ if (hash_size == 0)
+ {
+ return PTS_PCR_TRANSFORM_NO;
+ }
+ if (hash_size == pcr_len)
+ {
+ return PTS_PCR_TRANSFORM_MATCH;
+ }
+ if (hash_size > pcr_len)
+ {
+ return PTS_PCR_TRANSFORM_LONG;
+ }
+ return PTS_PCR_TRANSFORM_SHORT;
+}
+
diff --git a/src/libpts/pts/components/pts_comp_evidence.h b/src/libpts/pts/components/pts_comp_evidence.h
new file mode 100644
index 000000000..fe86aa940
--- /dev/null
+++ b/src/libpts/pts/components/pts_comp_evidence.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu, 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 pts_comp_evidence pts_comp_evidence
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_COMP_EVIDENCE_H_
+#define PTS_COMP_EVIDENCE_H_
+
+typedef struct pts_comp_evidence_t pts_comp_evidence_t;
+typedef enum pts_pcr_transform_t pts_pcr_transform_t;
+typedef enum pts_comp_evid_validation_t pts_comp_evid_validation_t;
+
+#include "pts/pts_meas_algo.h"
+#include "pts/components/pts_comp_func_name.h"
+
+#include <library.h>
+
+/**
+ * PTS PCR Transformations
+ */
+enum pts_pcr_transform_t {
+ /** No Transformation */
+ PTS_PCR_TRANSFORM_NO = 0,
+ /** Hash Value matched PCR size */
+ PTS_PCR_TRANSFORM_MATCH = 1,
+ /** Hash value shorter than PCR size */
+ PTS_PCR_TRANSFORM_SHORT = 2,
+ /** Hash value longer than PCR size */
+ PTS_PCR_TRANSFORM_LONG = 3,
+};
+
+/**
+ * PTS Component Evidence Validation Result Flags
+ */
+enum pts_comp_evid_validation_t {
+ /** No Validation was attempted */
+ PTS_COMP_EVID_VALIDATION_NONE = 0x00,
+ /** Attempted validation, unable to verify */
+ PTS_COMP_EVID_VALIDATION_UNABLE = 0x20,
+ /** Attempted validation, verification failed */
+ PTS_COMP_EVID_VALIDATION_FAILED = 0x40,
+ /** Attempted validation, verification passed */
+ PTS_COMP_EVID_VALIDATION_PASSED = 0x60,
+};
+
+/**
+ * PTS Functional Component Interface
+ */
+struct pts_comp_evidence_t {
+
+ /**
+ * Gets the Component Functional Name and Sub-Component Depth
+ *
+ * @param depth Sub-Component Depth
+ * @result Component Functional Name
+ */
+ pts_comp_func_name_t* (*get_comp_func_name)(pts_comp_evidence_t *this,
+ u_int32_t *depth);
+
+ /**
+ * Gets the PCR the measurement was extended into
+ *
+ * @result PCR the measurement was extended into
+ */
+ u_int32_t (*get_extended_pcr)(pts_comp_evidence_t *this);
+
+ /**
+ * Gets the measurement and the algorithms used
+ *
+ * @param extended_pcr PCR the measurement was extended into
+ * @param algo Measurement hash algorithm
+ * @param transform Transformation used for PCR extension
+ * @param measurement_time Time the measurement was taken
+ * @result Measurement hash value
+ */
+ chunk_t (*get_measurement)(pts_comp_evidence_t *this,
+ u_int32_t *extended_pcr,
+ pts_meas_algorithms_t *algo,
+ pts_pcr_transform_t *transform,
+ time_t *measurement_time);
+
+ /**
+ * Gets the PCR information if available
+ *
+ * @param pcr_before PCR value before extension
+ * @param pcr_after PCR value after extension
+ * @result TRUE if PCR information is available
+ */
+ bool (*get_pcr_info)(pts_comp_evidence_t *this, chunk_t *pcr_before,
+ chunk_t *pcr_after);
+
+ /**
+ * Sets PCR information if available
+ *
+ * @param pcr_before PCR value before extension
+ * @param pcr_after PCR value after extension
+ */
+ void (*set_pcr_info)(pts_comp_evidence_t *this, chunk_t pcr_before,
+ chunk_t pcr_after);
+
+ /**
+ * Gets Validation Result if available
+ *
+ * @param uri Verification Policy URI
+ * @return validation Validation Result
+ */
+ pts_comp_evid_validation_t (*get_validation)(pts_comp_evidence_t *this,
+ chunk_t *uri);
+
+ /**
+ * Sets Validation Result if available
+ *
+ * @param validation Validation Result
+ * @param uri Verification Policy URI
+ */
+ void (*set_validation)(pts_comp_evidence_t *this,
+ pts_comp_evid_validation_t validation, chunk_t uri);
+
+ /**
+ * Destroys a pts_comp_evidence_t object.
+ */
+ void (*destroy)(pts_comp_evidence_t *this);
+
+};
+
+/**
+ * Creates a pts_comp_evidence_t object
+ *
+ * @param name Component Functional Name
+ * @param depth Sub-component depth
+ * @param extended_pcr PCR the measurement was extended into
+ * @param algo Measurement hash algorithm
+ * @param transform Transformation used for PCR extension
+ * @param measurement_time Time the measurement was taken, 0 if unknown
+ * @param measurement Measurement hash value
+ */
+pts_comp_evidence_t* pts_comp_evidence_create(pts_comp_func_name_t *name,
+ u_int32_t depth,
+ u_int32_t extended_pcr,
+ pts_meas_algorithms_t algo,
+ pts_pcr_transform_t transform,
+ time_t measurement_time,
+ chunk_t measurement);
+
+/**
+ * Determine transform to fit measurement hash into PCR register
+ *
+ * @param algo Measurement hash algorithm
+ * @param pcr_len Length of the PCR registers in bytes
+ * @return PCR transform type
+ */
+pts_pcr_transform_t pts_meas_algo_to_pcr_transform(pts_meas_algorithms_t algo,
+ size_t pcr_len);
+
+#endif /** PTS_COMP_EVIDENCE_H_ @}*/
diff --git a/src/libpts/pts/components/pts_comp_func_name.c b/src/libpts/pts/components/pts_comp_func_name.c
new file mode 100644
index 000000000..d98850d78
--- /dev/null
+++ b/src/libpts/pts/components/pts_comp_func_name.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2011 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 "libpts.h"
+#include "pts/components/pts_comp_func_name.h"
+
+#include <debug.h>
+
+typedef struct private_pts_comp_func_name_t private_pts_comp_func_name_t;
+
+/**
+ * Private data of a pts_comp_func_name_t object.
+ *
+ */
+struct private_pts_comp_func_name_t {
+
+ /**
+ * Public pts_comp_func_name_t interface.
+ */
+ pts_comp_func_name_t public;
+
+ /**
+ * PTS Component Functional Name Vendor ID
+ */
+ u_int32_t vid;
+
+ /**
+ * PTS Component Functional Name
+ */
+ u_int32_t name;
+
+ /**
+ * PTS Component Functional Name Qualifier
+ */
+ u_int8_t qualifier;
+
+};
+
+METHOD(pts_comp_func_name_t, get_vendor_id, u_int32_t,
+ private_pts_comp_func_name_t *this)
+{
+ return this->vid;
+}
+
+METHOD(pts_comp_func_name_t, get_name, u_int32_t,
+ private_pts_comp_func_name_t *this)
+{
+ return this->name;
+}
+
+METHOD(pts_comp_func_name_t, get_qualifier, u_int8_t,
+ private_pts_comp_func_name_t *this)
+{
+ return this->qualifier;
+}
+
+static bool equals(private_pts_comp_func_name_t *this,
+ private_pts_comp_func_name_t *other)
+{
+ if (this->vid != other->vid || this->name != other->name)
+ {
+ return FALSE;
+ }
+ if (this->qualifier == PTS_QUALIFIER_UNKNOWN ||
+ other->qualifier == PTS_QUALIFIER_UNKNOWN)
+ {
+ return TRUE;
+ }
+ /* TODO handle qualifier wildcards */
+
+ return this->qualifier == other->qualifier;
+}
+
+METHOD(pts_comp_func_name_t, clone_, pts_comp_func_name_t*,
+ private_pts_comp_func_name_t *this)
+{
+ private_pts_comp_func_name_t *clone;
+
+ clone = malloc_thing(private_pts_comp_func_name_t);
+ memcpy(clone, this, sizeof(private_pts_comp_func_name_t));
+
+ return &clone->public;
+}
+
+METHOD(pts_comp_func_name_t, log_, void,
+ private_pts_comp_func_name_t *this, char *label)
+{
+ enum_name_t *names, *types;
+ char flags[8];
+ int type;
+
+ names = pts_components->get_comp_func_names(pts_components, this->vid);
+ types = pts_components->get_qualifier_type_names(pts_components, this->vid);
+ type = pts_components->get_qualifier(pts_components, &this->public, flags);
+
+ if (names && types)
+ {
+ DBG2(DBG_PTS, "%s%N functional component '%N' [%s] '%N'",
+ label, pen_names, this->vid, names, this->name, flags, types, type);
+ }
+ else
+ {
+ DBG2(DBG_PTS, "%s0x%06x functional component 0x%08x 0x%02x",
+ label, this->vid, this->name, this->qualifier);
+ }
+}
+
+METHOD(pts_comp_func_name_t, destroy, void,
+ private_pts_comp_func_name_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_comp_func_name_t* pts_comp_func_name_create(u_int32_t vid, u_int32_t name,
+ u_int8_t qualifier)
+{
+ private_pts_comp_func_name_t *this;
+
+ INIT(this,
+ .public = {
+ .get_vendor_id = _get_vendor_id,
+ .get_name = _get_name,
+ .get_qualifier = _get_qualifier,
+ .equals = (bool(*)(pts_comp_func_name_t*,pts_comp_func_name_t*))equals,
+ .clone = _clone_,
+ .log = _log_,
+ .destroy = _destroy,
+ },
+ .vid = vid,
+ .name = name,
+ .qualifier = qualifier,
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/components/pts_comp_func_name.h b/src/libpts/pts/components/pts_comp_func_name.h
new file mode 100644
index 000000000..2c7a84177
--- /dev/null
+++ b/src/libpts/pts/components/pts_comp_func_name.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_comp_func_name pts_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_FUNC_COMP_NAME_H_
+#define PTS_FUNC_COMP_NAME_H_
+
+typedef struct pts_comp_func_name_t pts_comp_func_name_t;
+
+#include <library.h>
+
+#define PTS_QUALIFIER_UNKNOWN 0x00
+#define PTS_QUALIFIER_WILDCARD 0x3F
+
+/**
+ * PTS Component Functional Name object
+ */
+struct pts_comp_func_name_t {
+
+ /**
+ * Get the PTS Component Functional Name Vendor ID
+ *
+ * @return PTS Component Functional Name Vendor ID
+ */
+ u_int32_t (*get_vendor_id)(pts_comp_func_name_t *this);
+
+ /**
+ * Get the PTS Component Functional Name
+ *
+ * @return PTS Component Functional Name
+ */
+ u_int32_t (*get_name)(pts_comp_func_name_t *this);
+
+ /**
+ * Get the PTS Component Functional Name Qualifier
+ *
+ * @return PTS Component Functional Name Qualifier
+ */
+ u_int8_t (*get_qualifier)(pts_comp_func_name_t *this);
+
+ /**
+ * Check to PTS Component Functional Names for equality
+ *
+ * @param other Other PTS Component Functional Name
+ * @return TRUE if equal
+ */
+ bool (*equals)(pts_comp_func_name_t *this, pts_comp_func_name_t *other);
+
+ /**
+ * Clone a PTS Component Functional Name
+ *
+ * @return Cloned PTS Component Functional Name
+ */
+ pts_comp_func_name_t* (*clone)(pts_comp_func_name_t *this);
+
+ /**
+ * Write PTS Component Functional Name information to the standard logfile
+ *
+ * @param label Label added to log output
+ */
+ void (*log)(pts_comp_func_name_t *this, char *label);
+
+ /**
+ * Destroys a pts_component_t object.
+ */
+ void (*destroy)(pts_comp_func_name_t *this);
+
+};
+
+/**
+ * Create a PTS Component Functional Name object
+ *
+ * @param vid PTS Component Functional Name Vendor ID
+ * @param name PTS Component Functional Name
+ * @param PTS Component Functional Name Qualifier
+ */
+pts_comp_func_name_t* pts_comp_func_name_create(u_int32_t vid, u_int32_t name,
+ u_int8_t qualifier);
+
+#endif /** PTS_FUNC_COMP_NAME_H_ @}*/
diff --git a/src/libpts/pts/components/pts_component.h b/src/libpts/pts/components/pts_component.h
new file mode 100644
index 000000000..524ff332d
--- /dev/null
+++ b/src/libpts/pts/components/pts_component.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 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 pts_component pts_component
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_COMPONENT_H_
+#define PTS_COMPONENT_H_
+
+typedef struct pts_component_t pts_component_t;
+
+#include "pts/pts.h"
+#include "pts/pts_database.h"
+#include "pts/components/pts_comp_func_name.h"
+#include "pts/components/pts_comp_evidence.h"
+
+#include <library.h>
+
+/**
+ * PTS Functional Component Interface
+ */
+struct pts_component_t {
+
+ /**
+ * Get the PTS Component Functional Name
+ *
+ * @return PTS Component Functional Name
+ */
+ pts_comp_func_name_t* (*get_comp_func_name)(pts_component_t *this);
+
+ /**
+ * Get the PTS Component Evidence Flags
+ *
+ * @return PTS Component Functional Name
+ */
+ u_int8_t (*get_evidence_flags)(pts_component_t *this);
+
+ /**
+ * Get the PTS Sub-component Depth
+ *
+ * @return PTS Sub-component Depth
+ */
+ u_int32_t (*get_depth)(pts_component_t *this);
+
+ /**
+ * Do evidence measurements on the PTS Functional Component
+ *
+ * @param pts PTS interface
+ * @param evidence returns component evidence measureemt
+ * @return status return code
+ */
+ status_t (*measure)(pts_component_t *this, pts_t *pts,
+ pts_comp_evidence_t** evidence);
+
+ /**
+ * Verify the evidence measurements of the PTS Functional Component
+ *
+ * @param pts PTS interface
+ * @param evidence component evidence measurement to be verified
+ * @return status return code
+ */
+ status_t (*verify)(pts_component_t *this, pts_t *pts,
+ pts_comp_evidence_t *evidence);
+
+
+ /**
+ * Tell the PTS Functional Component to finalize pending registrations
+ *
+ * @return TRUE if there are pending registrations
+ */
+ bool (*check_off_registrations)(pts_component_t *this);
+
+ /**
+ * Destroys a pts_component_t object.
+ */
+ void (*destroy)(pts_component_t *this);
+
+};
+
+#endif /** PTS_COMPONENT_H_ @}*/
diff --git a/src/libpts/pts/components/pts_component_manager.c b/src/libpts/pts/components/pts_component_manager.c
new file mode 100644
index 000000000..8ac4767bf
--- /dev/null
+++ b/src/libpts/pts/components/pts_component_manager.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2011 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 "pts/components/pts_component_manager.h"
+
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_pts_component_manager_t private_pts_component_manager_t;
+typedef struct vendor_entry_t vendor_entry_t;
+typedef struct component_entry_t component_entry_t;
+
+#define PTS_QUALIFIER_SIZE 6
+
+/**
+ * Vendor-specific namespace information and list of registered components
+ */
+struct vendor_entry_t {
+
+ /**
+ * Vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Vendor-specific Component Functional names
+ */
+ enum_name_t *comp_func_names;
+
+ /**
+ * Vendor-specific Qualifier Type names
+ */
+ enum_name_t *qualifier_type_names;
+
+ /**
+ * Vendor-specific Qualifier Flag names
+ */
+ char *qualifier_flag_names;
+
+ /**
+ * Vendor-specific size of Qualfiier Type field
+ */
+ int qualifier_type_size;
+
+ /**
+ * List of vendor-specific registered Functional Components
+ */
+ linked_list_t *components;
+};
+
+/**
+ * Destroy a vendor_entry_t object
+ */
+static void vendor_entry_destroy(vendor_entry_t *entry)
+{
+ entry->components->destroy_function(entry->components, free);
+ free(entry);
+}
+
+/**
+ * Creation method for a vendor-specific Functional Component
+ */
+struct component_entry_t {
+
+ /**
+ * Vendor-Specific Component Functional Name
+ */
+ u_int32_t name;
+
+ /**
+ * Functional Component creation method
+ */
+ pts_component_create_t create;
+};
+
+/**
+ * Private data of a pts_component_manager_t object.
+ *
+ */
+struct private_pts_component_manager_t {
+
+ /**
+ * Public pts_component_manager_t interface.
+ */
+ pts_component_manager_t public;
+
+ /**
+ * List of vendor-specific namespaces and registered components
+ */
+ linked_list_t *list;
+};
+
+METHOD(pts_component_manager_t, add_vendor, void,
+ private_pts_component_manager_t *this, pen_t vendor_id,
+ enum_name_t *comp_func_names, int qualifier_type_size,
+ char *qualifier_flag_names, enum_name_t *qualifier_type_names)
+{
+ vendor_entry_t *entry;
+
+ entry = malloc_thing(vendor_entry_t);
+ entry->vendor_id = vendor_id;
+ entry->comp_func_names = comp_func_names;
+ entry->qualifier_type_size = qualifier_type_size;
+ entry->qualifier_flag_names = qualifier_flag_names;
+ entry->qualifier_type_names = qualifier_type_names;
+ entry->components = linked_list_create();
+
+ this->list->insert_last(this->list, entry);
+ DBG2(DBG_PTS, "added %N functional component namespace",
+ pen_names, vendor_id);
+}
+
+METHOD(pts_component_manager_t, get_comp_func_names, enum_name_t*,
+ private_pts_component_manager_t *this, pen_t vendor_id)
+{
+ enumerator_t *enumerator;
+ vendor_entry_t *entry;
+ enum_name_t *names = NULL;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ names = entry->comp_func_names;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return names;
+}
+
+METHOD(pts_component_manager_t, get_qualifier_type_names, enum_name_t*,
+ private_pts_component_manager_t *this, pen_t vendor_id)
+{
+ enumerator_t *enumerator;
+ vendor_entry_t *entry;
+ enum_name_t *names = NULL;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ names = entry->qualifier_type_names;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return names;
+}
+
+METHOD(pts_component_manager_t, add_component, void,
+ private_pts_component_manager_t *this, pen_t vendor_id, u_int32_t name,
+ pts_component_create_t create)
+{
+ enumerator_t *enumerator;
+ vendor_entry_t *entry;
+ component_entry_t *component;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ component = malloc_thing(component_entry_t);
+ component->name = name;
+ component->create = create;
+
+ entry->components->insert_last(entry->components, component);
+ DBG2(DBG_PTS, "added %N functional component '%N'",
+ pen_names, vendor_id,
+ get_comp_func_names(this, vendor_id), name);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(pts_component_manager_t, remove_vendor, void,
+ private_pts_component_manager_t *this, pen_t vendor_id)
+{
+ enumerator_t *enumerator;
+ vendor_entry_t *entry;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ this->list->remove_at(this->list, enumerator);
+ vendor_entry_destroy(entry);
+ DBG2(DBG_PTS, "removed %N functional component namespace",
+ pen_names, vendor_id);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(pts_component_manager_t, get_qualifier, u_int8_t,
+ private_pts_component_manager_t *this, pts_comp_func_name_t *name,
+ char *flags)
+{
+ enumerator_t *enumerator;
+ vendor_entry_t *entry;
+ u_int8_t qualifier, size, flag, type = 0;
+ int i;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == name->get_vendor_id(name))
+ {
+ qualifier = name->get_qualifier(name);
+ size = entry->qualifier_type_size;
+
+ /* mask qualifier type field */
+ type = qualifier & ((1 << size) - 1);
+
+ /* determine flags */
+ size = PTS_QUALIFIER_SIZE - size;
+ flag = (1 << (PTS_QUALIFIER_SIZE - 1));
+ if (flags)
+ {
+ for (i = 0 ; i < size; i++)
+ {
+ flags[i] = (qualifier & flag) ?
+ entry->qualifier_flag_names[i] : '.';
+ flag >>= 1;
+ }
+ flags[size] = '\0';
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return type;
+}
+
+METHOD(pts_component_manager_t, create, pts_component_t*,
+ private_pts_component_manager_t *this,
+ pts_comp_func_name_t *name, u_int32_t depth, pts_database_t *pts_db)
+{
+ enumerator_t *enumerator, *e2;
+ vendor_entry_t *entry;
+ component_entry_t *entry2;
+ pts_component_t *component = NULL;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == name->get_vendor_id(name))
+ {
+ e2 = entry->components->create_enumerator(entry->components);
+ while (e2->enumerate(e2, &entry2))
+ {
+ if (entry2->name == name->get_name(name) && entry2->create)
+ {
+ component = entry2->create(name->get_qualifier(name),
+ depth, pts_db);
+ break;
+ }
+ }
+ e2->destroy(e2);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return component;
+}
+
+METHOD(pts_component_manager_t, destroy, void,
+ private_pts_component_manager_t *this)
+{
+ this->list->destroy_function(this->list, (void *)vendor_entry_destroy);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_component_manager_t *pts_component_manager_create(void)
+{
+ private_pts_component_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .add_vendor = _add_vendor,
+ .add_component = _add_component,
+ .remove_vendor = _remove_vendor,
+ .get_comp_func_names = _get_comp_func_names,
+ .get_qualifier_type_names = _get_qualifier_type_names,
+ .get_qualifier = _get_qualifier,
+ .create = _create,
+ .destroy = _destroy,
+ },
+ .list = linked_list_create(),
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/components/pts_component_manager.h b/src/libpts/pts/components/pts_component_manager.h
new file mode 100644
index 000000000..0079d0e26
--- /dev/null
+++ b/src/libpts/pts/components/pts_component_manager.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 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 pts_component_manager pts_component_manager
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_COMPONENT_MANAGER_H_
+#define PTS_COMPONENT_MANAGER_H_
+
+typedef struct pts_component_manager_t pts_component_manager_t;
+
+#include "pts/pts_database.h"
+#include "pts/components/pts_component.h"
+#include "pts/components/pts_comp_func_name.h"
+
+#include <library.h>
+#include <pen/pen.h>
+
+typedef pts_component_t* (*pts_component_create_t)(u_int8_t qualifier,
+ u_int32_t depth,
+ pts_database_t *pts_db);
+
+/**
+ * Manages PTS Functional Components
+ */
+struct pts_component_manager_t {
+
+ /**
+ * Add vendor-specific functional component names
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ * @param comp_func_names Vendor-specific Component Functional names
+ * @param qualifier_type_size Vendor-specific Qualifier Type size
+ * @param qualifier_flag_names Vendor-specific Qualifier Flag names
+ * @param qualifier_type_names Vendor-specific Qualifier Type names
+ */
+ void (*add_vendor)(pts_component_manager_t *this, pen_t vendor_id,
+ enum_name_t *comp_func_names,
+ int qualifier_type_size,
+ char *qualifier_flag_names,
+ enum_name_t *qualifier_type_names);
+
+ /**
+ * Add vendor-specific functional component
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ * @param names Component Functional Name
+ * @param create Functional Component creation method
+ */
+ void (*add_component)(pts_component_manager_t *this, pen_t vendor_id,
+ u_int32_t name, pts_component_create_t create);
+
+ /**
+ * Remove vendor-specific components and associated namespace
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ */
+ void (*remove_vendor)(pts_component_manager_t *this, pen_t vendor_id);
+
+ /**
+ * Return the Functional Component names for a given vendor ID
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ * @return Comp. Func. names if found, NULL else
+ */
+ enum_name_t* (*get_comp_func_names)(pts_component_manager_t *this,
+ pen_t vendor_id);
+
+ /**
+ * Return the Functional Component Qualifier Type names for a given vendor ID
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ * @return Qualifier Type names if found, NULL else
+ */
+ enum_name_t* (*get_qualifier_type_names)(pts_component_manager_t *this,
+ pen_t vendor_id);
+
+ /**
+ * Return the Qualifier Type and Flags
+ *
+ * @param name Component Functional Name
+ * @param flags Qualifier Flags as a string in a char buffer
+ * @return Qualifier Type
+ */
+ u_int8_t (*get_qualifier)(pts_component_manager_t *this,
+ pts_comp_func_name_t *name, char *flags);
+
+ /**
+ * Create a PTS Component object from a Functional Component Name object
+ *
+ * @param name Component Functional Name
+ * @param depth Sub-component Depth
+ * @param pts_db PTS measurement database
+ * @return Component object if supported, NULL else
+ */
+ pts_component_t* (*create)(pts_component_manager_t *this,
+ pts_comp_func_name_t *name, u_int32_t depth,
+ pts_database_t *pts_db);
+
+ /**
+ * Destroys a pts_component_manager_t object.
+ */
+ void (*destroy)(pts_component_manager_t *this);
+};
+
+/**
+ * Create a PA-TNC attribute manager
+ */
+pts_component_manager_t* pts_component_manager_create(void);
+
+#endif /** PTS_COMPONENT_MANAGER_H_ @}*/
diff --git a/src/libpts/pts/components/tcg/tcg_comp_func_name.c b/src/libpts/pts/components/tcg/tcg_comp_func_name.c
new file mode 100644
index 000000000..a70c84e48
--- /dev/null
+++ b/src/libpts/pts/components/tcg/tcg_comp_func_name.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 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 "tcg_comp_func_name.h"
+
+char pts_tcg_qualifier_flag_names[] = { 'K', 'S' };
+
+ENUM_BEGIN(pts_tcg_qualifier_type_names, PTS_TCG_QUALIFIER_TYPE_UNKNOWN,
+ PTS_TCG_QUALIFIER_TYPE_TNC,
+ "Unknown",
+ "Trusted Platform",
+ "Operating System",
+ "Graphical User Interface",
+ "Application",
+ "Networking",
+ "Library",
+ "TNC Defined Component"
+);
+ENUM_NEXT(pts_tcg_qualifier_type_names, PTS_TCG_QUALIFIER_TYPE_ALL,
+ PTS_TCG_QUALIFIER_TYPE_ALL,
+ PTS_TCG_QUALIFIER_TYPE_TNC,
+ "All Matching Components"
+);
+ENUM_END(pts_tcg_qualifier_type_names, PTS_TCG_QUALIFIER_TYPE_ALL);
+
+ENUM(pts_tcg_comp_func_names, PTS_TCG_COMP_FUNC_NAME_IGNORE,
+ PTS_TCG_COMP_FUNC_NAME_OPT_ROMS,
+ "Ignore",
+ "CRTM",
+ "BIOS",
+ "Platform Extensions",
+ "Motherboard Firmware",
+ "Initial Program Loader",
+ "Option ROMs"
+);
+
diff --git a/src/libpts/pts/components/tcg/tcg_comp_func_name.h b/src/libpts/pts/components/tcg/tcg_comp_func_name.h
new file mode 100644
index 000000000..9708ad09d
--- /dev/null
+++ b/src/libpts/pts/components/tcg/tcg_comp_func_name.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_tcg_comp_func_name pts_tcg_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_TCG_COMP_FUNC_NAME_H_
+#define PTS_TCG_COMP_FUNC_NAME_H_
+
+typedef enum pts_tcg_qualifier_type_t pts_tcg_qualifier_type_t;
+typedef enum pts_tcg_comp_func_name_t pts_tcp_comp_func_name_t;
+
+#include <library.h>
+
+/**
+ * PTS Component Functional Name Qualifier Flags for the TCG namespace
+ * see section 5.2 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 0 1 2 3 4 5
+ * +-+-+-+-+-+-+
+ * |K|S| Type |
+ * +-+-+-+-+-+-+
+ */
+#define PTS_TCG_QUALIFIER_FLAG_KERNEL (1<<5)
+#define PTS_TCG_QUALIFIER_FLAG_SUB (1<<4)
+
+extern char pts_tcg_qualifier_flag_names[];
+
+/**
+ * Size of the PTS Component Functional Name Qualifier Type field
+ */
+#define PTS_TCG_QUALIFIER_TYPE_SIZE 4
+
+/**
+ * PTS Component Functional Name Qualifier Types for the TCG namespace
+ * see section 5.2 of PTS Protocol: Binding to TNC IF-M Specification
+ */
+enum pts_tcg_qualifier_type_t {
+ /** Unknown */
+ PTS_TCG_QUALIFIER_TYPE_UNKNOWN = 0x0,
+ /** Trusted Platform */
+ PTS_TCG_QUALIFIER_TYPE_TRUSTED = 0x1,
+ /** Operating System */
+ PTS_TCG_QUALIFIER_TYPE_OS = 0x2,
+ /** Graphical User Interface */
+ PTS_TCG_QUALIFIER_TYPE_GUI = 0x3,
+ /** Application */
+ PTS_TCG_QUALIFIER_TYPE_APP = 0x4,
+ /** Networking */
+ PTS_TCG_QUALIFIER_TYPE_NET = 0x5,
+ /** Library */
+ PTS_TCG_QUALIFIER_TYPE_LIB = 0x6,
+ /** TNC Defined Component */
+ PTS_TCG_QUALIFIER_TYPE_TNC = 0x7,
+ /** All matching Components */
+ PTS_TCG_QUALIFIER_TYPE_ALL = 0xF,
+};
+
+extern enum_name_t *pts_tcg_qualifier_type_names;
+
+/**
+ * PTS Component Functional Name Binary Enumeration for the TCG namespace
+ * see section 5.3 of PTS Protocol: Binding to TNC IF-M Specification
+ */
+enum pts_tcg_comp_func_name_t {
+ /** Ignore */
+ PTS_TCG_COMP_FUNC_NAME_IGNORE = 0x0000,
+ /** CRTM */
+ PTS_TCG_COMP_FUNC_NAME_CRTM = 0x0001,
+ /** BIOS */
+ PTS_TCG_COMP_FUNC_NAME_BIOS = 0x0002,
+ /** Platform Extensions */
+ PTS_TCG_COMP_FUNC_NAME_PLATFORM_EXT = 0x0003,
+ /** Motherboard Firmware */
+ PTS_TCG_COMP_FUNC_NAME_BOARD = 0x0004,
+ /** Initial Program Loader */
+ PTS_TCG_COMP_FUNC_NAME_INIT_LOADER = 0x0005,
+ /** Option ROMs */
+ PTS_TCG_COMP_FUNC_NAME_OPT_ROMS = 0x0006,
+};
+
+extern enum_name_t *pts_tcg_comp_func_names;
+
+#endif /** PTS_TCG_COMP_FUNC_NAME_H_ @}*/
diff --git a/src/libpts/pts/pts.c b/src/libpts/pts/pts.c
new file mode 100644
index 000000000..65ae2b2d2
--- /dev/null
+++ b/src/libpts/pts/pts.c
@@ -0,0 +1,1539 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "pts.h"
+
+#include <debug.h>
+#include <crypto/hashers/hasher.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+
+#include <trousers/tss.h>
+#include <trousers/trousers.h>
+
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <errno.h>
+
+#define PTS_BUF_SIZE 4096
+
+/**
+ * Maximum number of PCR's of TPM, TPM Spec 1.2
+ */
+#define PCR_MAX_NUM 24
+
+/**
+ * Number of bytes that can be saved in a PCR of TPM, TPM Spec 1.2
+ */
+#define PCR_LEN 20
+
+typedef struct private_pts_t private_pts_t;
+
+/**
+ * Private data of a pts_t object.
+ *
+ */
+struct private_pts_t {
+
+ /**
+ * Public pts_t interface.
+ */
+ pts_t public;
+
+ /**
+ * PTS Protocol Capabilities
+ */
+ pts_proto_caps_flag_t proto_caps;
+
+ /**
+ * PTS Measurement Algorithm
+ */
+ pts_meas_algorithms_t algorithm;
+
+ /**
+ * DH Hash Algorithm
+ */
+ pts_meas_algorithms_t dh_hash_algorithm;
+
+ /**
+ * PTS Diffie-Hellman Secret
+ */
+ diffie_hellman_t *dh;
+
+ /**
+ * PTS Diffie-Hellman Initiator Nonce
+ */
+ chunk_t initiator_nonce;
+
+ /**
+ * PTS Diffie-Hellman Responder Nonce
+ */
+ chunk_t responder_nonce;
+
+ /**
+ * Secret assessment value to be used for TPM Quote as an external data
+ */
+ chunk_t secret;
+
+ /**
+ * Platform and OS Info
+ */
+ char *platform_info;
+
+ /**
+ * TRUE if IMC-PTS, FALSE if IMV-PTS
+ */
+ bool is_imc;
+
+ /**
+ * Do we have an activated TPM
+ */
+ bool has_tpm;
+
+ /**
+ * Contains a TPM_CAP_VERSION_INFO struct
+ */
+ chunk_t tpm_version_info;
+
+ /**
+ * Contains TSS Blob structure for AIK
+ */
+ chunk_t aik_blob;
+
+ /**
+ * Contains a Attestation Identity Key or Certificate
+ */
+ certificate_t *aik;
+
+ /**
+ * Table of extended PCRs with corresponding values
+ */
+ u_char* pcrs[PCR_MAX_NUM];
+
+ /**
+ * Length of PCR registers
+ */
+ size_t pcr_len;
+
+ /**
+ * Number of extended PCR registers
+ */
+ u_int32_t pcr_count;
+
+ /**
+ * Highest extended PCR register
+ */
+ u_int32_t pcr_max;
+
+ /**
+ * Bitmap of extended PCR registers
+ */
+ u_int8_t pcr_select[PCR_MAX_NUM / 8];
+
+};
+
+METHOD(pts_t, get_proto_caps, pts_proto_caps_flag_t,
+ private_pts_t *this)
+{
+ return this->proto_caps;
+}
+
+METHOD(pts_t, set_proto_caps, void,
+ private_pts_t *this, pts_proto_caps_flag_t flags)
+{
+ this->proto_caps = flags;
+ DBG2(DBG_PTS, "supported PTS protocol capabilities: %s%s%s%s%s",
+ flags & PTS_PROTO_CAPS_C ? "C" : ".",
+ flags & PTS_PROTO_CAPS_V ? "V" : ".",
+ flags & PTS_PROTO_CAPS_D ? "D" : ".",
+ flags & PTS_PROTO_CAPS_T ? "T" : ".",
+ flags & PTS_PROTO_CAPS_X ? "X" : ".");
+}
+
+METHOD(pts_t, get_meas_algorithm, pts_meas_algorithms_t,
+ private_pts_t *this)
+{
+ return this->algorithm;
+}
+
+METHOD(pts_t, set_meas_algorithm, void,
+ private_pts_t *this, pts_meas_algorithms_t algorithm)
+{
+ hash_algorithm_t hash_alg;
+
+ hash_alg = pts_meas_algo_to_hash(algorithm);
+ DBG2(DBG_PTS, "selected PTS measurement algorithm is %N",
+ hash_algorithm_names, hash_alg);
+ if (hash_alg != HASH_UNKNOWN)
+ {
+ this->algorithm = algorithm;
+ }
+}
+
+METHOD(pts_t, get_dh_hash_algorithm, pts_meas_algorithms_t,
+ private_pts_t *this)
+{
+ return this->dh_hash_algorithm;
+}
+
+METHOD(pts_t, set_dh_hash_algorithm, void,
+ private_pts_t *this, pts_meas_algorithms_t algorithm)
+{
+ hash_algorithm_t hash_alg;
+
+ hash_alg = pts_meas_algo_to_hash(algorithm);
+ DBG2(DBG_PTS, "selected DH hash algorithm is %N",
+ hash_algorithm_names, hash_alg);
+ if (hash_alg != HASH_UNKNOWN)
+ {
+ this->dh_hash_algorithm = algorithm;
+ }
+}
+
+
+METHOD(pts_t, create_dh_nonce, bool,
+ private_pts_t *this, pts_dh_group_t group, int nonce_len)
+{
+ diffie_hellman_group_t dh_group;
+ chunk_t *nonce;
+ rng_t *rng;
+
+ dh_group = pts_dh_group_to_ike(group);
+ DBG2(DBG_PTS, "selected PTS DH group is %N",
+ diffie_hellman_group_names, dh_group);
+ DESTROY_IF(this->dh);
+ this->dh = lib->crypto->create_dh(lib->crypto, dh_group);
+
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ if (!rng)
+ {
+ DBG1(DBG_PTS, "no rng available");
+ return FALSE;
+ }
+ DBG2(DBG_PTS, "nonce length is %d", nonce_len);
+ nonce = this->is_imc ? &this->responder_nonce : &this->initiator_nonce;
+ chunk_free(nonce);
+ rng->allocate_bytes(rng, nonce_len, nonce);
+ rng->destroy(rng);
+
+ return TRUE;
+}
+
+METHOD(pts_t, get_my_public_value, void,
+ private_pts_t *this, chunk_t *value, chunk_t *nonce)
+{
+ this->dh->get_my_public_value(this->dh, value);
+ *nonce = this->is_imc ? this->responder_nonce : this->initiator_nonce;
+}
+
+METHOD(pts_t, set_peer_public_value, void,
+ private_pts_t *this, chunk_t value, chunk_t nonce)
+{
+ this->dh->set_other_public_value(this->dh, value);
+
+ nonce = chunk_clone(nonce);
+ if (this->is_imc)
+ {
+ this->initiator_nonce = nonce;
+ }
+ else
+ {
+ this->responder_nonce = nonce;
+ }
+}
+
+METHOD(pts_t, calculate_secret, bool,
+ private_pts_t *this)
+{
+ hasher_t *hasher;
+ hash_algorithm_t hash_alg;
+ chunk_t shared_secret;
+
+ /* Check presence of nonces */
+ if (!this->initiator_nonce.len || !this->responder_nonce.len)
+ {
+ DBG1(DBG_PTS, "initiator and/or responder nonce is not available");
+ return FALSE;
+ }
+ DBG3(DBG_PTS, "initiator nonce: %B", &this->initiator_nonce);
+ DBG3(DBG_PTS, "responder nonce: %B", &this->responder_nonce);
+
+ /* Calculate the DH secret */
+ if (this->dh->get_shared_secret(this->dh, &shared_secret) != SUCCESS)
+ {
+ DBG1(DBG_PTS, "shared DH secret computation failed");
+ return FALSE;
+ }
+ DBG3(DBG_PTS, "shared DH secret: %B", &shared_secret);
+
+ /* Calculate the secret assessment value */
+ hash_alg = pts_meas_algo_to_hash(this->dh_hash_algorithm);
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
+
+ hasher->allocate_hash(hasher, chunk_from_chars('1'), NULL);
+ hasher->allocate_hash(hasher, this->initiator_nonce, NULL);
+ hasher->allocate_hash(hasher, this->responder_nonce, NULL);
+ hasher->allocate_hash(hasher, shared_secret, &this->secret);
+ hasher->destroy(hasher);
+
+ /* The DH secret must be destroyed */
+ chunk_clear(&shared_secret);
+
+ /*
+ * Truncate the hash to 20 bytes to fit the ExternalData
+ * argument of the TPM Quote command
+ */
+ this->secret.len = min(this->secret.len, 20);
+ DBG3(DBG_PTS, "secret assessment value: %B", &this->secret);
+ return TRUE;
+}
+
+/**
+ * Print TPM 1.2 Version Info
+ */
+static void print_tpm_version_info(private_pts_t *this)
+{
+ TPM_CAP_VERSION_INFO versionInfo;
+ UINT64 offset = 0;
+ TSS_RESULT result;
+
+ result = Trspi_UnloadBlob_CAP_VERSION_INFO(&offset,
+ this->tpm_version_info.ptr, &versionInfo);
+ if (result != TSS_SUCCESS)
+ {
+ DBG1(DBG_PTS, "could not parse tpm version info: tss error 0x%x",
+ result);
+ }
+ else
+ {
+ DBG2(DBG_PTS, "TPM 1.2 Version Info: Chip Version: %hhu.%hhu.%hhu.%hhu,"
+ " Spec Level: %hu, Errata Rev: %hhu, Vendor ID: %.4s",
+ versionInfo.version.major, versionInfo.version.minor,
+ versionInfo.version.revMajor, versionInfo.version.revMinor,
+ versionInfo.specLevel, versionInfo.errataRev,
+ versionInfo.tpmVendorID);
+ }
+}
+
+METHOD(pts_t, get_platform_info, char*,
+ private_pts_t *this)
+{
+ return this->platform_info;
+}
+
+METHOD(pts_t, set_platform_info, void,
+ private_pts_t *this, char *info)
+{
+ free(this->platform_info);
+ this->platform_info = strdup(info);
+}
+
+METHOD(pts_t, get_tpm_version_info, bool,
+ private_pts_t *this, chunk_t *info)
+{
+ if (!this->has_tpm)
+ {
+ return FALSE;
+ }
+ *info = this->tpm_version_info;
+ print_tpm_version_info(this);
+ return TRUE;
+}
+
+METHOD(pts_t, set_tpm_version_info, void,
+ private_pts_t *this, chunk_t info)
+{
+ this->tpm_version_info = chunk_clone(info);
+ print_tpm_version_info(this);
+}
+
+METHOD(pts_t, get_pcr_len, size_t,
+ private_pts_t *this)
+{
+ return this->pcr_len;
+}
+
+/**
+ * Load an AIK Blob (TSS_TSPATTRIB_KEYBLOB_BLOB attribute)
+ */
+static void load_aik_blob(private_pts_t *this)
+{
+ char *blob_path;
+ FILE *fp;
+ u_int32_t aikBlobLen;
+
+ blob_path = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.aik_blob", NULL);
+
+ if (blob_path)
+ {
+ /* Read aik key blob from a file */
+ if ((fp = fopen(blob_path, "r")) == NULL)
+ {
+ DBG1(DBG_PTS, "unable to open AIK Blob file: %s", blob_path);
+ return;
+ }
+
+ fseek(fp, 0, SEEK_END);
+ aikBlobLen = ftell(fp);
+ fseek(fp, 0L, SEEK_SET);
+
+ this->aik_blob = chunk_alloc(aikBlobLen);
+ if (fread(this->aik_blob.ptr, 1, aikBlobLen, fp))
+ {
+ DBG2(DBG_PTS, "loaded AIK Blob from '%s'", blob_path);
+ DBG3(DBG_PTS, "AIK Blob: %B", &this->aik_blob);
+ }
+ else
+ {
+ DBG1(DBG_PTS, "unable to read AIK Blob file '%s'", blob_path);
+ }
+ fclose(fp);
+ return;
+ }
+
+ DBG1(DBG_PTS, "AIK Blob is not available");
+}
+
+/**
+ * Load an AIK certificate or public key
+ * the certificate having precedence over the public key if both are present
+ */
+static void load_aik(private_pts_t *this)
+{
+ char *cert_path, *key_path;
+
+ cert_path = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.aik_cert", NULL);
+ key_path = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.aik_key", NULL);
+
+ if (cert_path)
+ {
+ this->aik = lib->creds->create(lib->creds, CRED_CERTIFICATE,
+ CERT_X509, BUILD_FROM_FILE,
+ cert_path, BUILD_END);
+ if (this->aik)
+ {
+ DBG2(DBG_PTS, "loaded AIK certificate from '%s'", cert_path);
+ return;
+ }
+ }
+ if (key_path)
+ {
+ this->aik = lib->creds->create(lib->creds, CRED_CERTIFICATE,
+ CERT_TRUSTED_PUBKEY, BUILD_FROM_FILE,
+ key_path, BUILD_END);
+ if (this->aik)
+ {
+ DBG2(DBG_PTS, "loaded AIK public key from '%s'", key_path);
+ return;
+ }
+ }
+
+ DBG1(DBG_PTS, "neither AIK certificate nor public key is available");
+}
+
+METHOD(pts_t, get_aik, certificate_t*,
+ private_pts_t *this)
+{
+ return this->aik;
+}
+
+METHOD(pts_t, set_aik, void,
+ private_pts_t *this, certificate_t *aik)
+{
+ DESTROY_IF(this->aik);
+ this->aik = aik->get_ref(aik);
+}
+
+METHOD(pts_t, get_aik_keyid, bool,
+ private_pts_t *this, chunk_t *keyid)
+{
+ public_key_t *public;
+ bool success;
+
+ if (!this->aik)
+ {
+ DBG1(DBG_PTS, "no AIK certificate available");
+ return FALSE;
+ }
+ public = this->aik->get_public_key(this->aik);
+ if (!public)
+ {
+ DBG1(DBG_PTS, "no AIK public key available");
+ return FALSE;
+ }
+ success = public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, keyid);
+ if (!success)
+ {
+ DBG1(DBG_PTS, "no SHA-1 AIK public key info ID available");
+ }
+ public->destroy(public);
+
+ return success;
+}
+
+METHOD(pts_t, hash_file, bool,
+ private_pts_t *this, hasher_t *hasher, char *pathname, u_char *hash)
+{
+ u_char buffer[PTS_BUF_SIZE];
+ FILE *file;
+ int bytes_read;
+
+ file = fopen(pathname, "rb");
+ if (!file)
+ {
+ DBG1(DBG_PTS," file '%s' can not be opened, %s", pathname,
+ strerror(errno));
+ return FALSE;
+ }
+ while (TRUE)
+ {
+ bytes_read = fread(buffer, 1, sizeof(buffer), file);
+ if (bytes_read > 0)
+ {
+ hasher->get_hash(hasher, chunk_create(buffer, bytes_read), NULL);
+ }
+ else
+ {
+ hasher->get_hash(hasher, chunk_empty, hash);
+ break;
+ }
+ }
+ fclose(file);
+
+ return TRUE;
+}
+
+/**
+ * Get the relative filename of a fully qualified file pathname
+ */
+static char* get_filename(char *pathname)
+{
+ char *pos, *filename;
+
+ pos = filename = pathname;
+ while (pos && *(++pos) != '\0')
+ {
+ filename = pos;
+ pos = strchr(filename, '/');
+ }
+ return filename;
+}
+
+METHOD(pts_t, is_path_valid, bool,
+ private_pts_t *this, char *path, pts_error_code_t *error_code)
+{
+ struct stat st;
+
+ *error_code = 0;
+
+ if (!stat(path, &st))
+ {
+ return TRUE;
+ }
+ else if (errno == ENOENT || errno == ENOTDIR)
+ {
+ DBG1(DBG_PTS, "file/directory does not exist %s", path);
+ *error_code = TCG_PTS_FILE_NOT_FOUND;
+ }
+ else if (errno == EFAULT)
+ {
+ DBG1(DBG_PTS, "bad address %s", path);
+ *error_code = TCG_PTS_INVALID_PATH;
+ }
+ else
+ {
+ DBG1(DBG_PTS, "error: %s occurred while validating path: %s",
+ strerror(errno), path);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+METHOD(pts_t, do_measurements, pts_file_meas_t*,
+ private_pts_t *this, u_int16_t request_id, char *pathname, bool is_directory)
+{
+ hasher_t *hasher;
+ hash_algorithm_t hash_alg;
+ u_char hash[HASH_SIZE_SHA384];
+ chunk_t measurement;
+ pts_file_meas_t *measurements;
+
+ /* Create a hasher */
+ hash_alg = pts_meas_algo_to_hash(this->algorithm);
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
+ if (!hasher)
+ {
+ DBG1(DBG_PTS, "hasher %N not available", hash_algorithm_names, hash_alg);
+ return NULL;
+ }
+
+ /* Create a measurement object */
+ measurements = pts_file_meas_create(request_id);
+
+ /* Link the hash to the measurement and set the measurement length */
+ measurement = chunk_create(hash, hasher->get_hash_size(hasher));
+
+ if (is_directory)
+ {
+ enumerator_t *enumerator;
+ char *rel_name, *abs_name;
+ struct stat st;
+
+ enumerator = enumerator_create_directory(pathname);
+ if (!enumerator)
+ {
+ DBG1(DBG_PTS," directory '%s' can not be opened, %s", pathname,
+ strerror(errno));
+ hasher->destroy(hasher);
+ measurements->destroy(measurements);
+ return NULL;
+ }
+ while (enumerator->enumerate(enumerator, &rel_name, &abs_name, &st))
+ {
+ /* measure regular files only */
+ if (S_ISREG(st.st_mode) && *rel_name != '.')
+ {
+ if (!hash_file(this, hasher, abs_name, hash))
+ {
+ enumerator->destroy(enumerator);
+ hasher->destroy(hasher);
+ measurements->destroy(measurements);
+ return NULL;
+ }
+ DBG2(DBG_PTS, " %#B for '%s'", &measurement, rel_name);
+ measurements->add(measurements, rel_name, measurement);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ char *filename;
+
+ if (!hash_file(this, hasher, pathname, hash))
+ {
+ hasher->destroy(hasher);
+ measurements->destroy(measurements);
+ return NULL;
+ }
+ filename = get_filename(pathname);
+ DBG2(DBG_PTS, " %#B for '%s'", &measurement, filename);
+ measurements->add(measurements, filename, measurement);
+ }
+ hasher->destroy(hasher);
+
+ return measurements;
+}
+
+/**
+ * Obtain statistical information describing a file
+ */
+static bool file_metadata(char *pathname, pts_file_metadata_t **entry)
+{
+ struct stat st;
+ pts_file_metadata_t *this;
+
+ this = malloc_thing(pts_file_metadata_t);
+
+ if (stat(pathname, &st))
+ {
+ DBG1(DBG_PTS, "unable to obtain statistics about '%s'", pathname);
+ return FALSE;
+ }
+
+ if (S_ISREG(st.st_mode))
+ {
+ this->type = PTS_FILE_REGULAR;
+ }
+ else if (S_ISDIR(st.st_mode))
+ {
+ this->type = PTS_FILE_DIRECTORY;
+ }
+ else if (S_ISCHR(st.st_mode))
+ {
+ this->type = PTS_FILE_CHAR_SPEC;
+ }
+ else if (S_ISBLK(st.st_mode))
+ {
+ this->type = PTS_FILE_BLOCK_SPEC;
+ }
+ else if (S_ISFIFO(st.st_mode))
+ {
+ this->type = PTS_FILE_FIFO;
+ }
+ else if (S_ISLNK(st.st_mode))
+ {
+ this->type = PTS_FILE_SYM_LINK;
+ }
+ else if (S_ISSOCK(st.st_mode))
+ {
+ this->type = PTS_FILE_SOCKET;
+ }
+ else
+ {
+ this->type = PTS_FILE_OTHER;
+ }
+
+ this->filesize = st.st_size;
+ this->created = st.st_ctime;
+ this->modified = st.st_mtime;
+ this->accessed = st.st_atime;
+ this->owner = st.st_uid;
+ this->group = st.st_gid;
+
+ *entry = this;
+ return TRUE;
+}
+
+METHOD(pts_t, get_metadata, pts_file_meta_t*,
+ private_pts_t *this, char *pathname, bool is_directory)
+{
+ pts_file_meta_t *metadata;
+ pts_file_metadata_t *entry;
+
+ /* Create a metadata object */
+ metadata = pts_file_meta_create();
+
+ if (is_directory)
+ {
+ enumerator_t *enumerator;
+ char *rel_name, *abs_name;
+ struct stat st;
+
+ enumerator = enumerator_create_directory(pathname);
+ if (!enumerator)
+ {
+ DBG1(DBG_PTS," directory '%s' can not be opened, %s", pathname,
+ strerror(errno));
+ metadata->destroy(metadata);
+ return NULL;
+ }
+ while (enumerator->enumerate(enumerator, &rel_name, &abs_name, &st))
+ {
+ /* measure regular files only */
+ if (S_ISREG(st.st_mode) && *rel_name != '.')
+ {
+ if (!file_metadata(abs_name, &entry))
+ {
+ enumerator->destroy(enumerator);
+ metadata->destroy(metadata);
+ return NULL;
+ }
+ entry->filename = strdup(rel_name);
+ metadata->add(metadata, entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ if (!file_metadata(pathname, &entry))
+ {
+ metadata->destroy(metadata);
+ return NULL;
+ }
+ entry->filename = strdup(get_filename(pathname));
+ metadata->add(metadata, entry);
+ }
+
+ return metadata;
+}
+
+METHOD(pts_t, read_pcr, bool,
+ private_pts_t *this, u_int32_t pcr_num, chunk_t *pcr_value)
+{
+ TSS_HCONTEXT hContext;
+ TSS_HTPM hTPM;
+ TSS_RESULT result;
+ chunk_t rgbPcrValue;
+
+ bool success = FALSE;
+
+ result = Tspi_Context_Create(&hContext);
+ if (result != TSS_SUCCESS)
+ {
+ DBG1(DBG_PTS, "TPM context could not be created: tss error 0x%x", result);
+ return FALSE;
+ }
+
+ result = Tspi_Context_Connect(hContext, NULL);
+ if (result != TSS_SUCCESS)
+ {
+ goto err;
+ }
+ result = Tspi_Context_GetTpmObject (hContext, &hTPM);
+ if (result != TSS_SUCCESS)
+ {
+ goto err;
+ }
+ result = Tspi_TPM_PcrRead(hTPM, pcr_num, (UINT32*)&rgbPcrValue.len, &rgbPcrValue.ptr);
+ if (result != TSS_SUCCESS)
+ {
+ goto err;
+ }
+ *pcr_value = chunk_clone(rgbPcrValue);
+ DBG3(DBG_PTS, "PCR %d value:%B", pcr_num, pcr_value);
+ success = TRUE;
+
+err:
+ if (!success)
+ {
+ DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
+ }
+ Tspi_Context_FreeMemory(hContext, NULL);
+ Tspi_Context_Close(hContext);
+
+ return success;
+}
+
+METHOD(pts_t, extend_pcr, bool,
+ private_pts_t *this, u_int32_t pcr_num, chunk_t input, chunk_t *output)
+{
+ TSS_HCONTEXT hContext;
+ TSS_HTPM hTPM;
+ TSS_RESULT result;
+ u_int32_t pcr_length;
+ chunk_t pcr_value;
+
+ result = Tspi_Context_Create(&hContext);
+ if (result != TSS_SUCCESS)
+ {
+ DBG1(DBG_PTS, "TPM context could not be created: tss error 0x%x",
+ result);
+ return FALSE;
+ }
+ result = Tspi_Context_Connect(hContext, NULL);
+ if (result != TSS_SUCCESS)
+ {
+ goto err;
+ }
+ result = Tspi_Context_GetTpmObject (hContext, &hTPM);
+ if (result != TSS_SUCCESS)
+ {
+ goto err;
+ }
+
+ pcr_value = chunk_alloc(PCR_LEN);
+ result = Tspi_TPM_PcrExtend(hTPM, pcr_num, PCR_LEN, input.ptr,
+ NULL, &pcr_length, &pcr_value.ptr);
+ if (result != TSS_SUCCESS)
+ {
+ goto err;
+ }
+
+ *output = pcr_value;
+ *output = chunk_clone(*output);
+
+ DBG3(DBG_PTS, "PCR %d extended with: %B", pcr_num, &input);
+ DBG3(DBG_PTS, "PCR %d value after extend: %B", pcr_num, output);
+
+ chunk_clear(&pcr_value);
+ Tspi_Context_FreeMemory(hContext, NULL);
+ Tspi_Context_Close(hContext);
+
+ return TRUE;
+
+err:
+ DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
+
+ chunk_clear(&pcr_value);
+ Tspi_Context_FreeMemory(hContext, NULL);
+ Tspi_Context_Close(hContext);
+
+ return FALSE;
+}
+
+
+static void clear_pcrs(private_pts_t *this)
+{
+ int i;
+
+ for (i = 0; i <= this->pcr_max; i++)
+ {
+ free(this->pcrs[i]);
+ this->pcrs[i] = NULL;
+ }
+ this->pcr_count = 0;
+ this->pcr_max = 0;
+
+ memset(this->pcr_select, 0x00, sizeof(this->pcr_select));
+}
+
+METHOD(pts_t, quote_tpm, bool,
+ private_pts_t *this, bool use_quote2, chunk_t *pcr_comp, chunk_t *quote_sig)
+{
+ TSS_HCONTEXT hContext;
+ TSS_HTPM hTPM;
+ TSS_HKEY hAIK;
+ TSS_HKEY hSRK;
+ TSS_HPOLICY srkUsagePolicy;
+ TSS_UUID SRK_UUID = TSS_UUID_SRK;
+ BYTE secret[] = TSS_WELL_KNOWN_SECRET;
+ TSS_HPCRS hPcrComposite;
+ TSS_VALIDATION valData;
+ TSS_RESULT result;
+ chunk_t quote_info;
+ BYTE* versionInfo;
+ u_int32_t versionInfoSize, pcr, i = 0, f = 1;
+ bool success = FALSE;
+
+ result = Tspi_Context_Create(&hContext);
+ if (result != TSS_SUCCESS)
+ {
+ DBG1(DBG_PTS, "TPM context could not be created: tss error 0x%x",
+ result);
+ return FALSE;
+ }
+ result = Tspi_Context_Connect(hContext, NULL);
+ if (result != TSS_SUCCESS)
+ {
+ goto err1;
+ }
+ result = Tspi_Context_GetTpmObject (hContext, &hTPM);
+ if (result != TSS_SUCCESS)
+ {
+ goto err1;
+ }
+
+ /* Retrieve SRK from TPM and set the authentication to well known secret*/
+ result = Tspi_Context_LoadKeyByUUID(hContext, TSS_PS_TYPE_SYSTEM,
+ SRK_UUID, &hSRK);
+ if (result != TSS_SUCCESS)
+ {
+ goto err1;
+ }
+
+ result = Tspi_GetPolicyObject(hSRK, TSS_POLICY_USAGE, &srkUsagePolicy);
+ if (result != TSS_SUCCESS)
+ {
+ goto err1;
+ }
+ result = Tspi_Policy_SetSecret(srkUsagePolicy, TSS_SECRET_MODE_SHA1,
+ 20, secret);
+ if (result != TSS_SUCCESS)
+ {
+ goto err1;
+ }
+
+ result = Tspi_Context_LoadKeyByBlob (hContext, hSRK, this->aik_blob.len,
+ this->aik_blob.ptr, &hAIK);
+ if (result != TSS_SUCCESS)
+ {
+ goto err1;
+ }
+
+ /* Create PCR composite object */
+ result = use_quote2 ?
+ Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_PCRS,
+ TSS_PCRS_STRUCT_INFO_SHORT, &hPcrComposite) :
+ Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_PCRS,
+ 0, &hPcrComposite);
+ if (result != TSS_SUCCESS)
+ {
+ goto err2;
+ }
+
+ /* Select PCRs */
+ for (pcr = 0; pcr <= this->pcr_max ; pcr++)
+ {
+ if (f == 256)
+ {
+ i++;
+ f = 1;
+ }
+ if (this->pcr_select[i] & f)
+ {
+ result = use_quote2 ?
+ Tspi_PcrComposite_SelectPcrIndexEx(hPcrComposite, pcr,
+ TSS_PCRS_DIRECTION_RELEASE) :
+ Tspi_PcrComposite_SelectPcrIndex(hPcrComposite, pcr);
+ if (result != TSS_SUCCESS)
+ {
+ goto err3;
+ }
+ }
+ f <<= 1;
+ }
+
+ /* Set the Validation Data */
+ valData.ulExternalDataLength = this->secret.len;
+ valData.rgbExternalData = (BYTE *)this->secret.ptr;
+
+
+ /* TPM Quote */
+ result = use_quote2 ?
+ Tspi_TPM_Quote2(hTPM, hAIK, FALSE, hPcrComposite, &valData,
+ &versionInfoSize, &versionInfo):
+ Tspi_TPM_Quote(hTPM, hAIK, hPcrComposite, &valData);
+ if (result != TSS_SUCCESS)
+ {
+ goto err4;
+ }
+
+ /* Set output chunks */
+ *pcr_comp = chunk_alloc(HASH_SIZE_SHA1);
+
+ if (use_quote2)
+ {
+ /* TPM_Composite_Hash is last 20 bytes of TPM_Quote_Info2 structure */
+ memcpy(pcr_comp->ptr, valData.rgbData + valData.ulDataLength - HASH_SIZE_SHA1,
+ HASH_SIZE_SHA1);
+ }
+ else
+ {
+ /* TPM_Composite_Hash is 8-28th bytes of TPM_Quote_Info structure */
+ memcpy(pcr_comp->ptr, valData.rgbData + 8, HASH_SIZE_SHA1);
+ }
+ DBG3(DBG_PTS, "Hash of PCR Composite: %#B", pcr_comp);
+
+ quote_info = chunk_create(valData.rgbData, valData.ulDataLength);
+ DBG3(DBG_PTS, "TPM Quote Info: %B",&quote_info);
+
+ *quote_sig = chunk_clone(chunk_create(valData.rgbValidationData,
+ valData.ulValidationDataLength));
+ DBG3(DBG_PTS, "TPM Quote Signature: %B",quote_sig);
+
+ success = TRUE;
+
+ /* Cleanup */
+err4:
+ Tspi_Context_FreeMemory(hContext, NULL);
+
+err3:
+ Tspi_Context_CloseObject(hContext, hPcrComposite);
+
+err2:
+ Tspi_Context_CloseObject(hContext, hAIK);
+
+err1:
+ Tspi_Context_Close(hContext);
+
+ if (!success)
+ {
+ DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
+ }
+ clear_pcrs(this);
+
+ return success;
+}
+
+METHOD(pts_t, select_pcr, bool,
+ private_pts_t *this, u_int32_t pcr)
+{
+ u_int32_t i, f;
+
+ if (pcr >= PCR_MAX_NUM)
+ {
+ DBG1(DBG_PTS, "PCR %u: number is larger than maximum of %u",
+ pcr, PCR_MAX_NUM-1);
+ return FALSE;
+ }
+
+ /* Determine PCR selection flag */
+ i = pcr / 8;
+ f = 1 << (pcr - 8*i);
+
+ /* Has this PCR already been selected? */
+ if (!(this->pcr_select[i] & f))
+ {
+ this->pcr_select[i] |= f;
+ this->pcr_max = max(this->pcr_max, pcr);
+ this->pcr_count++;
+ }
+
+ return TRUE;
+}
+
+METHOD(pts_t, add_pcr, bool,
+ private_pts_t *this, u_int32_t pcr, chunk_t pcr_before, chunk_t pcr_after)
+{
+ if (pcr >= PCR_MAX_NUM)
+ {
+ DBG1(DBG_PTS, "PCR %u: number is larger than maximum of %u",
+ pcr, PCR_MAX_NUM-1);
+ return FALSE;
+ }
+
+ /* Is the length of the PCR registers already set? */
+ if (this->pcr_len)
+ {
+ if (pcr_after.len != this->pcr_len)
+ {
+ DBG1(DBG_PTS, "PCR %02u: length is %d bytes but should be %d bytes",
+ pcr_after.len, this->pcr_len);
+ return FALSE;
+ }
+ }
+ else
+ {
+ this->pcr_len = pcr_after.len;
+ }
+
+ /* Has the value of the PCR register already been assigned? */
+ if (this->pcrs[pcr])
+ {
+ if (!memeq(this->pcrs[pcr], pcr_before.ptr, this->pcr_len))
+ {
+ DBG1(DBG_PTS, "PCR %02u: new pcr_before value does not equal "
+ "old pcr_after value");
+ }
+ /* remove the old PCR value */
+ free(this->pcrs[pcr]);
+ }
+ else
+ {
+ /* add extended PCR Register */
+ this->pcr_select[pcr / 8] |= 1 << (pcr % 8);
+ this->pcr_max = max(this->pcr_max, pcr);
+ this->pcr_count++;
+ }
+
+ /* Duplicate and store current PCR value */
+ pcr_after = chunk_clone(pcr_after);
+ this->pcrs[pcr] = pcr_after.ptr;
+
+ return TRUE;
+}
+
+/**
+ * TPM_QUOTE_INFO structure:
+ * 4 bytes of version
+ * 4 bytes 'Q' 'U' 'O' 'T'
+ * 20 byte SHA1 of TCPA_PCR_COMPOSITE
+ * 20 byte nonce
+ *
+ * TPM_QUOTE_INFO2 structure:
+ * 2 bytes Tag 0x0036 TPM_Tag_Quote_info2
+ * 4 bytes 'Q' 'U' 'T' '2'
+ * 20 bytes nonce
+ * 26 bytes PCR_INFO_SHORT
+ */
+
+METHOD(pts_t, get_quote_info, bool,
+ private_pts_t *this, bool use_quote2, bool use_ver_info,
+ pts_meas_algorithms_t comp_hash_algo,
+ chunk_t *out_pcr_comp, chunk_t *out_quote_info)
+{
+ u_int8_t size_of_select;
+ int pcr_comp_len, i;
+ chunk_t pcr_comp, hash_pcr_comp;
+ bio_writer_t *writer;
+ hasher_t *hasher;
+
+ if (this->pcr_count == 0)
+ {
+ DBG1(DBG_PTS, "No extended PCR entries available, "
+ "unable to construct TPM Quote Info");
+ return FALSE;
+ }
+ if (!this->secret.ptr)
+ {
+ DBG1(DBG_PTS, "Secret assessment value unavailable, ",
+ "unable to construct TPM Quote Info");
+ return FALSE;
+ }
+ if (use_quote2 && use_ver_info && !this->tpm_version_info.ptr)
+ {
+ DBG1(DBG_PTS, "TPM Version Information unavailable, ",
+ "unable to construct TPM Quote Info2");
+ return FALSE;
+ }
+
+ /**
+ * A TPM v1.2 has 24 PCR Registers
+ * so the bitmask field length used by TrouSerS is at least 3 bytes
+ */
+ size_of_select = max(PCR_MAX_NUM / 8, 1 + this->pcr_max / 8);
+ pcr_comp_len = 2 + size_of_select + 4 + this->pcr_count * this->pcr_len;
+
+ writer = bio_writer_create(pcr_comp_len);
+
+ writer->write_uint16(writer, size_of_select);
+ for (i = 0; i < size_of_select; i++)
+ {
+ writer->write_uint8(writer, this->pcr_select[i]);
+ }
+
+ writer->write_uint32(writer, this->pcr_count * this->pcr_len);
+ for (i = 0; i < 8 * size_of_select; i++)
+ {
+ if (this->pcrs[i])
+ {
+ writer->write_data(writer, chunk_create(this->pcrs[i], this->pcr_len));
+ }
+ }
+ pcr_comp = chunk_clone(writer->get_buf(writer));
+ DBG3(DBG_PTS, "constructed PCR Composite: %B", &pcr_comp);
+
+ writer->destroy(writer);
+
+ /* Output the TPM_PCR_COMPOSITE expected from IMC */
+ if (comp_hash_algo)
+ {
+ hash_algorithm_t algo;
+
+ algo = pts_meas_algo_to_hash(comp_hash_algo);
+ hasher = lib->crypto->create_hasher(lib->crypto, algo);
+
+ /* Hash the PCR Composite Structure */
+ hasher->allocate_hash(hasher, pcr_comp, out_pcr_comp);
+ DBG3(DBG_PTS, "constructed PCR Composite hash: %#B", out_pcr_comp);
+ hasher->destroy(hasher);
+ }
+ else
+ {
+ *out_pcr_comp = chunk_clone(pcr_comp);
+ }
+
+ /* SHA1 hash of PCR Composite to construct TPM_QUOTE_INFO */
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ hasher->allocate_hash(hasher, pcr_comp, &hash_pcr_comp);
+ hasher->destroy(hasher);
+
+ /* Construct TPM_QUOTE_INFO/TPM_QUOTE_INFO2 structure */
+ writer = bio_writer_create(TPM_QUOTE_INFO_LEN);
+
+ if (use_quote2)
+ {
+ /* TPM Structure Tag */
+ writer->write_uint16(writer, TPM_TAG_QUOTE_INFO2);
+
+ /* Magic QUT2 value */
+ writer->write_data(writer, chunk_create("QUT2", 4));
+
+ /* Secret assessment value 20 bytes (nonce) */
+ writer->write_data(writer, this->secret);
+
+ /* Length of the PCR selection field */
+ writer->write_uint16(writer, size_of_select);
+
+ /* PCR selection */
+ for (i = 0; i < size_of_select ; i++)
+ {
+ writer->write_uint8(writer, this->pcr_select[i]);
+ }
+
+ /* TPM Locality Selection */
+ writer->write_uint8(writer, TPM_LOC_ZERO);
+
+ /* PCR Composite Hash */
+ writer->write_data(writer, hash_pcr_comp);
+
+ if (use_ver_info)
+ {
+ /* TPM version Info */
+ writer->write_data(writer, this->tpm_version_info);
+ }
+ }
+ else
+ {
+ /* Version number */
+ writer->write_data(writer, chunk_from_chars(1, 1, 0, 0));
+
+ /* Magic QUOT value */
+ writer->write_data(writer, chunk_create("QUOT", 4));
+
+ /* PCR Composite Hash */
+ writer->write_data(writer, hash_pcr_comp);
+
+ /* Secret assessment value 20 bytes (nonce) */
+ writer->write_data(writer, this->secret);
+ }
+
+ /* TPM Quote Info */
+ *out_quote_info = chunk_clone(writer->get_buf(writer));
+ DBG3(DBG_PTS, "constructed TPM Quote Info: %B", out_quote_info);
+
+ writer->destroy(writer);
+ free(pcr_comp.ptr);
+ free(hash_pcr_comp.ptr);
+ clear_pcrs(this);
+
+ return TRUE;
+}
+
+METHOD(pts_t, verify_quote_signature, bool,
+ private_pts_t *this, chunk_t data, chunk_t signature)
+{
+ public_key_t *aik_pub_key;
+
+ aik_pub_key = this->aik->get_public_key(this->aik);
+ if (!aik_pub_key)
+ {
+ DBG1(DBG_PTS, "failed to get public key from AIK certificate");
+ return FALSE;
+ }
+
+ if (!aik_pub_key->verify(aik_pub_key, SIGN_RSA_EMSA_PKCS1_SHA1,
+ data, signature))
+ {
+ DBG1(DBG_PTS, "signature verification failed for TPM Quote Info");
+ DESTROY_IF(aik_pub_key);
+ return FALSE;
+ }
+
+ aik_pub_key->destroy(aik_pub_key);
+ return TRUE;
+}
+
+METHOD(pts_t, destroy, void,
+ private_pts_t *this)
+{
+ clear_pcrs(this);
+ DESTROY_IF(this->aik);
+ DESTROY_IF(this->dh);
+ free(this->initiator_nonce.ptr);
+ free(this->responder_nonce.ptr);
+ free(this->secret.ptr);
+ free(this->platform_info);
+ free(this->aik_blob.ptr);
+ free(this->tpm_version_info.ptr);
+ free(this);
+}
+
+#define RELEASE_LSB 0
+#define RELEASE_DEBIAN 1
+
+/**
+ * Determine Linux distribution and hardware platform
+ */
+static char* extract_platform_info(void)
+{
+ FILE *file;
+ char buf[BUF_LEN], *pos = buf, *value = NULL;
+ int i, len = BUF_LEN - 1;
+ struct utsname uninfo;
+
+ /* Linux/Unix distribution release info (from http://linuxmafia.com) */
+ const char* releases[] = {
+ "/etc/lsb-release", "/etc/debian_version",
+ "/etc/SuSE-release", "/etc/novell-release",
+ "/etc/sles-release", "/etc/redhat-release",
+ "/etc/fedora-release", "/etc/gentoo-release",
+ "/etc/slackware-version", "/etc/annvix-release",
+ "/etc/arch-release", "/etc/arklinux-release",
+ "/etc/aurox-release", "/etc/blackcat-release",
+ "/etc/cobalt-release", "/etc/conectiva-release",
+ "/etc/debian_release", "/etc/immunix-release",
+ "/etc/lfs-release", "/etc/linuxppc-release",
+ "/etc/mandrake-release", "/etc/mandriva-release",
+ "/etc/mandrakelinux-release", "/etc/mklinux-release",
+ "/etc/pld-release", "/etc/redhat_version",
+ "/etc/slackware-release", "/etc/e-smith-release",
+ "/etc/release", "/etc/sun-release",
+ "/etc/tinysofa-release", "/etc/turbolinux-release",
+ "/etc/ultrapenguin-release", "/etc/UnitedLinux-release",
+ "/etc/va-release", "/etc/yellowdog-release"
+ };
+
+ const char description[] = "DISTRIB_DESCRIPTION=\"";
+ const char str_debian[] = "Debian ";
+
+ for (i = 0; i < countof(releases); i++)
+ {
+ file = fopen(releases[i], "r");
+ if (!file)
+ {
+ continue;
+ }
+
+ if (i == RELEASE_DEBIAN)
+ {
+ strcpy(buf, str_debian);
+ pos += strlen(str_debian);
+ len -= strlen(str_debian);
+ }
+
+ fseek(file, 0, SEEK_END);
+ len = min(ftell(file), len);
+ rewind(file);
+ pos[len] = '\0';
+ if (fread(pos, 1, len, file) != len)
+ {
+ DBG1(DBG_PTS, "failed to read file '%s'", releases[i]);
+ fclose(file);
+ return NULL;
+ }
+ fclose(file);
+
+ if (i == RELEASE_LSB)
+ {
+ pos = strstr(buf, description);
+ if (!pos)
+ {
+ DBG1(DBG_PTS, "failed to find begin of lsb-release "
+ "DESCRIPTION field");
+ return NULL;
+ }
+ value = pos + strlen(description);
+ pos = strchr(value, '"');
+ if (!pos)
+ {
+ DBG1(DBG_PTS, "failed to find end of lsb-release "
+ "DESCRIPTION field");
+ return NULL;
+ }
+ }
+ else
+ {
+ value = buf;
+ pos = strchr(pos, '\n');
+ if (!pos)
+ {
+ DBG1(DBG_PTS, "failed to find end of release string");
+ return NULL;
+ }
+ }
+ break;
+ }
+
+ if (!value)
+ {
+ DBG1(DBG_PTS, "no distribution release file found");
+ return NULL;
+ }
+
+ if (uname(&uninfo) < 0)
+ {
+ DBG1(DBG_PTS, "could not retrieve machine architecture");
+ return NULL;
+ }
+
+ *pos++ = ' ';
+ len = sizeof(buf)-1 + (pos - buf);
+ strncpy(pos, uninfo.machine, len);
+
+ DBG1(DBG_PTS, "platform is '%s'", value);
+ return strdup(value);
+}
+
+/**
+ * Check for a TPM by querying for TPM Version Info
+ */
+static bool has_tpm(private_pts_t *this)
+{
+ TSS_HCONTEXT hContext;
+ TSS_HTPM hTPM;
+ TSS_RESULT result;
+ u_int32_t version_info_len;
+
+ result = Tspi_Context_Create(&hContext);
+ if (result != TSS_SUCCESS)
+ {
+ DBG1(DBG_PTS, "TPM context could not be created: tss error 0x%x",
+ result);
+ return FALSE;
+ }
+ result = Tspi_Context_Connect(hContext, NULL);
+ if (result != TSS_SUCCESS)
+ {
+ goto err;
+ }
+ result = Tspi_Context_GetTpmObject (hContext, &hTPM);
+ if (result != TSS_SUCCESS)
+ {
+ goto err;
+ }
+ result = Tspi_TPM_GetCapability(hTPM, TSS_TPMCAP_VERSION_VAL, 0, NULL,
+ &version_info_len,
+ &this->tpm_version_info.ptr);
+ this->tpm_version_info.len = version_info_len;
+ if (result != TSS_SUCCESS)
+ {
+ goto err;
+ }
+ this->tpm_version_info = chunk_clone(this->tpm_version_info);
+
+ Tspi_Context_FreeMemory(hContext, NULL);
+ Tspi_Context_Close(hContext);
+ return TRUE;
+
+ err:
+ DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
+ Tspi_Context_FreeMemory(hContext, NULL);
+ Tspi_Context_Close(hContext);
+ return FALSE;
+}
+
+/**
+ * See header
+ */
+pts_t *pts_create(bool is_imc)
+{
+ private_pts_t *this;
+
+ INIT(this,
+ .public = {
+ .get_proto_caps = _get_proto_caps,
+ .set_proto_caps = _set_proto_caps,
+ .get_meas_algorithm = _get_meas_algorithm,
+ .set_meas_algorithm = _set_meas_algorithm,
+ .get_dh_hash_algorithm = _get_dh_hash_algorithm,
+ .set_dh_hash_algorithm = _set_dh_hash_algorithm,
+ .create_dh_nonce = _create_dh_nonce,
+ .get_my_public_value = _get_my_public_value,
+ .set_peer_public_value = _set_peer_public_value,
+ .calculate_secret = _calculate_secret,
+ .get_platform_info = _get_platform_info,
+ .set_platform_info = _set_platform_info,
+ .get_tpm_version_info = _get_tpm_version_info,
+ .set_tpm_version_info = _set_tpm_version_info,
+ .get_pcr_len = _get_pcr_len,
+ .get_aik = _get_aik,
+ .set_aik = _set_aik,
+ .get_aik_keyid = _get_aik_keyid,
+ .is_path_valid = _is_path_valid,
+ .hash_file = _hash_file,
+ .do_measurements = _do_measurements,
+ .get_metadata = _get_metadata,
+ .read_pcr = _read_pcr,
+ .extend_pcr = _extend_pcr,
+ .quote_tpm = _quote_tpm,
+ .select_pcr = _select_pcr,
+ .add_pcr = _add_pcr,
+ .get_quote_info = _get_quote_info,
+ .verify_quote_signature = _verify_quote_signature,
+ .destroy = _destroy,
+ },
+ .is_imc = is_imc,
+ .proto_caps = PTS_PROTO_CAPS_V,
+ .algorithm = PTS_MEAS_ALGO_SHA256,
+ .dh_hash_algorithm = PTS_MEAS_ALGO_SHA256,
+ );
+
+ if (is_imc)
+ {
+ this->platform_info = extract_platform_info();
+
+ if (has_tpm(this))
+ {
+ this->has_tpm = TRUE;
+ this->pcr_len = PCR_LEN;
+ this->proto_caps |= PTS_PROTO_CAPS_T | PTS_PROTO_CAPS_D;
+ load_aik(this);
+ load_aik_blob(this);
+ }
+ }
+ else
+ {
+ this->proto_caps |= PTS_PROTO_CAPS_T | PTS_PROTO_CAPS_D;
+ }
+
+ return &this->public;
+}
diff --git a/src/libpts/pts/pts.h b/src/libpts/pts/pts.h
new file mode 100644
index 000000000..212acb02a
--- /dev/null
+++ b/src/libpts/pts/pts.h
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts pts
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_H_
+#define PTS_H_
+
+typedef struct pts_t pts_t;
+
+#include "pts_error.h"
+#include "pts_proto_caps.h"
+#include "pts_meas_algo.h"
+#include "pts_file_meas.h"
+#include "pts_file_meta.h"
+#include "pts_dh_group.h"
+#include "pts_req_func_comp_evid.h"
+#include "pts_simple_evid_final.h"
+#include "components/pts_comp_func_name.h"
+
+#include <library.h>
+#include <utils/linked_list.h>
+
+/**
+ * UTF-8 encoding of the character used to delimiter the filename
+ */
+#define SOLIDUS_UTF 0x2F
+#define REVERSE_SOLIDUS_UTF 0x5C
+
+/**
+ * PCR indices used for measurements of various functional components
+ */
+#define PCR_BIOS 0
+#define PCR_PLATFORM_EXT 1
+#define PCR_MOTHERBOARD 1
+#define PCR_OPTION_ROMS 2
+#define PCR_IPL 4
+
+#define PCR_TBOOT_POLICY 17
+#define PCR_TBOOT_MLE 18
+
+#define PCR_TGRUB_MBR_STAGE1 4
+#define PCR_TGRUB_STAGE2_PART1 8
+#define PCR_TGRUB_STAGE2_PART2 9
+#define PCR_TGRUB_CMD_LINE_ARGS 12
+#define PCR_TGRUB_CHECKFILE 13
+#define PCR_TGRUB_LOADED_FILES 14
+
+#define PCR_DEBUG 16
+
+/**
+ * Length of the generated nonce used for calculation of shared secret
+ */
+#define ASSESSMENT_SECRET_LEN 20
+
+/**
+ * Length of the TPM_QUOTE_INFO structure, TPM Spec 1.2
+ */
+#define TPM_QUOTE_INFO_LEN 48
+
+/**
+ * Hashing algorithm used by tboot and trustedGRUB
+ */
+#define TRUSTED_HASH_ALGO PTS_MEAS_ALGO_SHA1
+
+/**
+ * Class implementing the TCG Platform Trust Service (PTS)
+ *
+ */
+struct pts_t {
+
+ /**
+ * Get PTS Protocol Capabilities
+ *
+ * @return Protocol capabilities flags
+ */
+ pts_proto_caps_flag_t (*get_proto_caps)(pts_t *this);
+
+ /**
+ * Set PTS Protocol Capabilities
+ *
+ * @param flags Protocol capabilities flags
+ */
+ void (*set_proto_caps)(pts_t *this, pts_proto_caps_flag_t flags);
+
+ /**
+ * Get PTS Measurement Algorithm
+ *
+ * @return PTS measurement algorithm
+ */
+ pts_meas_algorithms_t (*get_meas_algorithm)(pts_t *this);
+
+ /**
+ * Set PTS Measurement Algorithm
+ *
+ * @param algorithm PTS measurement algorithm
+ */
+ void (*set_meas_algorithm)(pts_t *this, pts_meas_algorithms_t algorithm);
+
+ /**
+ * Get DH Hash Algorithm
+ *
+ * @return DH hash algorithm
+ */
+ pts_meas_algorithms_t (*get_dh_hash_algorithm)(pts_t *this);
+
+ /**
+ * Set DH Hash Algorithm
+ *
+ * @param algorithm DH hash algorithm
+ */
+ void (*set_dh_hash_algorithm)(pts_t *this, pts_meas_algorithms_t algorithm);
+
+ /**
+ * Create PTS Diffie-Hellman object and nonce
+ *
+ * @param group PTS DH group
+ * @param nonce_len Nonce length
+ * @return TRUE if creation was successful
+ *
+ */
+ bool (*create_dh_nonce)(pts_t *this, pts_dh_group_t group, int nonce_len);
+
+ /**
+ * Get my Diffie-Hellman public value
+ *
+ * @param value My public DH value
+ * @param nonce My DH nonce
+ */
+ void (*get_my_public_value)(pts_t *this, chunk_t *value, chunk_t *nonce);
+
+ /**
+ * Set peer Diffie.Hellman public value
+ *
+ * @param value Peer public DH value
+ * @param nonce Peer DH nonce
+ */
+ void (*set_peer_public_value) (pts_t *this, chunk_t value, chunk_t nonce);
+
+ /**
+ * Calculates assessment secret to be used for TPM Quote as ExternalData
+ *
+ * @return TRUE unless both DH public values
+ * and nonces are set
+ */
+ bool (*calculate_secret) (pts_t *this);
+
+ /**
+ * Get Platform and OS Info
+ *
+ * @return Platform and OS info
+ */
+ char* (*get_platform_info)(pts_t *this);
+
+ /**
+ * Set Platform and OS Info
+ *
+ * @param info Platform and OS info
+ */
+ void (*set_platform_info)(pts_t *this, char *info);
+
+ /**
+ * Get TPM 1.2 Version Info
+ *
+ * @param info chunk containing a TPM_CAP_VERSION_INFO struct
+ * @return TRUE if TPM Version Info available
+ */
+ bool (*get_tpm_version_info)(pts_t *this, chunk_t *info);
+
+ /**
+ * Set TPM 1.2 Version Info
+ *
+ * @param info chunk containing a TPM_CAP_VERSION_INFO struct
+ */
+ void (*set_tpm_version_info)(pts_t *this, chunk_t info);
+
+ /**
+ * Get the length of the TPM PCR registers
+ *
+ * @return Length of PCR registers in bytes, 0 if undefined
+ */
+ size_t (*get_pcr_len)(pts_t *this);
+
+ /**
+ * Get Attestation Identity Certificate or Public Key
+ *
+ * @return AIK Certificate or Public Key
+ */
+ certificate_t* (*get_aik)(pts_t *this);
+
+ /**
+ * Set Attestation Identity Certificate or Public Key
+ *
+ * @param aik AIK Certificate or Public Key
+ */
+ void (*set_aik)(pts_t *this, certificate_t *aik);
+
+ /**
+ * Get SHA-1 Attestation Identity Public Key Info ID
+ *
+ * @param keyid AIK ID
+ * @return TRUE if AIK ID exists
+ */
+ bool (*get_aik_keyid)(pts_t *this, chunk_t *keyid);
+
+ /**
+ * Check whether path is valid file/directory on filesystem
+ *
+ * @param path Absolute path
+ * @param error_code Output variable for PTS error code
+ * @return TRUE if path is valid or file/directory
+ * doesn't exist or path is invalid
+ * FALSE if local error occurred within stat function
+ */
+ bool (*is_path_valid)(pts_t *this, char *path, pts_error_code_t *error_code);
+
+ /**
+ * Compute a hash over a file
+ * @param hasher Hasher to be used
+ * @param pathname Absolute path of a file
+ * @param hash Buffer to keep hash output
+ * @return TRUE if path is valid and hashing succeeded
+ */
+ bool (*hash_file)(pts_t *this, hasher_t *hasher, char *pathname, u_char *hash);
+
+ /**
+ * Do PTS File Measurements
+ *
+ * @param request_id ID of PTS File Measurement Request
+ * @param pathname Absolute pathname of file to be measured
+ * @param is_directory TRUE if directory contents are measured
+ * @return PTS File Measurements of NULL if FAILED
+ */
+ pts_file_meas_t* (*do_measurements)(pts_t *this, u_int16_t request_id,
+ char *pathname, bool is_directory);
+
+ /**
+ * Obtain file metadata
+ *
+ * @param pathname Absolute pathname of file/directory
+ * @param is_directory TRUE if directory contents are requested
+ * @return PTS File Metadata or NULL if FAILED
+ */
+ pts_file_meta_t* (*get_metadata)(pts_t *this, char *pathname,
+ bool is_directory);
+
+ /**
+ * Reads given PCR value and returns it
+ * Expects owner secret to be WELL_KNOWN_SECRET
+ *
+ * @param pcr_num Number of PCR to read
+ * @param pcr_value Chunk to save pcr read output
+ * @return NULL in case of TSS error, PCR value otherwise
+ */
+ bool (*read_pcr)(pts_t *this, u_int32_t pcr_num, chunk_t *pcr_value);
+
+ /**
+ * Extends given PCR with given value
+ * Expects owner secret to be WELL_KNOWN_SECRET
+ *
+ * @param pcr_num Number of PCR to extend
+ * @param input Value to extend
+ * @param output Chunk to save PCR value after extension
+ * @return FALSE in case of TSS error, TRUE otherwise
+ */
+ bool (*extend_pcr)(pts_t *this, u_int32_t pcr_num, chunk_t input,
+ chunk_t *output);
+
+ /**
+ * Quote over PCR's
+ * Expects owner and SRK secret to be WELL_KNOWN_SECRET and no password set for AIK
+ *
+ * @param use_quote2 Version of the Quote function to be used
+ * @param pcr_comp Chunk to save PCR composite structure
+ * @param quote_sig Chunk to save quote operation output
+ * without external data (anti-replay protection)
+ * @return FALSE in case of TSS error, TRUE otherwise
+ */
+ bool (*quote_tpm)(pts_t *this, bool use_quote2, chunk_t *pcr_comp,
+ chunk_t *quote_sig);
+
+ /**
+ * Mark an extended PCR as selected
+ *
+ * @param pcr Number of the extended PCR
+ * @return TRUE if PCR number is valid
+ */
+ bool (*select_pcr)(pts_t *this, u_int32_t pcr);
+
+ /**
+ * Add an extended PCR with its corresponding value
+ *
+ * @param pcr Number of the extended PCR
+ * @param pcr_before PCR value before extension
+ * @param pcr_after PCR value after extension
+ * @return TRUE if PCR number and register length is valid
+ */
+ bool (*add_pcr)(pts_t *this, u_int32_t pcr, chunk_t pcr_before,
+ chunk_t pcr_after);
+
+ /**
+ * Constructs and returns TPM Quote Info structure expected from IMC
+ *
+ * @param use_quote2 Version of the TPM_QUOTE_INFO to be constructed
+ * @param use_ver_info Version info is concatenated to TPM_QUOTE_INFO2
+ * @param comp_hash_algo Composite Hash Algorithm
+ * @param pcr_comp Output variable to store PCR Composite
+ * @param quote_info Output variable to store TPM Quote Info
+ * @return FALSE in case of any error, TRUE otherwise
+ */
+ bool (*get_quote_info)(pts_t *this, bool use_quote2, bool ver_info_included,
+ pts_meas_algorithms_t comp_hash_algo,
+ chunk_t *pcr_comp, chunk_t *quote_info);
+
+ /**
+ * Constructs and returns PCR Quote Digest structure expected from IMC
+ *
+ * @param data Calculated TPM Quote Digest
+ * @param signature TPM Quote Signature received from IMC
+ * @return FALSE if signature is not verified
+ */
+ bool (*verify_quote_signature)(pts_t *this, chunk_t data, chunk_t signature);
+
+ /**
+ * Destroys a pts_t object.
+ */
+ void (*destroy)(pts_t *this);
+
+};
+
+/**
+ * Creates an pts_t object
+ *
+ * @param is_imc TRUE if running on an IMC
+ */
+pts_t* pts_create(bool is_imc);
+
+#endif /** PTS_H_ @}*/
diff --git a/src/libpts/pts/pts_creds.c b/src/libpts/pts/pts_creds.c
new file mode 100644
index 000000000..5a6197bdb
--- /dev/null
+++ b/src/libpts/pts/pts_creds.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2011 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 "pts_creds.h"
+
+#include <debug.h>
+#include <credentials/certificates/x509.h>
+#include <credentials/sets/mem_cred.h>
+
+#include <sys/stat.h>
+
+typedef struct private_pts_creds_t private_pts_creds_t;
+
+/**
+ * Private data of a pts_creds_t object.
+ *
+ */
+struct private_pts_creds_t {
+
+ /**
+ * Public pts_creds_t interface.
+ */
+ pts_creds_t public;
+
+ /**
+ * Credential set
+ */
+ mem_cred_t *creds;
+
+};
+
+METHOD(pts_creds_t, get_set, credential_set_t*,
+ private_pts_creds_t *this)
+{
+ return &this->creds->set;
+}
+
+
+METHOD(pts_creds_t, destroy, void,
+ private_pts_creds_t *this)
+{
+ this->creds->destroy(this->creds);
+ free(this);
+}
+
+/**
+ * Load trusted PTS CA certificates from a directory
+ */
+static void load_cacerts(private_pts_creds_t *this, char *path)
+{
+ enumerator_t *enumerator;
+ struct stat st;
+ char *file;
+
+ DBG1(DBG_PTS, "loading PTS ca certificates from '%s'", path);
+
+ enumerator = enumerator_create_directory(path);
+ if (!enumerator)
+ {
+ return;
+ }
+
+ while (enumerator->enumerate(enumerator, NULL, &file, &st))
+ {
+ certificate_t *cert;
+
+ if (!S_ISREG(st.st_mode))
+ {
+ /* skip special file */
+ continue;
+ }
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_FROM_FILE, file, BUILD_END);
+ if (cert)
+ {
+ x509_t *x509 = (x509_t*)cert;
+
+ if (!(x509->get_flags(x509) & X509_CA))
+ {
+ DBG1(DBG_PTS, " ca certificate \"%Y\" lacks ca basic constraint"
+ ", discarded", cert->get_subject(cert));
+ cert->destroy(cert);
+ }
+ else
+ {
+ DBG1(DBG_PTS, " loaded ca certificate \"%Y\" from '%s'",
+ cert->get_subject(cert), file);
+ this->creds->add_cert(this->creds, TRUE, cert);
+ }
+ }
+ else
+ {
+ DBG1(DBG_PTS, " loading ca certificate from '%s' failed", file);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+/**
+ * See header
+ */
+pts_creds_t *pts_creds_create(char *path)
+{
+ private_pts_creds_t *this;
+
+ if (!path)
+ {
+ DBG1(DBG_PTS, "no PTS cacerts directory defined");
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .get_set = _get_set,
+ .destroy = _destroy,
+ },
+ .creds = mem_cred_create(),
+ );
+
+ load_cacerts(this, path);
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/pts_creds.h b/src/libpts/pts/pts_creds.h
new file mode 100644
index 000000000..eb9c39537
--- /dev/null
+++ b/src/libpts/pts/pts_creds.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 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 pts_creds pts_creds
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_CREDS_H_
+#define PTS_CREDS_H_
+
+typedef struct pts_creds_t pts_creds_t;
+
+#include <library.h>
+#include <credentials/credential_set.h>
+
+/**
+ * Class implementing a PTS credentials set
+ */
+struct pts_creds_t {
+
+ /**
+ * Get the credential set
+ *
+ * @return credential set
+ */
+ credential_set_t* (*get_set)(pts_creds_t *this);
+
+ /**
+ * Destroys a pts_creds_t object.
+ */
+ void (*destroy)(pts_creds_t *this);
+
+};
+
+/**
+ * Creates an pts_creds_t object
+ *
+ * @param path path to the PTS cacerts directory
+ */
+pts_creds_t* pts_creds_create(char *path);
+
+#endif /** PTS_CREDS_H_ @}*/
diff --git a/src/libpts/pts/pts_database.c b/src/libpts/pts/pts_database.c
new file mode 100644
index 000000000..282755c0a
--- /dev/null
+++ b/src/libpts/pts/pts_database.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "pts_database.h"
+
+#include <debug.h>
+#include <crypto/hashers/hasher.h>
+
+
+typedef struct private_pts_database_t private_pts_database_t;
+
+/**
+ * Private data of a pts_database_t object.
+ *
+ */
+struct private_pts_database_t {
+
+ /**
+ * Public pts_database_t interface.
+ */
+ pts_database_t public;
+
+ /**
+ * database instance
+ */
+ database_t *db;
+
+};
+
+METHOD(pts_database_t, create_file_meas_enumerator, enumerator_t*,
+ private_pts_database_t *this, char *product)
+{
+ enumerator_t *e;
+
+ /* look for all entries belonging to a product in the files table */
+ e = this->db->query(this->db,
+ "SELECT f.id, f.type, f.path FROM files AS f "
+ "JOIN product_file AS pf ON f.id = pf.file "
+ "JOIN products AS p ON p.id = pf.product "
+ "WHERE p.name = ? AND pf.measurement = 1",
+ DB_TEXT, product, DB_INT, DB_INT, DB_TEXT);
+ return e;
+}
+
+METHOD(pts_database_t, create_file_meta_enumerator, enumerator_t*,
+ private_pts_database_t *this, char *product)
+{
+ enumerator_t *e;
+
+ /* look for all entries belonging to a product in the files table */
+ e = this->db->query(this->db,
+ "SELECT f.type, f.path FROM files AS f "
+ "JOIN product_file AS pf ON f.id = pf.file "
+ "JOIN products AS p ON p.id = pf.product "
+ "WHERE p.name = ? AND pf.metadata = 1",
+ DB_TEXT, product, DB_INT, DB_TEXT);
+ return e;
+}
+
+METHOD(pts_database_t, create_file_hash_enumerator, enumerator_t*,
+ private_pts_database_t *this, char *product, pts_meas_algorithms_t algo,
+ int id, bool is_dir)
+{
+ enumerator_t *e;
+
+ if (is_dir)
+ {
+ e = this->db->query(this->db,
+ "SELECT f.path, fh.hash FROM file_hashes AS fh "
+ "JOIN files AS f ON fh.file = f.id "
+ "JOIN products AS p ON fh.product = p.id "
+ "WHERE p.name = ? AND fh.directory = ? AND fh.algo = ? "
+ "ORDER BY f.path",
+ DB_TEXT, product, DB_INT, id, DB_INT, algo, DB_TEXT, DB_BLOB);
+ }
+ else
+ {
+ e = this->db->query(this->db,
+ "SELECT f.path, fh.hash FROM file_hashes AS fh "
+ "JOIN files AS f ON fh.file = f.id "
+ "JOIN products AS p ON fh.product = p.id "
+ "WHERE p.name = ? AND fh.file = ? AND fh.algo = ?",
+ DB_TEXT, product, DB_INT, id, DB_INT, algo, DB_TEXT, DB_BLOB);
+ }
+ return e;
+}
+
+METHOD(pts_database_t, check_aik_keyid, status_t,
+ private_pts_database_t *this, chunk_t keyid, int *kid)
+{
+ enumerator_t *e;
+
+ /* If the AIK is registered get the primary key */
+ e = this->db->query(this->db,
+ "SELECT id FROM keys WHERE keyid = ?", DB_BLOB, keyid, DB_INT);
+ if (!e)
+ {
+ DBG1(DBG_PTS, "no database query enumerator returned");
+ return FAILED;
+ }
+ if (!e->enumerate(e, kid))
+ {
+ DBG1(DBG_PTS, "AIK %#B is not registered in database", &keyid);
+ e->destroy(e);
+ return FAILED;
+ }
+ e->destroy(e);
+
+ return SUCCESS;
+}
+
+METHOD(pts_database_t, create_comp_evid_enumerator, enumerator_t*,
+ private_pts_database_t *this, int kid)
+{
+ enumerator_t *e;
+
+ /* look for all entries belonging to an AIK in the components table */
+ e = this->db->query(this->db,
+ "SELECT c.vendor_id, c.name, c.qualifier, kc.depth "
+ "FROM components AS c "
+ "JOIN key_component AS kc ON c.id = kc.component "
+ "WHERE kc.key = ? ORDER BY kc.seq_no",
+ DB_INT, kid, DB_INT, DB_INT, DB_INT, DB_INT);
+ return e;
+}
+
+METHOD(pts_database_t, check_comp_measurement, status_t,
+ private_pts_database_t *this, chunk_t measurement, int cid, int kid,
+ int seq_no, int pcr, pts_meas_algorithms_t algo)
+{
+ enumerator_t *e;
+ chunk_t hash;
+ status_t status = NOT_FOUND;
+
+ e = this->db->query(this->db,
+ "SELECT hash FROM component_hashes "
+ "WHERE component = ? AND key = ? "
+ "AND seq_no = ? AND pcr = ? AND algo = ? ",
+ DB_INT, cid, DB_INT, kid, DB_INT, seq_no,
+ DB_INT, pcr, DB_INT, algo, DB_BLOB);
+ if (!e)
+ {
+ DBG1(DBG_PTS, "no database query enumerator returned");
+ return FAILED;
+ }
+
+ while (e->enumerate(e, &hash))
+ {
+ if (chunk_equals(hash, measurement))
+ {
+ status = SUCCESS;
+ break;
+ }
+ else
+ {
+ DBG1(DBG_PTS, "PCR %2d no matching component measurement #%d "
+ "found in database", pcr, seq_no);
+ DBG1(DBG_PTS, " expected: %#B", &hash);
+ DBG1(DBG_PTS, " received: %#B", &measurement);
+ status = FAILED;
+ break;
+ }
+ }
+ e->destroy(e);
+
+ if (status == NOT_FOUND)
+ {
+ DBG1(DBG_PTS, "PCR %2d no measurement #%d "
+ "found in database", pcr, seq_no);
+ }
+
+ return status;
+}
+
+METHOD(pts_database_t, insert_comp_measurement, status_t,
+ private_pts_database_t *this, chunk_t measurement, int cid, int kid,
+ int seq_no, int pcr, pts_meas_algorithms_t algo)
+{
+ int id;
+
+ if (this->db->execute(this->db, &id,
+ "INSERT INTO component_hashes "
+ "(component, key, seq_no, pcr, algo, hash) "
+ "VALUES (?, ?, ?, ?, ?, ?)",
+ DB_INT, cid, DB_INT, kid, DB_INT, seq_no, DB_INT, pcr,
+ DB_INT, algo, DB_BLOB, measurement) == 1)
+ {
+ return SUCCESS;
+ }
+
+ DBG1(DBG_PTS, "could not insert component measurement into database");
+ return FAILED;
+}
+
+METHOD(pts_database_t, delete_comp_measurements, int,
+ private_pts_database_t *this, int cid, int kid)
+{
+ return this->db->execute(this->db, NULL,
+ "DELETE FROM component_hashes "
+ "WHERE component = ? AND key = ?",
+ DB_INT, cid, DB_INT, kid);
+}
+
+METHOD(pts_database_t, get_comp_measurement_count, status_t,
+ private_pts_database_t *this, pts_comp_func_name_t *comp_name,
+ chunk_t keyid, pts_meas_algorithms_t algo, int *cid, int *kid, int *count)
+{
+ enumerator_t *e;
+ status_t status = SUCCESS;
+
+ /* Initialize count */
+ *count = 0;
+
+ if (_check_aik_keyid(this, keyid, kid) != SUCCESS)
+ {
+ return FAILED;
+ }
+
+ /* Get the primary key of the Component Functional Name */
+ e = this->db->query(this->db,
+ "SELECT id FROM components "
+ " WHERE vendor_id = ? AND name = ? AND qualifier = ?",
+ DB_INT, comp_name->get_vendor_id(comp_name),
+ DB_INT, comp_name->get_name(comp_name),
+ DB_INT, comp_name->get_qualifier(comp_name),
+ DB_INT);
+ if (!e)
+ {
+ DBG1(DBG_PTS, "no database query enumerator returned");
+ return FAILED;
+ }
+ if (!e->enumerate(e, cid))
+ {
+ DBG1(DBG_PTS, "component functional name not found in database");
+ e->destroy(e);
+ return FAILED;
+ }
+ e->destroy(e);
+
+ /* Get the number of stored measurements for a given AIK and component */
+ e = this->db->query(this->db,
+ "SELECT COUNT(*) FROM component_hashes AS ch "
+ "WHERE component = ? AND key = ? AND algo = ?",
+ DB_INT, *cid, DB_INT, *kid, DB_INT, algo, DB_INT);
+ if (!e)
+ {
+ DBG1(DBG_PTS, "no database query enumerator returned");
+ return FAILED;
+ }
+ if (!e->enumerate(e, count))
+ {
+ DBG1(DBG_PTS, "no component measurement count returned from database");
+ status = FAILED;
+ }
+ e->destroy(e);
+
+ return status;
+}
+
+METHOD(pts_database_t, destroy, void,
+ private_pts_database_t *this)
+{
+ this->db->destroy(this->db);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_database_t *pts_database_create(char *uri)
+{
+ private_pts_database_t *this;
+
+ INIT(this,
+ .public = {
+ .create_file_meas_enumerator = _create_file_meas_enumerator,
+ .create_file_meta_enumerator = _create_file_meta_enumerator,
+ .create_comp_evid_enumerator = _create_comp_evid_enumerator,
+ .create_file_hash_enumerator = _create_file_hash_enumerator,
+ .check_aik_keyid = _check_aik_keyid,
+ .check_comp_measurement = _check_comp_measurement,
+ .insert_comp_measurement = _insert_comp_measurement,
+ .delete_comp_measurements = _delete_comp_measurements,
+ .get_comp_measurement_count = _get_comp_measurement_count,
+ .destroy = _destroy,
+ },
+ .db = lib->db->create(lib->db, uri),
+ );
+
+ if (!this->db)
+ {
+ DBG1(DBG_PTS,
+ "failed to connect to PTS file measurement database '%s'", uri);
+ free(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/pts_database.h b/src/libpts/pts/pts_database.h
new file mode 100644
index 000000000..a9a68ac76
--- /dev/null
+++ b/src/libpts/pts/pts_database.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2011 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 pts_database pts_database
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_DATABASE_H_
+#define PTS_DATABASE_H_
+
+typedef struct pts_database_t pts_database_t;
+
+#include "pts_meas_algo.h"
+#include "components/pts_comp_func_name.h"
+#include <library.h>
+
+/**
+ * Class implementing the PTS File Measurement database
+ *
+ */
+struct pts_database_t {
+
+ /**
+ * Get files/directories to be measured by PTS
+ *
+ * @param product Software product (os, vpn client, etc.)
+ * @return Enumerator over all matching files/directories
+ */
+ enumerator_t* (*create_file_meas_enumerator)(pts_database_t *this,
+ char *product);
+
+ /**
+ * Get files/directories to request metadata of
+ *
+ * @param product Software product (os, vpn client, etc.)
+ * @return Enumerator over all matching files/directories
+ */
+ enumerator_t* (*create_file_meta_enumerator)(pts_database_t *this,
+ char *product);
+
+ /**
+ * Get stored measurement hash for single file or directory entries
+ *
+ * @param product Software product (os, vpn client, etc.)
+ * @param algo Hash algorithm used for measurement
+ * @param id Primary key of measured file/directory
+ * @param is_dir TRUE if directory was measured
+ * @return Enumerator over all matching measurement hashes
+ */
+ enumerator_t* (*create_file_hash_enumerator)(pts_database_t *this,
+ char *product, pts_meas_algorithms_t algo,
+ int id, bool is_dir);
+
+ /**
+ * Check if an AIK given by its keyid is registered in the database
+ *
+ * @param keyid AIK keyid (SHA-1 hash of the AIK public key info)
+ * @param kid Primary key of AIK entry in keys table
+ * @return SUCCESS if AIK is present, FAILED otherwise
+ */
+ status_t (*check_aik_keyid)(pts_database_t *this, chunk_t keyid, int *kid);
+
+ /**
+ * Get functional components to request evidence of
+ *
+ * @param kid Primary key of AIK entry in keys table
+ * @return Enumerator over all matching components
+ */
+ enumerator_t* (*create_comp_evid_enumerator)(pts_database_t *this, int kid);
+
+ /**
+ * Check a functional component measurement against value stored in database
+ *
+ * @param measurement measurement hash
+ * @param cid Primary key of Component Functional Name entry
+ * @param kid Primary key of AIK entry in keys table
+ * @param seq_no Measurement sequence number
+ * @param prc Number of the PCR the measurement was extended into
+ * @param algo Hash algorithm used for measurement
+ * @return SUCCESS if check was successful
+ */
+ status_t (*check_comp_measurement)(pts_database_t *this, chunk_t measurement,
+ int cid, int kid, int seq_no, int pcr,
+ pts_meas_algorithms_t algo);
+
+ /**
+ * Insert a functional component measurement into the database
+ *
+ * @param measurement Measurement hash
+ * @param cid Primary key of Component Functional Name entry
+ * @param kid Primary key of AIK entry in keys table
+ * @param seq_no Measurement sequence number
+ * @param prc Number of the PCR the measurement was extended into
+ * @param algo Hash algorithm used for measurement
+ * @return SUCCESS if INSERT was successful
+ */
+ status_t (*insert_comp_measurement)(pts_database_t *this, chunk_t measurement,
+ int cid, int kid, int seq_no, int pcr,
+ pts_meas_algorithms_t algo);
+
+ /**
+ * Delete functional component measurements from the database
+ *
+ * @param cid Primary key of Component Functional Name entry
+ * @param kid Primary key of AIK entry in keys table
+ * @return number of deleted measurement entries
+ */
+ int (*delete_comp_measurements)(pts_database_t *this, int cid, int kid);
+
+ /**
+ * Get the number of measurements for a functional component and AIK
+ *
+ * @param comp_name Component Functional Name
+ * @param keyid SHA-1 hash of AIK public key info
+ * @param algo Hash algorithm used for measurement
+ * @param cid Primary key of Component Functional Name entry
+ * @param kid Primary key of AIK entry in keys table
+ * @param count measurement count
+ * @return SUCCESS if COUNT was successful
+ */
+ status_t (*get_comp_measurement_count)(pts_database_t *this,
+ pts_comp_func_name_t *comp_name, chunk_t keyid,
+ pts_meas_algorithms_t algo, int *cid, int *kid,
+ int *count);
+
+ /**
+ * Destroys a pts_database_t object.
+ */
+ void (*destroy)(pts_database_t *this);
+
+};
+
+/**
+ * Creates an pts_database_t object
+ *
+ * @param uri database uri
+ */
+pts_database_t* pts_database_create(char *uri);
+
+#endif /** PTS_DATABASE_H_ @}*/
diff --git a/src/libpts/pts/pts_dh_group.c b/src/libpts/pts/pts_dh_group.c
new file mode 100644
index 000000000..fb141327f
--- /dev/null
+++ b/src/libpts/pts/pts_dh_group.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "pts_dh_group.h"
+
+#include <debug.h>
+
+/**
+ * Described in header.
+ */
+bool pts_dh_group_probe(pts_dh_group_t *dh_groups)
+{
+ enumerator_t *enumerator;
+ diffie_hellman_group_t dh_group;
+ const char *plugin_name;
+ char format1[] = " %s PTS DH group %N[%s] available";
+ char format2[] = " %s PTS DH group %N not available";
+
+ *dh_groups = PTS_DH_GROUP_NONE;
+
+ enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &dh_group, &plugin_name))
+ {
+ if (dh_group == MODP_1024_BIT)
+ {
+ *dh_groups |= PTS_DH_GROUP_IKE2;
+ DBG2(DBG_PTS, format1, "optional ", diffie_hellman_group_names,
+ dh_group, plugin_name);
+ }
+ else if (dh_group == MODP_1536_BIT)
+ {
+ *dh_groups |= PTS_DH_GROUP_IKE5;
+ DBG2(DBG_PTS, format1, "optional ", diffie_hellman_group_names,
+ dh_group, plugin_name);
+ }
+ else if (dh_group == MODP_2048_BIT)
+ {
+ *dh_groups |= PTS_DH_GROUP_IKE14;
+ DBG2(DBG_PTS, format1, "optional ", diffie_hellman_group_names,
+ dh_group, plugin_name);
+ }
+ else if (dh_group == ECP_256_BIT)
+ {
+ *dh_groups |= PTS_DH_GROUP_IKE19;
+ DBG2(DBG_PTS, format1, "mandatory", diffie_hellman_group_names,
+ dh_group, plugin_name);
+ }
+ else if (dh_group == ECP_384_BIT)
+ {
+ *dh_groups |= PTS_DH_GROUP_IKE20;
+ DBG2(DBG_PTS, format1, "optional ", diffie_hellman_group_names,
+ dh_group, plugin_name);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (*dh_groups & PTS_DH_GROUP_IKE19)
+ {
+ return TRUE;
+ }
+ else
+ {
+ DBG1(DBG_PTS, format2, "mandatory", diffie_hellman_group_names,
+ ECP_256_BIT);
+ }
+ return FALSE;
+}
+
+/**
+ * Described in header.
+ */
+bool pts_dh_group_update(char *dh_group, pts_dh_group_t *dh_groups)
+{
+ if (strcaseeq(dh_group, "ecp384"))
+ {
+ /* nothing to update, all groups are supported */
+ return TRUE;
+ }
+ if (strcaseeq(dh_group, "ecp256"))
+ {
+ /* remove DH group 20 */
+ *dh_groups &= ~PTS_DH_GROUP_IKE20;
+ return TRUE;
+ }
+ if (strcaseeq(dh_group, "modp2048"))
+ {
+ /* remove DH groups 19 and 20 */
+ *dh_groups &= ~(PTS_DH_GROUP_IKE20 | PTS_DH_GROUP_IKE19);
+ return TRUE;
+ }
+ if (strcaseeq(dh_group, "modp1536"))
+ {
+ /* remove DH groups 14, 19 and 20 */
+ *dh_groups &= ~(PTS_DH_GROUP_IKE20 | PTS_DH_GROUP_IKE19 |
+ PTS_DH_GROUP_IKE14);
+ return TRUE;
+ }
+ if (strcaseeq(dh_group, "modp1024"))
+ {
+ /* remove DH groups 5, 14, 19 and 20 */
+ *dh_groups &= ~(PTS_DH_GROUP_IKE20 | PTS_DH_GROUP_IKE19 |
+ PTS_DH_GROUP_IKE14 | PTS_DH_GROUP_IKE5);
+ return TRUE;
+ }
+ DBG1(DBG_PTS, "unknown DH group '%s' configured", dh_group);
+ return FALSE;
+}
+
+/**
+ * Described in header.
+ */
+pts_dh_group_t pts_dh_group_select(pts_dh_group_t supported_dh_groups,
+ pts_dh_group_t offered_dh_groups)
+{
+ if ((supported_dh_groups & PTS_DH_GROUP_IKE20) &&
+ (offered_dh_groups & PTS_DH_GROUP_IKE20))
+ {
+ return PTS_DH_GROUP_IKE20;
+ }
+ if ((supported_dh_groups & PTS_DH_GROUP_IKE19) &&
+ (offered_dh_groups & PTS_DH_GROUP_IKE19))
+ {
+ return PTS_DH_GROUP_IKE19;
+ }
+ if ((supported_dh_groups & PTS_DH_GROUP_IKE14) &&
+ (offered_dh_groups & PTS_DH_GROUP_IKE14))
+ {
+ return PTS_DH_GROUP_IKE14;
+ }
+ if ((supported_dh_groups & PTS_DH_GROUP_IKE5) &&
+ (offered_dh_groups & PTS_DH_GROUP_IKE5))
+ {
+ return PTS_DH_GROUP_IKE5;
+ }
+ if ((supported_dh_groups & PTS_DH_GROUP_IKE2) &&
+ (offered_dh_groups & PTS_DH_GROUP_IKE2))
+ {
+ return PTS_DH_GROUP_IKE2;
+ }
+ return PTS_DH_GROUP_NONE;
+}
+
+/**
+ * Described in header.
+ */
+diffie_hellman_group_t pts_dh_group_to_ike(pts_dh_group_t dh_group)
+{
+ switch (dh_group)
+ {
+ case PTS_DH_GROUP_IKE2:
+ return MODP_1024_BIT;
+ case PTS_DH_GROUP_IKE5:
+ return MODP_1536_BIT;
+ case PTS_DH_GROUP_IKE14:
+ return MODP_2048_BIT;
+ case PTS_DH_GROUP_IKE19:
+ return ECP_256_BIT;
+ case PTS_DH_GROUP_IKE20:
+ return ECP_384_BIT;
+ default:
+ return MODP_NONE;
+ }
+}
diff --git a/src/libpts/pts/pts_dh_group.h b/src/libpts/pts/pts_dh_group.h
new file mode 100644
index 000000000..8664a4b84
--- /dev/null
+++ b/src/libpts/pts/pts_dh_group.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_dh_group pts_dh_group
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_DH_GROUP_H_
+#define PTS_DH_GROUP_H_
+
+#include <library.h>
+#include <crypto/diffie_hellman.h>
+
+typedef enum pts_dh_group_t pts_dh_group_t;
+
+/**
+ * PTS Diffie Hellman Group Values
+ */
+enum pts_dh_group_t {
+ /** No DH Group */
+ PTS_DH_GROUP_NONE = 0,
+ /** IKE Group 2 */
+ PTS_DH_GROUP_IKE2 = (1<<15),
+ /** IKE Group 5 */
+ PTS_DH_GROUP_IKE5 = (1<<14),
+ /** IKE Group 14 */
+ PTS_DH_GROUP_IKE14 = (1<<13),
+ /** IKE Group 19 */
+ PTS_DH_GROUP_IKE19 = (1<<12),
+ /** IKE Group 20 */
+ PTS_DH_GROUP_IKE20 = (1<<11),
+};
+
+/**
+ * Diffie-Hellman Group Values
+ * see section 3.8.6 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |1|2|3|4|5|R|R|R|R|R|R|R|R|R|R|R|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+/**
+ * Probe available PTS Diffie-Hellman groups
+ *
+ * @param dh_groups returns set of available DH groups
+ * @return TRUE if mandatory DH groups are available
+ */
+bool pts_dh_group_probe(pts_dh_group_t *dh_groups);
+
+/**
+ * Update supported Diffie-Hellman groups according to configuration
+ *
+ * modp1024: PTS_DH_GROUP_IKE2
+ * modp1536: PTS_DH_GROUP_IKE2 | PTS_DH_GROUP_IKE5
+ * modp2048: PTS_DH_GROUP_IKE2 | PTS_DH_GROUP_IKE5 | PTS_DH_GROUP_IKE14
+ * ecp256: PTS_DH_GROUP_IKE2 | PTS_DH_GROUP_IKE5 | PTS_DH_GROUP_IKE14 |
+ * PTS_DH_GROUP_IKE19
+ * ecp384: PTS_DH_GROUP_IKE2 | PTS_DH_GROUP_IKE5 | PTS_DH_GROUP_IKE14 |
+ * PTS_DH_GROUP_IKE19 | PTS_DH_GROUP_IKE20
+ *
+ * The PTS-IMC is expected to select the strongest supported group
+ *
+ * @param dh_group configured DH group
+ * @param dh_groups returns set of available DH groups
+ */
+bool pts_dh_group_update(char *dh_group, pts_dh_group_t *dh_groups);
+
+/**
+ * Select the strongest supported Diffie-Hellman group
+ * among a set of offered DH groups
+ *
+ * @param supported_groups set of supported DH groups
+ * @param offered_groups set of offered DH groups
+ * @return selected DH group
+ */
+pts_dh_group_t pts_dh_group_select(pts_dh_group_t supported_dh_groups,
+ pts_dh_group_t offered_dh_groups);
+
+/**
+ * Convert pts_dh_group_t to diffie_hellman_group_t
+ *
+ * @param dh_group PTS DH group type
+ * @return IKE DH group type
+ */
+diffie_hellman_group_t pts_dh_group_to_ike(pts_dh_group_t dh_group);
+
+#endif /** PTS_DH_GROUP_H_ @}*/
diff --git a/src/libpts/pts/pts_error.c b/src/libpts/pts/pts_error.c
new file mode 100644
index 000000000..6e914b2a9
--- /dev/null
+++ b/src/libpts/pts/pts_error.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "pts_error.h"
+
+#include <bio/bio_writer.h>
+#include <ietf/ietf_attr_pa_tnc_error.h>
+
+ENUM(pts_error_code_names, TCG_PTS_RESERVED_ERROR, TCG_PTS_UNABLE_DET_PCR,
+ "Reserved Error",
+ "Hash Algorithm Not Supported",
+ "Invalid Path",
+ "File Not Found",
+ "Registry Not Supported",
+ "Registry Key Not Found",
+ "D-H Group Not Supported",
+ "DH-PN Nonce Not Acceptable",
+ "Invalid Functional Name Family",
+ "TPM Version Information Unavailable",
+ "Invalid File Pathname Delimiter",
+ "PTS Operation Not Supported",
+ "Unable To Update Reference Manifest",
+ "Unable To Perform Local Validation",
+ "Unable To Collect Current Evidence",
+ "Unable To Determine Transitive Trust Chain",
+ "Unable To Determine PCR"
+);
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t* pts_hash_alg_error_create(pts_meas_algorithms_t algorithms)
+{
+ bio_writer_t *writer;
+ chunk_t msg_info;
+ pa_tnc_attr_t *attr;
+
+ writer = bio_writer_create(4);
+ writer->write_uint16(writer, 0x0000);
+ writer->write_uint16(writer, algorithms);
+ msg_info = writer->get_buf(writer);
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG, TCG_PTS_HASH_ALG_NOT_SUPPORTED,
+ msg_info);
+ writer->destroy(writer);
+
+ return attr;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t* pts_dh_group_error_create(pts_dh_group_t dh_groups)
+{
+ bio_writer_t *writer;
+ chunk_t msg_info;
+ pa_tnc_attr_t *attr;
+
+ writer = bio_writer_create(4);
+ writer->write_uint16(writer, 0x0000);
+ writer->write_uint16(writer, dh_groups);
+ msg_info = writer->get_buf(writer);
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG, TCG_PTS_DH_GRPS_NOT_SUPPORTED,
+ msg_info);
+ writer->destroy(writer);
+
+ return attr;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t* pts_dh_nonce_error_create(int min_nonce_len, int max_nonce_len)
+{
+ bio_writer_t *writer;
+ chunk_t msg_info;
+ pa_tnc_attr_t *attr;
+
+ writer = bio_writer_create(4);
+ writer->write_uint16(writer, min_nonce_len);
+ writer->write_uint16(writer, max_nonce_len);
+ msg_info = writer->get_buf(writer);
+ attr = ietf_attr_pa_tnc_error_create(PEN_TCG, TCG_PTS_BAD_NONCE_LENGTH,
+ msg_info);
+ writer->destroy(writer);
+
+ return attr;
+}
diff --git a/src/libpts/pts/pts_error.h b/src/libpts/pts/pts_error.h
new file mode 100644
index 000000000..9a53abd98
--- /dev/null
+++ b/src/libpts/pts/pts_error.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_error pts_error
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_ERROR_H_
+#define PTS_ERROR_H_
+
+typedef enum pts_error_code_t pts_error_code_t;
+
+#include "pts_meas_algo.h"
+#include "pts_dh_group.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+#include <library.h>
+
+#define PTS_MIN_NONCE_LEN 17
+#define PTS_MAX_NONCE_LEN 0xffff
+
+/**
+ * PTS Attestation Error Codes
+ * see section 3.14.2 of PTS Protocol: Binding to TNC IF-M Specification
+ */
+enum pts_error_code_t {
+ TCG_PTS_RESERVED_ERROR = 0,
+ TCG_PTS_HASH_ALG_NOT_SUPPORTED = 1,
+ TCG_PTS_INVALID_PATH = 2,
+ TCG_PTS_FILE_NOT_FOUND = 3,
+ TCG_PTS_REG_NOT_SUPPORTED = 4,
+ TCG_PTS_REG_KEY_NOT_FOUND = 5,
+ TCG_PTS_DH_GRPS_NOT_SUPPORTED = 6,
+ TCG_PTS_BAD_NONCE_LENGTH = 7,
+ TCG_PTS_INVALID_NAME_FAM = 8,
+ TCG_PTS_TPM_VERS_NOT_SUPPORTED = 9,
+ TCG_PTS_INVALID_DELIMITER = 10,
+ TCG_PTS_OPERATION_NOT_SUPPORTED = 11,
+ TCG_PTS_RM_ERROR = 12,
+ TCG_PTS_UNABLE_LOCAL_VAL = 13,
+ TCG_PTS_UNABLE_CUR_EVID = 14,
+ TCG_PTS_UNABLE_DET_TTC = 15,
+ TCG_PTS_UNABLE_DET_PCR = 16,
+};
+
+/**
+ * enum name for pts_error_code_t.
+ */
+extern enum_name_t *pts_error_code_names;
+
+/**
+ * Creates a PTS Hash Algorithm Not Supported Error Attribute
+ * see section 4.2.2 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * @param algorithms supported measurement hash algorithms
+ */
+pa_tnc_attr_t* pts_hash_alg_error_create(pts_meas_algorithms_t algorithms);
+
+/**
+ * Creates a PTS DH Group Not Supported Error Attribute
+ * see section 4.2.4 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * @param dh_groups supported DH groups
+ */
+pa_tnc_attr_t* pts_dh_group_error_create(pts_dh_group_t dh_groups);
+
+/**
+ * Creates a PTS DH PN Nonce Not Supported Error Attribute
+ * see section 4.2.5 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * @param min_nonce_len minimum nonce length
+ * @param max_nonce_len maximum nonce length
+ */
+pa_tnc_attr_t* pts_dh_nonce_error_create(int min_nonce_len, int max_nonce_len);
+
+#endif /** PTS_ERROR_H_ @}*/
diff --git a/src/libpts/pts/pts_file_meas.c b/src/libpts/pts/pts_file_meas.c
new file mode 100644
index 000000000..f0e0d4c0a
--- /dev/null
+++ b/src/libpts/pts/pts_file_meas.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "pts_file_meas.h"
+
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_pts_file_meas_t private_pts_file_meas_t;
+
+/**
+ * Private data of a pts_file_meas_t object.
+ *
+ */
+struct private_pts_file_meas_t {
+
+ /**
+ * Public pts_file_meas_t interface.
+ */
+ pts_file_meas_t public;
+
+ /**
+ * ID of PTS File Measurement Request
+ */
+ u_int16_t request_id;
+
+ /**
+ * List of File Measurements
+ */
+ linked_list_t *list;
+};
+
+typedef struct entry_t entry_t;
+
+/**
+ * PTS File Measurement entry
+ */
+struct entry_t {
+ char *filename;
+ chunk_t measurement;
+};
+
+/**
+ * Free an entry_t object
+ */
+static void free_entry(entry_t *entry)
+{
+ if (entry)
+ {
+ free(entry->filename);
+ free(entry->measurement.ptr);
+ free(entry);
+ }
+}
+
+METHOD(pts_file_meas_t, get_request_id, u_int16_t,
+ private_pts_file_meas_t *this)
+{
+ return this->request_id;
+}
+
+METHOD(pts_file_meas_t, get_file_count, int,
+ private_pts_file_meas_t *this)
+{
+ return this->list->get_count(this->list);
+}
+
+METHOD(pts_file_meas_t, add, void,
+ private_pts_file_meas_t *this, char *filename, chunk_t measurement)
+{
+ entry_t *entry;
+
+ entry = malloc_thing(entry_t);
+ entry->filename = strdup(filename);
+ entry->measurement = chunk_clone(measurement);
+
+ this->list->insert_last(this->list, entry);
+}
+
+/**
+ * Enumerate file measurement entries
+ */
+static bool entry_filter(void *null, entry_t **entry, char **filename,
+ void *i2, chunk_t *measurement)
+{
+ *filename = (*entry)->filename;
+ *measurement = (*entry)->measurement;
+ return TRUE;
+}
+
+METHOD(pts_file_meas_t, create_enumerator, enumerator_t*,
+ private_pts_file_meas_t *this)
+{
+ return enumerator_create_filter(this->list->create_enumerator(this->list),
+ (void*)entry_filter, NULL, NULL);
+}
+
+METHOD(pts_file_meas_t, verify, bool,
+ private_pts_file_meas_t *this, enumerator_t *e_hash, bool is_dir)
+{
+ char *filename;
+ chunk_t measurement;
+ entry_t *entry;
+ enumerator_t *enumerator;
+ bool found, success = TRUE;
+
+ while (e_hash->enumerate(e_hash, &filename, &measurement))
+ {
+ found = FALSE;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (!is_dir || streq(filename, entry->filename))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ DBG1(DBG_PTS, " no measurement found for '%s'", filename);
+ success = FALSE;
+ continue;
+ }
+ if (chunk_equals(measurement, entry->measurement))
+ {
+ DBG2(DBG_PTS, " %#B for '%s' is ok", &measurement, filename);
+ }
+ else
+ {
+ DBG1(DBG_PTS, " %#B for '%s' is incorrect", &measurement, filename);
+ success = FALSE;
+ }
+ if (!is_dir)
+ {
+ break;
+ }
+ }
+ return success;
+}
+
+METHOD(pts_file_meas_t, destroy, void,
+ private_pts_file_meas_t *this)
+{
+ this->list->destroy_function(this->list, (void *)free_entry);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_file_meas_t *pts_file_meas_create(u_int16_t request_id)
+{
+ private_pts_file_meas_t *this;
+
+ INIT(this,
+ .public = {
+ .get_request_id = _get_request_id,
+ .get_file_count = _get_file_count,
+ .add = _add,
+ .create_enumerator = _create_enumerator,
+ .verify = _verify,
+ .destroy = _destroy,
+ },
+ .request_id = request_id,
+ .list = linked_list_create(),
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/pts_file_meas.h b/src/libpts/pts/pts_file_meas.h
new file mode 100644
index 000000000..3ebb5c2a0
--- /dev/null
+++ b/src/libpts/pts/pts_file_meas.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_file_meas pts_file_meas
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_FILE_MEAS_H_
+#define PTS_FILE_MEAS_H_
+
+#include <library.h>
+
+typedef struct pts_file_meas_t pts_file_meas_t;
+
+/**
+ * Class storing PTS File Measurements
+ */
+struct pts_file_meas_t {
+
+ /**
+ * Get the ID of the PTS File Measurement Request
+ *
+ * @return ID of PTS File Measurement Request
+ */
+ u_int16_t (*get_request_id)(pts_file_meas_t *this);
+
+ /**
+ * Get the number of measured files
+ *
+ * @return Number of measured files
+ */
+ int (*get_file_count)(pts_file_meas_t *this);
+
+ /**
+ * Add a PTS File Measurement
+ *
+ * @param filename Name of measured file or directory
+ * @param measurement PTS Measurement hash
+ */
+ void (*add)(pts_file_meas_t *this, char *filename, chunk_t measurement);
+
+ /**
+ * Create a PTS File Measurement enumerator
+ *
+ * @return Enumerator returning filename and measurement
+ */
+ enumerator_t* (*create_enumerator)(pts_file_meas_t *this);
+
+ /**
+ * Verify stored hashes against PTS File Measurements
+ *
+ * @param e_hash Hash enumerator
+ * @paraem is_dir TRUE for directory contents hashes
+ * @return TRUE if all hashes match a measurement
+ */
+ bool (*verify)(pts_file_meas_t *this, enumerator_t *e_hash, bool is_dir);
+
+ /**
+ * Destroys a pts_file_meas_t object.
+ */
+ void (*destroy)(pts_file_meas_t *this);
+
+};
+
+/**
+ * Creates a pts_file_meas_t object
+ *
+ * @param request_id ID of PTS File Measurement Request
+ */
+pts_file_meas_t* pts_file_meas_create(u_int16_t request_id);
+
+#endif /** PTS_FILE_MEAS_H_ @}*/
diff --git a/src/libpts/pts/pts_file_meta.c b/src/libpts/pts/pts_file_meta.c
new file mode 100644
index 000000000..6ed1c01b4
--- /dev/null
+++ b/src/libpts/pts/pts_file_meta.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "pts_file_meta.h"
+
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_pts_file_meta_t private_pts_file_meta_t;
+
+/**
+ * Private data of a pts_file_meta_t object.
+ *
+ */
+struct private_pts_file_meta_t {
+
+ /**
+ * Public pts_file_meta_t interface.
+ */
+ pts_file_meta_t public;
+
+ /**
+ * List of File Metadata
+ */
+ linked_list_t *list;
+};
+
+/**
+ * Free an pts_file_metadata_t object
+ */
+static void free_entry(pts_file_metadata_t *entry)
+{
+ if (entry)
+ {
+ free(entry->filename);
+ free(entry);
+ }
+}
+
+METHOD(pts_file_meta_t, get_file_count, int,
+ private_pts_file_meta_t *this)
+{
+ return this->list->get_count(this->list);
+}
+
+METHOD(pts_file_meta_t, add, void,
+ private_pts_file_meta_t *this, pts_file_metadata_t *metadata)
+{
+ this->list->insert_last(this->list, metadata);
+}
+
+METHOD(pts_file_meta_t, create_enumerator, enumerator_t*,
+ private_pts_file_meta_t *this)
+{
+ return this->list->create_enumerator(this->list);
+}
+
+METHOD(pts_file_meta_t, destroy, void,
+ private_pts_file_meta_t *this)
+{
+ this->list->destroy_function(this->list, (void *)free_entry);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_file_meta_t *pts_file_meta_create()
+{
+ private_pts_file_meta_t *this;
+
+ INIT(this,
+ .public = {
+ .get_file_count = _get_file_count,
+ .add = _add,
+ .create_enumerator = _create_enumerator,
+ .destroy = _destroy,
+ },
+ .list = linked_list_create(),
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/pts_file_meta.h b/src/libpts/pts/pts_file_meta.h
new file mode 100644
index 000000000..3f1813306
--- /dev/null
+++ b/src/libpts/pts/pts_file_meta.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_file_meta pts_file_meta
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_FILE_META_H_
+#define PTS_FILE_META_H_
+
+#include "pts_file_type.h"
+
+#include <time.h>
+#include <library.h>
+
+typedef struct pts_file_meta_t pts_file_meta_t;
+typedef struct pts_file_metadata_t pts_file_metadata_t;
+
+/**
+ * Structure holding file metadata
+ */
+struct pts_file_metadata_t {
+ pts_file_type_t type;
+ u_int64_t filesize;
+ u_int64_t created;
+ u_int64_t modified;
+ u_int64_t accessed;
+ u_int64_t owner;
+ u_int64_t group;
+ char *filename;
+};
+
+/**
+ * Class storing PTS File Metadata
+ */
+struct pts_file_meta_t {
+
+ /**
+ * Get the number of files
+ *
+ * @return Number of files
+ */
+ int (*get_file_count)(pts_file_meta_t *this);
+
+ /**
+ * Add PTS File Metadata
+ *
+ * @param filename Name of measured file or directory
+ * @param metadata File metadata
+ */
+ void (*add)(pts_file_meta_t *this, pts_file_metadata_t *metadata);
+
+ /**
+ * Create a PTS File Metadata enumerator
+ *
+ * @return Enumerator returning file metadata
+ */
+ enumerator_t* (*create_enumerator)(pts_file_meta_t *this);
+
+ /**
+ * Destroys a pts_file_meta_t object.
+ */
+ void (*destroy)(pts_file_meta_t *this);
+
+};
+
+/**
+ * Creates a pts_file_meta_t object
+ */
+pts_file_meta_t* pts_file_meta_create();
+
+#endif /** PTS_FILE_MEAS_H_ @}*/
diff --git a/src/libpts/pts/pts_file_type.c b/src/libpts/pts/pts_file_type.c
new file mode 100644
index 000000000..fe849dea4
--- /dev/null
+++ b/src/libpts/pts/pts_file_type.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 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 "pts_file_type.h"
+
+ENUM(pts_file_type_names, PTS_FILE_OTHER, PTS_FILE_SOCKET,
+ "Other",
+ "FIFO",
+ "Character-Special",
+ "Reserved-3",
+ "Directory",
+ "Reserved-5",
+ "Block-Special",
+ "Reserved-7",
+ "Regular",
+ "Reserved-9",
+ "Symbolic-Link",
+ "Reserved-11",
+ "Socket"
+);
+
diff --git a/src/libpts/pts/pts_file_type.h b/src/libpts/pts/pts_file_type.h
new file mode 100644
index 000000000..c1d236888
--- /dev/null
+++ b/src/libpts/pts/pts_file_type.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_file_type pts_file_type
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_FILE_TYPE_H_
+#define PTS_FILE_TYPE_H_
+
+#include <library.h>
+
+typedef enum pts_file_type_t pts_file_type_t;
+
+/**
+ * PTS File Type
+ * see section 3.17.3 of PTS Protocol: Binding to TNC IF-M Specification
+ */
+enum pts_file_type_t {
+ /** Either unknown or different from standardized types */
+ PTS_FILE_OTHER = 0x0000,
+ /** Pipe communication file */
+ PTS_FILE_FIFO = 0x0001,
+ /** Character special file */
+ PTS_FILE_CHAR_SPEC = 0x0002,
+ /** Reserved */
+ PTS_FILE_RESERVED_3 = 0x0003,
+ /** Directory */
+ PTS_FILE_DIRECTORY = 0x0004,
+ /** Reserved */
+ PTS_FILE_RESERVED_5 = 0x0005,
+ /** Block special file */
+ PTS_FILE_BLOCK_SPEC = 0x0006,
+ /** Reserved */
+ PTS_FILE_RESERVED_7 = 0x0007,
+ /** Regular file */
+ PTS_FILE_REGULAR = 0x0008,
+ /** Reserved */
+ PTS_FILE_RESERVED_9 = 0x0009,
+ /** Symbolic link */
+ PTS_FILE_SYM_LINK = 0x000A,
+ /** Reserved */
+ PTS_FILE_RESERVED_11 = 0x000B,
+ /** Socket communication special file */
+ PTS_FILE_SOCKET = 0x000C,
+};
+
+extern enum_name_t *pts_file_type_names;
+
+#endif /** PTS_FILE_TYPE_H_ @}*/
diff --git a/src/libpts/pts/pts_meas_algo.c b/src/libpts/pts/pts_meas_algo.c
new file mode 100644
index 000000000..865857d3c
--- /dev/null
+++ b/src/libpts/pts/pts_meas_algo.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2011 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 "pts_meas_algo.h"
+
+#include <debug.h>
+
+ENUM(pts_meas_algorithm_names, PTS_MEAS_ALGO_NONE, PTS_MEAS_ALGO_SHA384,
+ "None",
+ "SHA1",
+ "SHA256",
+ "SHA384"
+);
+
+/**
+ * Described in header.
+ */
+bool pts_meas_algo_probe(pts_meas_algorithms_t *algorithms)
+{
+ enumerator_t *enumerator;
+ hash_algorithm_t hash_alg;
+ const char *plugin_name;
+ char format1[] = " %s PTS measurement algorithm %N[%s] available";
+ char format2[] = " %s PTS measurement algorithm %N not available";
+
+ *algorithms = 0;
+
+ enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
+ while (enumerator->enumerate(enumerator, &hash_alg, &plugin_name))
+ {
+ if (hash_alg == HASH_SHA1)
+ {
+ *algorithms |= PTS_MEAS_ALGO_SHA1;
+ DBG2(DBG_PTS, format1, "mandatory", hash_algorithm_names, hash_alg,
+ plugin_name);
+ }
+ else if (hash_alg == HASH_SHA256)
+ {
+ *algorithms |= PTS_MEAS_ALGO_SHA256;
+ DBG2(DBG_PTS, format1, "mandatory", hash_algorithm_names, hash_alg,
+ plugin_name);
+ }
+ else if (hash_alg == HASH_SHA384)
+ {
+ *algorithms |= PTS_MEAS_ALGO_SHA384;
+ DBG2(DBG_PTS, format1, "optional ", hash_algorithm_names, hash_alg,
+ plugin_name);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!(*algorithms & PTS_MEAS_ALGO_SHA384))
+ {
+ DBG1(DBG_PTS, format2, "optional ", hash_algorithm_names, HASH_SHA384);
+ }
+ if ((*algorithms & PTS_MEAS_ALGO_SHA1) &&
+ (*algorithms & PTS_MEAS_ALGO_SHA256))
+ {
+ return TRUE;
+ }
+ if (!(*algorithms & PTS_MEAS_ALGO_SHA1))
+ {
+ DBG1(DBG_PTS, format2, "mandatory", hash_algorithm_names, HASH_SHA1);
+ }
+ if (!(*algorithms & PTS_MEAS_ALGO_SHA256))
+ {
+ DBG1(DBG_PTS, format2, "mandatory", hash_algorithm_names, HASH_SHA256);
+ }
+ return FALSE;
+}
+
+/**
+ * Described in header.
+ */
+bool pts_meas_algo_update(char *hash_alg, pts_meas_algorithms_t *algorithms)
+{
+ if (strcaseeq(hash_alg, "sha384") || strcaseeq(hash_alg, "sha2_384"))
+ {
+ /* nothing to update, all algorithms are supported */
+ return TRUE;
+ }
+ if (strcaseeq(hash_alg, "sha256") || strcaseeq(hash_alg, "sha2_256"))
+ {
+ /* remove SHA384algorithm */
+ *algorithms &= ~PTS_MEAS_ALGO_SHA384;
+ return TRUE;
+ }
+ if (strcaseeq(hash_alg, "sha1"))
+ {
+ /* remove SHA384 and SHA256 algorithms */
+ *algorithms &= ~(PTS_MEAS_ALGO_SHA384 | PTS_MEAS_ALGO_SHA256);
+ return TRUE;
+ }
+ DBG1(DBG_PTS, "unknown hash algorithm '%s' configured", hash_alg);
+ return FALSE;
+}
+
+/**
+ * Described in header.
+ */
+pts_meas_algorithms_t pts_meas_algo_select(pts_meas_algorithms_t supported_algos,
+ pts_meas_algorithms_t offered_algos)
+{
+ if ((supported_algos & PTS_MEAS_ALGO_SHA384) &&
+ (offered_algos & PTS_MEAS_ALGO_SHA384))
+ {
+ return PTS_MEAS_ALGO_SHA384;
+ }
+ if ((supported_algos & PTS_MEAS_ALGO_SHA256) &&
+ (offered_algos & PTS_MEAS_ALGO_SHA256))
+ {
+ return PTS_MEAS_ALGO_SHA256;
+ }
+ if ((supported_algos & PTS_MEAS_ALGO_SHA1) &&
+ (offered_algos & PTS_MEAS_ALGO_SHA1))
+ {
+ return PTS_MEAS_ALGO_SHA1;
+ }
+ return PTS_MEAS_ALGO_NONE;
+}
+
+/**
+ * Described in header.
+ */
+hash_algorithm_t pts_meas_algo_to_hash(pts_meas_algorithms_t algorithm)
+{
+ switch (algorithm)
+ {
+ case PTS_MEAS_ALGO_SHA1:
+ return HASH_SHA1;
+ case PTS_MEAS_ALGO_SHA256:
+ return HASH_SHA256;
+ case PTS_MEAS_ALGO_SHA384:
+ return HASH_SHA384;
+ default:
+ return HASH_UNKNOWN;
+ }
+}
+
+/**
+ * Described in header.
+ */
+size_t pts_meas_algo_hash_size(pts_meas_algorithms_t algorithm)
+{
+ switch (algorithm)
+ {
+ case PTS_MEAS_ALGO_SHA1:
+ return HASH_SIZE_SHA1;
+ case PTS_MEAS_ALGO_SHA256:
+ return HASH_SIZE_SHA256;
+ case PTS_MEAS_ALGO_SHA384:
+ return HASH_SIZE_SHA384;
+ case PTS_MEAS_ALGO_NONE:
+ default:
+ return 0;
+ }
+}
+
diff --git a/src/libpts/pts/pts_meas_algo.h b/src/libpts/pts/pts_meas_algo.h
new file mode 100644
index 000000000..1d96a4946
--- /dev/null
+++ b/src/libpts/pts/pts_meas_algo.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_meas_algo pts_meas_algo
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_MEAS_ALGO_H_
+#define PTS_MEAS_ALGO_H_
+
+#include <library.h>
+#include <crypto/hashers/hasher.h>
+
+typedef enum pts_meas_algorithms_t pts_meas_algorithms_t;
+
+/**
+ * PTS Measurement Algorithms
+ */
+enum pts_meas_algorithms_t {
+ PTS_MEAS_ALGO_NONE = 0,
+ PTS_MEAS_ALGO_SHA1 = (1<<15),
+ PTS_MEAS_ALGO_SHA256 = (1<<14),
+ PTS_MEAS_ALGO_SHA384 = (1<<13),
+};
+
+/**
+ * enum name for pts_meas_algorithms_t.
+ */
+extern enum_name_t *pts_meas_algorithm_names;
+
+/**
+ * Diffie-Hellman Hash Algorithm Values
+ * see section 3.8.5 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |1|2|3|R|R|R|R|R|R|R|R|R|R|R|R|R|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+/**
+ * Probe available PTS measurement algorithms
+ *
+ * @param algorithms set of available algorithms
+ * @return TRUE if mandatory algorithms are available
+ */
+bool pts_meas_algo_probe(pts_meas_algorithms_t *algorithms);
+
+/**
+ * Update supported PTS measurement algorithms according to configuration
+ *
+ * sha1 : PTS_MEAS_ALGO_SHA1
+ * sha256: PTS_MEAS_ALGO_SHA1 | PTS_MEAS_ALGO_SHA256
+ * sha384: PTS_MEAS_ALGO_SHA1 | PTS_MEAS_ALGO_SHA256 | PTS_MEAS_ALGO_SHA384
+ *
+ * The PTS-IMC is expected to select the strongest supported algorithm
+ *
+ * @param hash_alg configured hash algorithm
+ * @param algorithms returns set of available PTS measurement algorithms
+ */
+bool pts_meas_algo_update(char *hash_alg, pts_meas_algorithms_t *algorithms);
+
+/**
+ * Select the strongest PTS measurement algorithm
+ * among a set of offered PTS measurement algorithms
+ *
+ * @param supported_algos set of supported PTS measurement algorithms
+ * @param offered_algos set of offered PTS measurements algorithms
+ * @return selected algorithm
+ */
+pts_meas_algorithms_t pts_meas_algo_select(pts_meas_algorithms_t supported_algos,
+ pts_meas_algorithms_t offered_algos);
+
+/**
+ * Convert pts_meas_algorithms_t to hash_algorithm_t
+ *
+ * @param algorithm PTS measurement algorithm type
+ * @return libstrongswan hash algorithm type
+ */
+hash_algorithm_t pts_meas_algo_to_hash(pts_meas_algorithms_t algorithm);
+
+/**
+ * Return the hash size of a pts_meas_algorithm
+ *
+ * @param algorithm PTS measurement algorithm type
+ * @return hash size in bytes
+ */
+size_t pts_meas_algo_hash_size(pts_meas_algorithms_t algorithm);
+
+#endif /** PTS_MEAS_ALGO_H_ @}*/
diff --git a/src/libpts/pts/pts_proto_caps.h b/src/libpts/pts/pts_proto_caps.h
new file mode 100644
index 000000000..4346d9b79
--- /dev/null
+++ b/src/libpts/pts/pts_proto_caps.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_proto_caps pts_proto_caps
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_PROTO_CAPS_H_
+#define PTS_PROTO_CAPS_H_
+
+typedef enum pts_proto_caps_flag_t pts_proto_caps_flag_t;
+
+#include <library.h>
+
+/**
+ * PTS Protocol Capabilities Flags
+ */
+enum pts_proto_caps_flag_t {
+ /** XML based Evidence Support flag */
+ PTS_PROTO_CAPS_X = (1<<0),
+ /** Trusted Platform Evidence flag */
+ PTS_PROTO_CAPS_T = (1<<1),
+ /** DH Nonce Negotiation Support flag */
+ PTS_PROTO_CAPS_D = (1<<2),
+ /** Verification Support flag */
+ PTS_PROTO_CAPS_V = (1<<3),
+ /** Current (In-Memory) Evidence Support flag */
+ PTS_PROTO_CAPS_C = (1<<4),
+};
+
+#endif /** PTS_PROTO_CAPS_H_ @}*/
diff --git a/src/libpts/pts/pts_req_func_comp_evid.h b/src/libpts/pts/pts_req_func_comp_evid.h
new file mode 100644
index 000000000..bbf5bbf5b
--- /dev/null
+++ b/src/libpts/pts/pts_req_func_comp_evid.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_req_func_comp_evid pts_req_func_comp_evid
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_REQ_FUNC_COMP_EVID_H_
+#define PTS_REQ_FUNC_COMP_EVID_H_
+
+typedef enum pts_req_func_comp_evid_t pts_req_func_comp_evid_t;
+
+#include <library.h>
+
+/**
+ * PTS Request Functional Component Evidence Flags
+ */
+enum pts_req_func_comp_evid_t {
+ /** Transitive Trust Chain flag */
+ PTS_REQ_FUNC_COMP_EVID_TTC = (1<<7),
+ /** Verify Component flag */
+ PTS_REQ_FUNC_COMP_EVID_VER = (1<<6),
+ /** Current Evidence flag */
+ PTS_REQ_FUNC_COMP_EVID_CURR = (1<<5),
+ /** PCR Information flag */
+ PTS_REQ_FUNC_COMP_EVID_PCR = (1<<4),
+};
+
+#endif /** PTS_FUNCT_COMP_EVID_REQ_H_ @}*/
diff --git a/src/libpts/pts/pts_simple_evid_final.h b/src/libpts/pts/pts_simple_evid_final.h
new file mode 100644
index 000000000..0c8dea0cc
--- /dev/null
+++ b/src/libpts/pts/pts_simple_evid_final.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 pts_simple_evid_final pts_rsimple_evid_final
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_SIMPLE_EVID_FINAL_H_
+#define PTS_SIMPLE_EVID_FINAL_H_
+
+typedef enum pts_simple_evid_final_flag_t pts_simple_evid_final_flag_t;
+
+#include <library.h>
+
+/**
+ * PTS Simple Evidence Final Flags
+ */
+enum pts_simple_evid_final_flag_t {
+ /** TPM PCR Composite and TPM Quote Signature not included */
+ PTS_SIMPLE_EVID_FINAL_NO = 0x00,
+ /** TPM PCR Composite and TPM Quote Signature included
+ * using TPM_QUOTE_INFO */
+ PTS_SIMPLE_EVID_FINAL_QUOTE_INFO = 0x40,
+ /** TPM PCR Composite and TPM Quote Signature included
+ * using TPM_QUOTE_INFO2, TPM_CAP_VERSION_INFO not appended */
+ PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2 = 0x80,
+ /** TPM PCR Composite and TPM Quote Signature included
+ * using TPM_QUOTE_INFO2, TPM_CAP_VERSION_INFO appended */
+ PTS_SIMPLE_EVID_FINAL_QUOTE_INFO2_CAP_VER = 0xC0,
+ /** Evidence Signature included */
+ PTS_SIMPLE_EVID_FINAL_EVID_SIG = 0x20,
+};
+
+#endif /** PTS_SIMPLE_EVID_FINAL_H_ @}*/
diff --git a/src/libpts/tcg/tcg_attr.c b/src/libpts/tcg/tcg_attr.c
new file mode 100644
index 000000000..656791a8f
--- /dev/null
+++ b/src/libpts/tcg/tcg_attr.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2011 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 "tcg_attr.h"
+#include "tcg/tcg_pts_attr_proto_caps.h"
+#include "tcg/tcg_pts_attr_dh_nonce_params_req.h"
+#include "tcg/tcg_pts_attr_dh_nonce_params_resp.h"
+#include "tcg/tcg_pts_attr_dh_nonce_finish.h"
+#include "tcg/tcg_pts_attr_meas_algo.h"
+#include "tcg/tcg_pts_attr_get_tpm_version_info.h"
+#include "tcg/tcg_pts_attr_tpm_version_info.h"
+#include "tcg/tcg_pts_attr_get_aik.h"
+#include "tcg/tcg_pts_attr_aik.h"
+#include "tcg/tcg_pts_attr_req_func_comp_evid.h"
+#include "tcg/tcg_pts_attr_gen_attest_evid.h"
+#include "tcg/tcg_pts_attr_simple_comp_evid.h"
+#include "tcg/tcg_pts_attr_simple_evid_final.h"
+#include "tcg/tcg_pts_attr_req_file_meas.h"
+#include "tcg/tcg_pts_attr_file_meas.h"
+#include "tcg/tcg_pts_attr_req_file_meta.h"
+#include "tcg/tcg_pts_attr_unix_file_meta.h"
+
+ENUM_BEGIN(tcg_attr_names, TCG_PTS_REQ_FUNC_COMP_EVID,
+ TCG_PTS_REQ_FUNC_COMP_EVID,
+ "Request Functional Component Evidence");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_GEN_ATTEST_EVID,
+ TCG_PTS_GEN_ATTEST_EVID,
+ TCG_PTS_REQ_FUNC_COMP_EVID,
+ "Generate Attestation Evidence");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_SIMPLE_COMP_EVID,
+ TCG_PTS_SIMPLE_COMP_EVID,
+ TCG_PTS_GEN_ATTEST_EVID,
+ "Simple Component Evidence");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_SIMPLE_EVID_FINAL,
+ TCG_PTS_SIMPLE_EVID_FINAL,
+ TCG_PTS_SIMPLE_COMP_EVID,
+ "Simple Evidence Final");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_VERIFICATION_RESULT,
+ TCG_PTS_VERIFICATION_RESULT,
+ TCG_PTS_SIMPLE_EVID_FINAL,
+ "Verification Result");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_INTEG_REPORT,
+ TCG_PTS_INTEG_REPORT,
+ TCG_PTS_VERIFICATION_RESULT,
+ "Integrity Report");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_FILE_META,
+ TCG_PTS_REQ_FILE_META,
+ TCG_PTS_INTEG_REPORT,
+ "Request File Metadata");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_WIN_FILE_META,
+ TCG_PTS_WIN_FILE_META,
+ TCG_PTS_REQ_FILE_META,
+ "Windows-Style File Metadata");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_UNIX_FILE_META,
+ TCG_PTS_UNIX_FILE_META,
+ TCG_PTS_WIN_FILE_META,
+ "Unix-Style File Metadata");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_REGISTRY_VALUE,
+ TCG_PTS_REQ_REGISTRY_VALUE,
+ TCG_PTS_UNIX_FILE_META,
+ "Request Registry Value");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REGISTRY_VALUE,
+ TCG_PTS_REGISTRY_VALUE,
+ TCG_PTS_REQ_REGISTRY_VALUE,
+ "Registry Value");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_FILE_MEAS,
+ TCG_PTS_REQ_FILE_MEAS,
+ TCG_PTS_REGISTRY_VALUE,
+ "Request File Measurement");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_FILE_MEAS,
+ TCG_PTS_FILE_MEAS,
+ TCG_PTS_REQ_FILE_MEAS,
+ "File Measurement");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_INTEG_MEAS_LOG,
+ TCG_PTS_REQ_INTEG_MEAS_LOG,
+ TCG_PTS_FILE_MEAS,
+ "Request Integrity Measurement Log");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_INTEG_MEAS_LOG,
+ TCG_PTS_INTEG_MEAS_LOG,
+ TCG_PTS_REQ_INTEG_MEAS_LOG,
+ "Integrity Measurement Log");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_PROTO_CAPS,
+ TCG_PTS_REQ_PROTO_CAPS,
+ TCG_PTS_INTEG_MEAS_LOG,
+ "Request PTS Protocol Capabilities");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_PROTO_CAPS,
+ TCG_PTS_PROTO_CAPS,
+ TCG_PTS_REQ_PROTO_CAPS,
+ "PTS Protocol Capabilities");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_DH_NONCE_PARAMS_REQ,
+ TCG_PTS_DH_NONCE_PARAMS_REQ,
+ TCG_PTS_PROTO_CAPS,
+ "DH Nonce Parameters Request");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_DH_NONCE_PARAMS_RESP,
+ TCG_PTS_DH_NONCE_PARAMS_RESP,
+ TCG_PTS_DH_NONCE_PARAMS_REQ,
+ "DH Nonce Parameters Response");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_DH_NONCE_FINISH,
+ TCG_PTS_DH_NONCE_FINISH,
+ TCG_PTS_DH_NONCE_PARAMS_RESP,
+ "DH Nonce Finish");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_MEAS_ALGO,
+ TCG_PTS_MEAS_ALGO,
+ TCG_PTS_DH_NONCE_FINISH,
+ "PTS Measurement Algorithm Request");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_MEAS_ALGO_SELECTION,
+ TCG_PTS_MEAS_ALGO_SELECTION,
+ TCG_PTS_MEAS_ALGO,
+ "PTS Measurement Algorithm");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_GET_TPM_VERSION_INFO,
+ TCG_PTS_GET_TPM_VERSION_INFO,
+ TCG_PTS_MEAS_ALGO_SELECTION,
+ "Get TPM Version Information");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_TPM_VERSION_INFO,
+ TCG_PTS_TPM_VERSION_INFO,
+ TCG_PTS_GET_TPM_VERSION_INFO,
+ "TPM Version Information");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_TEMPL_REF_MANI_SET_META,
+ TCG_PTS_REQ_TEMPL_REF_MANI_SET_META,
+ TCG_PTS_TPM_VERSION_INFO,
+ "Request Template Reference Manifest Set Metadata");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_TEMPL_REF_MANI_SET_META,
+ TCG_PTS_TEMPL_REF_MANI_SET_META,
+ TCG_PTS_REQ_TEMPL_REF_MANI_SET_META,
+ "Template Reference Manifest Set Metadata");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_UPDATE_TEMPL_REF_MANI,
+ TCG_PTS_UPDATE_TEMPL_REF_MANI,
+ TCG_PTS_TEMPL_REF_MANI_SET_META,
+ "Update Template Reference Manifest");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_GET_AIK,
+ TCG_PTS_GET_AIK,
+ TCG_PTS_UPDATE_TEMPL_REF_MANI,
+ "Get Attestation Identity Key");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_AIK,
+ TCG_PTS_AIK,
+ TCG_PTS_GET_AIK,
+ "Attestation Identity Key");
+ENUM_END(tcg_attr_names, TCG_PTS_AIK);
+
+/**
+ * See header
+ */
+pa_tnc_attr_t* tcg_attr_create_from_data(u_int32_t type, chunk_t value)
+{
+ switch (type)
+ {
+ case TCG_PTS_REQ_PROTO_CAPS:
+ return tcg_pts_attr_proto_caps_create_from_data(value, TRUE);
+ case TCG_PTS_PROTO_CAPS:
+ return tcg_pts_attr_proto_caps_create_from_data(value, FALSE);
+ case TCG_PTS_DH_NONCE_PARAMS_REQ:
+ return tcg_pts_attr_dh_nonce_params_req_create_from_data(value);
+ case TCG_PTS_DH_NONCE_PARAMS_RESP:
+ return tcg_pts_attr_dh_nonce_params_resp_create_from_data(value);
+ case TCG_PTS_DH_NONCE_FINISH:
+ return tcg_pts_attr_dh_nonce_finish_create_from_data(value);
+ case TCG_PTS_MEAS_ALGO:
+ return tcg_pts_attr_meas_algo_create_from_data(value, FALSE);
+ case TCG_PTS_MEAS_ALGO_SELECTION:
+ return tcg_pts_attr_meas_algo_create_from_data(value, TRUE);
+ case TCG_PTS_GET_TPM_VERSION_INFO:
+ return tcg_pts_attr_get_tpm_version_info_create_from_data(value);
+ case TCG_PTS_TPM_VERSION_INFO:
+ return tcg_pts_attr_tpm_version_info_create_from_data(value);
+ case TCG_PTS_GET_AIK:
+ return tcg_pts_attr_get_aik_create_from_data(value);
+ case TCG_PTS_AIK:
+ return tcg_pts_attr_aik_create_from_data(value);
+ case TCG_PTS_REQ_FUNC_COMP_EVID:
+ return tcg_pts_attr_req_func_comp_evid_create_from_data(value);
+ case TCG_PTS_GEN_ATTEST_EVID:
+ return tcg_pts_attr_gen_attest_evid_create_from_data(value);
+ case TCG_PTS_SIMPLE_COMP_EVID:
+ return tcg_pts_attr_simple_comp_evid_create_from_data(value);
+ case TCG_PTS_SIMPLE_EVID_FINAL:
+ return tcg_pts_attr_simple_evid_final_create_from_data(value);
+ case TCG_PTS_REQ_FILE_MEAS:
+ return tcg_pts_attr_req_file_meas_create_from_data(value);
+ case TCG_PTS_FILE_MEAS:
+ return tcg_pts_attr_file_meas_create_from_data(value);
+ case TCG_PTS_REQ_FILE_META:
+ return tcg_pts_attr_req_file_meta_create_from_data(value);
+ case TCG_PTS_UNIX_FILE_META:
+ return tcg_pts_attr_unix_file_meta_create_from_data(value);
+ case TCG_PTS_REQ_TEMPL_REF_MANI_SET_META:
+ case TCG_PTS_TEMPL_REF_MANI_SET_META:
+ case TCG_PTS_UPDATE_TEMPL_REF_MANI:
+ case TCG_PTS_VERIFICATION_RESULT:
+ case TCG_PTS_INTEG_REPORT:
+ case TCG_PTS_WIN_FILE_META:
+ case TCG_PTS_REQ_REGISTRY_VALUE:
+ case TCG_PTS_REGISTRY_VALUE:
+ case TCG_PTS_REQ_INTEG_MEAS_LOG:
+ case TCG_PTS_INTEG_MEAS_LOG:
+ default:
+ return NULL;
+ }
+}
diff --git a/src/libpts/tcg/tcg_attr.h b/src/libpts/tcg/tcg_attr.h
new file mode 100644
index 000000000..b45e1488f
--- /dev/null
+++ b/src/libpts/tcg/tcg_attr.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 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 tcg_attrt tcg_attr
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_ATTR_H_
+#define TCG_ATTR_H_
+
+#include <pa_tnc/pa_tnc_attr.h>
+#include <library.h>
+
+typedef enum tcg_attr_t tcg_attr_t;
+
+/**
+ * TCG PTS IF-M Attributes (section 4 of PTS PROTO: Binding to TNC IF-M)
+ */
+enum tcg_attr_t {
+
+ /* PTS Protocol Negotiations */
+ TCG_PTS_REQ_PROTO_CAPS = 0x01000000,
+ TCG_PTS_PROTO_CAPS = 0x02000000,
+ TCG_PTS_DH_NONCE_PARAMS_REQ = 0x03000000,
+ TCG_PTS_DH_NONCE_PARAMS_RESP = 0x04000000,
+ TCG_PTS_DH_NONCE_FINISH = 0x05000000,
+ TCG_PTS_MEAS_ALGO = 0x06000000,
+ TCG_PTS_MEAS_ALGO_SELECTION = 0x07000000,
+ TCG_PTS_GET_TPM_VERSION_INFO = 0x08000000,
+ TCG_PTS_TPM_VERSION_INFO = 0x09000000,
+ TCG_PTS_REQ_TEMPL_REF_MANI_SET_META = 0x0A000000,
+ TCG_PTS_TEMPL_REF_MANI_SET_META = 0x0B000000,
+ TCG_PTS_UPDATE_TEMPL_REF_MANI = 0x0C000000,
+ TCG_PTS_GET_AIK = 0x0D000000,
+ TCG_PTS_AIK = 0x0E000000,
+
+ /* PTS-based Attestation Evidence */
+ TCG_PTS_REQ_FUNC_COMP_EVID = 0x00100000,
+ TCG_PTS_GEN_ATTEST_EVID = 0x00200000,
+ TCG_PTS_SIMPLE_COMP_EVID = 0x00300000,
+ TCG_PTS_SIMPLE_EVID_FINAL = 0x00400000,
+ TCG_PTS_VERIFICATION_RESULT = 0x00500000,
+ TCG_PTS_INTEG_REPORT = 0x00600000,
+ TCG_PTS_REQ_FILE_META = 0x00700000,
+ TCG_PTS_WIN_FILE_META = 0x00800000,
+ TCG_PTS_UNIX_FILE_META = 0x00900000,
+ TCG_PTS_REQ_REGISTRY_VALUE = 0x00A00000,
+ TCG_PTS_REGISTRY_VALUE = 0x00B00000,
+ TCG_PTS_REQ_FILE_MEAS = 0x00C00000,
+ TCG_PTS_FILE_MEAS = 0x00D00000,
+ TCG_PTS_REQ_INTEG_MEAS_LOG = 0x00E00000,
+ TCG_PTS_INTEG_MEAS_LOG = 0x00F00000,
+};
+
+/**
+ * enum name for tcg_attr_t.
+ */
+extern enum_name_t *tcg_attr_names;
+
+/**
+ * Create a TCG PA-TNC attribute from data
+ *
+ * @param type attribute type
+ * @param value attribute value
+ */
+pa_tnc_attr_t* tcg_attr_create_from_data(u_int32_t type, chunk_t value);
+
+#endif /** TCG_ATTR_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_aik.c b/src/libpts/tcg/tcg_pts_attr_aik.c
new file mode 100644
index 000000000..9be3794b6
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_aik.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_aik.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_aik_t private_tcg_pts_attr_aik_t;
+
+/**
+ * Attestation Identity Key
+ * see section 3.13 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Attestation Identity Key (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Attestation Identity Key (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_AIK_SIZE 4
+#define PTS_AIK_FLAGS_NONE 0
+#define PTS_AIK_FLAGS_NAKED_KEY (1<<7)
+/**
+ * Private data of an tcg_pts_attr_aik_t object.
+ */
+struct private_tcg_pts_attr_aik_t {
+
+ /**
+ * Public members of tcg_pts_attr_aik_t
+ */
+ tcg_pts_attr_aik_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * AIK Certificate or Public Key
+ */
+ certificate_t *aik;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_aik_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_aik_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_aik_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_aik_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_aik_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_aik_t *this)
+{
+ bio_writer_t *writer;
+ u_int8_t flags = PTS_AIK_FLAGS_NONE;
+ cred_encoding_type_t encoding_type = CERT_ASN1_DER;
+ chunk_t aik_blob;
+
+ if (this->aik->get_type(this->aik) == CERT_TRUSTED_PUBKEY)
+ {
+ flags |= PTS_AIK_FLAGS_NAKED_KEY;
+ encoding_type = PUBKEY_SPKI_ASN1_DER;
+ }
+ if (!this->aik->get_encoding(this->aik, encoding_type, &aik_blob))
+ {
+ DBG1(DBG_TNC, "encoding of Attestation Identity Key failed");
+ aik_blob = chunk_empty;
+ }
+ writer = bio_writer_create(PTS_AIK_SIZE);
+ writer->write_uint8(writer, flags);
+ writer->write_data (writer, aik_blob);
+ this->value = chunk_clone(writer->get_buf(writer));
+ free(aik_blob.ptr);
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_aik_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t flags;
+ certificate_type_t type;
+ chunk_t aik_blob;
+
+ if (this->value.len < PTS_AIK_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Attestation Identity Key");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint8(reader, &flags);
+ reader->read_data (reader, reader->remaining(reader), &aik_blob);
+
+ type = (flags & PTS_AIK_FLAGS_NAKED_KEY) ? CERT_TRUSTED_PUBKEY : CERT_X509;
+
+ this->aik = lib->creds->create(lib->creds, CRED_CERTIFICATE, type,
+ BUILD_BLOB_PEM, aik_blob, BUILD_END);
+ reader->destroy(reader);
+
+ if (!this->aik)
+ {
+ DBG1(DBG_TNC, "parsing of Attestation Identity Key failed");
+ *offset = 0;
+ return FAILED;
+ }
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_aik_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_aik_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF(this->aik);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_aik_t, get_aik, certificate_t*,
+ private_tcg_pts_attr_aik_t *this)
+{
+ return this->aik;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_aik_create(certificate_t *aik)
+{
+ private_tcg_pts_attr_aik_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_aik = _get_aik,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_AIK,
+ .aik = aik->get_ref(aik),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_aik_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_aik_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_aik = _get_aik,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_AIK,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_aik.h b/src/libpts/tcg/tcg_pts_attr_aik.h
new file mode 100644
index 000000000..96e90582b
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_aik.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_aik tcg_pts_attr_aik
+ * @{ @ingroup tcg_pts_attr_aik
+ */
+
+#ifndef TCG_PTS_ATTR_AIK_H_
+#define TCG_PTS_ATTR_AIK_H_
+
+typedef struct tcg_pts_attr_aik_t tcg_pts_attr_aik_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+#include <credentials/certificates/certificate.h>
+
+/**
+ * Class implementing the TCG PTS Attestation Identity Key attribute
+ *
+ */
+struct tcg_pts_attr_aik_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get AIK
+ *
+ * @return AIK Certificate or Public Key
+ */
+ certificate_t* (*get_aik)(tcg_pts_attr_aik_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_aik_t object
+ *
+ * @param aik Attestation Identity Key
+ */
+pa_tnc_attr_t* tcg_pts_attr_aik_create(certificate_t *aik);
+
+/**
+ * Creates an tcg_pts_attr_aik_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_aik_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_AIK_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c b/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c
new file mode 100644
index 000000000..dce98e87d
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_dh_nonce_finish.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_dh_nonce_finish_t
+ private_tcg_pts_attr_dh_nonce_finish_t;
+
+/**
+ * PTS DH Nonce Finish
+ * see section 3.8.3 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | Nonce Len | Selected Hash Algorithm |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | D-H Initiator Public Value ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | D-H Initiator Nonce ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_DH_NONCE_FINISH_SIZE 12
+#define PTS_DH_NONCE_FINISH_RESERVED 0x00
+
+/**
+ * Private data of an tcg_pts_attr_dh_nonce_finish_t object.
+ */
+struct private_tcg_pts_attr_dh_nonce_finish_t {
+
+ /**
+ * Public members of tcg_pts_attr_dh_nonce_finish_t
+ */
+ tcg_pts_attr_dh_nonce_finish_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Selected Hashing Algorithm
+ */
+ pts_meas_algorithms_t hash_algo;
+
+ /**
+ * DH Initiator Public Value
+ */
+ chunk_t initiator_value;
+
+ /**
+ * DH Initiator Nonce
+ */
+ chunk_t initiator_nonce;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_dh_nonce_finish_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ bio_writer_t *writer;
+
+ writer = bio_writer_create(PTS_DH_NONCE_FINISH_SIZE);
+ writer->write_uint8 (writer, PTS_DH_NONCE_FINISH_RESERVED);
+ writer->write_uint8 (writer, this->initiator_nonce.len);
+ writer->write_uint16(writer, this->hash_algo);
+ writer->write_data (writer, this->initiator_value);
+ writer->write_data (writer, this->initiator_nonce);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t reserved, nonce_len;
+ u_int16_t hash_algo;
+
+ if (this->value.len < PTS_DH_NONCE_FINISH_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS DH Nonce Finish");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &reserved);
+ reader->read_uint8 (reader, &nonce_len);
+ reader->read_uint16(reader, &hash_algo);
+ reader->read_data(reader, reader->remaining(reader) - nonce_len,
+ &this->initiator_value);
+ reader->read_data(reader, nonce_len, &this->initiator_nonce);
+ this->hash_algo = hash_algo;
+ this->initiator_value = chunk_clone(this->initiator_value);
+ this->initiator_nonce = chunk_clone(this->initiator_nonce);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this->initiator_value.ptr);
+ free(this->initiator_nonce.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_dh_nonce_finish_t, get_hash_algo, pts_meas_algorithms_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->hash_algo;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_finish_t, get_initiator_value, chunk_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->initiator_value;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_finish_t, get_initiator_nonce, chunk_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->initiator_nonce;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create(
+ pts_meas_algorithms_t hash_algo,
+ chunk_t initiator_value,
+ chunk_t initiator_nonce)
+{
+ private_tcg_pts_attr_dh_nonce_finish_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_hash_algo = _get_hash_algo,
+ .get_initiator_nonce = _get_initiator_nonce,
+ .get_initiator_value = _get_initiator_value,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_DH_NONCE_FINISH,
+ .hash_algo = hash_algo,
+ .initiator_value = initiator_value,
+ .initiator_nonce = chunk_clone(initiator_nonce),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create_from_data(chunk_t value)
+{
+ private_tcg_pts_attr_dh_nonce_finish_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_hash_algo = _get_hash_algo,
+ .get_initiator_nonce = _get_initiator_nonce,
+ .get_initiator_value = _get_initiator_value,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_DH_NONCE_FINISH,
+ .value = chunk_clone(value),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.h b/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.h
new file mode 100644
index 000000000..7148065c5
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_dh_nonce_finish tcg_pts_attr_dh_nonce_finish
+ * @{ @ingroup tcg_pts_attr_dh_nonce_finish
+ */
+
+#ifndef TCG_PTS_ATTR_DH_NONCE_FINISH_H_
+#define TCG_PTS_ATTR_DH_NONCE_FINISH_H_
+
+typedef struct tcg_pts_attr_dh_nonce_finish_t tcg_pts_attr_dh_nonce_finish_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts_meas_algo.h"
+
+/**
+ * Class implementing the TCG PTS DH Nonce Finish Attribute
+ */
+struct tcg_pts_attr_dh_nonce_finish_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get nonce length
+ *
+ * @return Length of nonce
+ */
+ u_int8_t (*get_nonce_len)(tcg_pts_attr_dh_nonce_finish_t *this);
+
+ /**
+ * Get selected hash algorithm
+ *
+ * @return Selected hash algorithm
+ */
+ pts_meas_algorithms_t (*get_hash_algo)(tcg_pts_attr_dh_nonce_finish_t *this);
+
+ /**
+ * Get DH Initiator Public Value
+ *
+ * @return DH Initiator Public Value
+ */
+ chunk_t (*get_initiator_value)(tcg_pts_attr_dh_nonce_finish_t *this);
+
+ /**
+ * Get DH Initiator Nonce
+ *
+ * @return DH Initiator Nonce
+ */
+ chunk_t (*get_initiator_nonce)(tcg_pts_attr_dh_nonce_finish_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_finish_t object
+ *
+ * @param hash_algo Selected hash algorithm
+ * @param initiator_value DH Initiator Public Value
+ * @param initiator_nonce DH Initiator Nonce
+ */
+pa_tnc_attr_t* tcg_pts_attr_dh_nonce_finish_create(
+ pts_meas_algorithms_t hash_algo,
+ chunk_t initiator_value,
+ chunk_t initiator_nonce);
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_finish_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_dh_nonce_finish_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_DH_NONCE_FINISH_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c
new file mode 100644
index 000000000..36266fe12
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_dh_nonce_params_req.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_dh_nonce_params_req_t
+ private_tcg_pts_attr_dh_nonce_params_req_t;
+
+/**
+ * PTS DH Nonce Parameters Request
+ * see section 3.8.1 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | Min. Nonce Len | D-H Group Set |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_DH_NONCE_PARAMS_REQ_SIZE 4
+#define PTS_DH_NONCE_PARAMS_REQ_RESERVED 0x00
+
+/**
+ * Private data of an tcg_pts_attr_dh_nonce_params_req_t object.
+ */
+struct private_tcg_pts_attr_dh_nonce_params_req_t {
+
+ /**
+ * Public members of tcg_pts_attr_dh_nonce_params_req_t
+ */
+ tcg_pts_attr_dh_nonce_params_req_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Minimum acceptable length of nonce
+ */
+ u_int8_t min_nonce_len;
+
+ /**
+ * Diffie Hellman group set
+ */
+ pts_dh_group_t dh_groups;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ bio_writer_t *writer;
+
+ writer = bio_writer_create(PTS_DH_NONCE_PARAMS_REQ_SIZE);
+ writer->write_uint8 (writer, PTS_DH_NONCE_PARAMS_REQ_RESERVED);
+ writer->write_uint8 (writer, this->min_nonce_len);
+ writer->write_uint16(writer, this->dh_groups);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t reserved;
+ u_int16_t dh_groups;
+
+ if (this->value.len < PTS_DH_NONCE_PARAMS_REQ_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS DH Nonce Parameters Request");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint8(reader, &reserved);
+ reader->read_uint8(reader, &this->min_nonce_len);
+ reader->read_uint16(reader, &dh_groups);
+ this->dh_groups = dh_groups;
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_req_t, get_min_nonce_len, u_int8_t,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ return this->min_nonce_len;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_req_t, get_dh_groups, pts_dh_group_t,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ return this->dh_groups;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create(u_int8_t min_nonce_len,
+ pts_dh_group_t dh_groups)
+{
+ private_tcg_pts_attr_dh_nonce_params_req_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_min_nonce_len = _get_min_nonce_len,
+ .get_dh_groups = _get_dh_groups,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_DH_NONCE_PARAMS_REQ,
+ .min_nonce_len = min_nonce_len,
+ .dh_groups = dh_groups,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create_from_data(chunk_t value)
+{
+ private_tcg_pts_attr_dh_nonce_params_req_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_min_nonce_len = _get_min_nonce_len,
+ .get_dh_groups = _get_dh_groups,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_DH_NONCE_PARAMS_REQ,
+ .value = chunk_clone(value),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.h b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.h
new file mode 100644
index 000000000..170077156
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_dh_nonce_params_req tcg_pts_attr_dh_nonce_params_req
+ * @{ @ingroup tcg_pts_attr_dh_nonce_params_req
+ */
+
+#ifndef TCG_PTS_ATTR_DH_NONCE_PARAMS_REQ_H_
+#define TCG_PTS_ATTR_DH_NONCE_PARAMS_REQ_H_
+
+typedef struct tcg_pts_attr_dh_nonce_params_req_t
+ tcg_pts_attr_dh_nonce_params_req_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts_dh_group.h"
+
+/**
+ * Class implementing the TCG PTS DH Nonce Parameters Request Attribute
+ */
+struct tcg_pts_attr_dh_nonce_params_req_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get Minimum nonce length
+ *
+ * @return Minimum acceptable length of nonce
+ */
+ u_int8_t (*get_min_nonce_len)(tcg_pts_attr_dh_nonce_params_req_t *this);
+
+ /**
+ * Get supported Diffie Hellman Groups
+ *
+ * @return Supported Diffie Hellman Groups
+ */
+ pts_dh_group_t (*get_dh_groups)(tcg_pts_attr_dh_nonce_params_req_t *this);
+};
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_params_req_t object
+ *
+ * @param min_nonce_len Minimum acceptable length of nonce
+ * @param dh_groups Initiator's supported DH groups
+ */
+pa_tnc_attr_t* tcg_pts_attr_dh_nonce_params_req_create(u_int8_t min_nonce_len,
+ pts_dh_group_t dh_groups);
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_params_req_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_dh_nonce_params_req_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_DH_NONCE_PARAMS_REQ_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c
new file mode 100644
index 000000000..09bfa3aac
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_dh_nonce_params_resp.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_dh_nonce_params_resp_t
+ private_tcg_pts_attr_dh_nonce_params_resp_t;
+
+/**
+ * PTS DH Nonce Parameters Response
+ * see section 3.8.2 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | Nonce Len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Selected D-H Group | Hash Algorithm Set |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | D-H Responder Nonce ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | D-H Responder Public Value ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_DH_NONCE_PARAMS_RESP_SIZE 16
+#define PTS_DH_NONCE_PARAMS_RESP_RESERVED 0x0000
+
+/**
+ * Private data of an tcg_pts_attr_dh_nonce_params_resp_t object.
+ */
+struct private_tcg_pts_attr_dh_nonce_params_resp_t {
+
+ /**
+ * Public members of tcg_pts_attr_dh_nonce_params_resp_t
+ */
+ tcg_pts_attr_dh_nonce_params_resp_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Selected Diffie Hellman group
+ */
+ pts_dh_group_t dh_group;
+
+ /**
+ * Supported Hashing Algorithms
+ */
+ pts_meas_algorithms_t hash_algo_set;
+
+ /**
+ * DH Responder Nonce
+ */
+ chunk_t responder_nonce;
+
+ /**
+ * DH Responder Public Value
+ */
+ chunk_t responder_value;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ bio_writer_t *writer;
+
+ writer = bio_writer_create(PTS_DH_NONCE_PARAMS_RESP_SIZE);
+ writer->write_uint24(writer, PTS_DH_NONCE_PARAMS_RESP_RESERVED);
+ writer->write_uint8 (writer, this->responder_nonce.len);
+ writer->write_uint16(writer, this->dh_group);
+ writer->write_uint16(writer, this->hash_algo_set);
+ writer->write_data (writer, this->responder_nonce);
+ writer->write_data (writer, this->responder_value);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int32_t reserved;
+ u_int8_t nonce_len;
+ u_int16_t dh_group, hash_algo_set;
+
+ if (this->value.len < PTS_DH_NONCE_PARAMS_RESP_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS DH Nonce Parameters Response");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint24(reader, &reserved);
+ reader->read_uint8 (reader, &nonce_len);
+ reader->read_uint16(reader, &dh_group);
+ reader->read_uint16(reader, &hash_algo_set);
+ reader->read_data(reader, nonce_len, &this->responder_nonce);
+ reader->read_data(reader, reader->remaining(reader), &this->responder_value);
+ this->dh_group = dh_group;
+ this->hash_algo_set = hash_algo_set;
+ this->responder_nonce = chunk_clone(this->responder_nonce);
+ this->responder_value = chunk_clone(this->responder_value);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this->responder_nonce.ptr);
+ free(this->responder_value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_dh_group, pts_dh_group_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->dh_group;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_hash_algo_set,
+ pts_meas_algorithms_t, private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->hash_algo_set;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_responder_nonce, chunk_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->responder_nonce;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_responder_value, chunk_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->responder_value;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create(pts_dh_group_t dh_group,
+ pts_meas_algorithms_t hash_algo_set,
+ chunk_t responder_nonce,
+ chunk_t responder_value)
+{
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_dh_group = _get_dh_group,
+ .get_hash_algo_set = _get_hash_algo_set,
+ .get_responder_nonce = _get_responder_nonce,
+ .get_responder_value = _get_responder_value,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_DH_NONCE_PARAMS_RESP,
+ .dh_group = dh_group,
+ .hash_algo_set = hash_algo_set,
+ .responder_nonce = chunk_clone(responder_nonce),
+ .responder_value = responder_value,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create_from_data(chunk_t value)
+{
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_dh_group = _get_dh_group,
+ .get_hash_algo_set = _get_hash_algo_set,
+ .get_responder_nonce = _get_responder_nonce,
+ .get_responder_value = _get_responder_value,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_DH_NONCE_PARAMS_RESP,
+ .value = chunk_clone(value),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.h b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.h
new file mode 100644
index 000000000..d2141f8b9
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_dh_nonce_params_resp tcg_pts_attr_dh_nonce_params_resp
+ * @{ @ingroup tcg_pts_attr_dh_nonce_params_resp
+ */
+
+#ifndef TCG_PTS_ATTR_DH_NONCE_PARAMS_RESP_H_
+#define TCG_PTS_ATTR_DH_NONCE_PARAMS_RESP_H_
+
+typedef struct tcg_pts_attr_dh_nonce_params_resp_t
+ tcg_pts_attr_dh_nonce_params_resp_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts_dh_group.h"
+#include "pts/pts_meas_algo.h"
+
+/**
+ * Class implementing the TCG PTS DH Nonce Parameters Response Attribute
+ */
+struct tcg_pts_attr_dh_nonce_params_resp_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get selected Diffie Hellman Group
+ *
+ * @return Selected Diffie Hellman Group
+ */
+ pts_dh_group_t (*get_dh_group)(tcg_pts_attr_dh_nonce_params_resp_t *this);
+
+ /**
+ * Get supported hash algorithms
+ *
+ * @return Hash algorithm set
+ */
+ pts_meas_algorithms_t (*get_hash_algo_set)(
+ tcg_pts_attr_dh_nonce_params_resp_t *this);
+
+ /**
+ * Get DH Responder Nonce
+ *
+ * @return DH Responder Nonce
+ */
+ chunk_t (*get_responder_nonce)(tcg_pts_attr_dh_nonce_params_resp_t *this);
+
+ /**
+ * Get DH Responder Public Value
+ *
+ * @return DH Responder Public Value
+ */
+ chunk_t (*get_responder_value)(tcg_pts_attr_dh_nonce_params_resp_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_params_resp_t object
+ *
+ * @param dh_group Selected DH group
+ * @param hash_algo_set Set of supported hash algorithms
+ * @param responder_nonce DH Responder Nonce
+ * @param responder_pub_val DH Responder Public value
+ */
+pa_tnc_attr_t* tcg_pts_attr_dh_nonce_params_resp_create(pts_dh_group_t dh_group,
+ pts_meas_algorithms_t hash_algo_set,
+ chunk_t responder_nonce,
+ chunk_t responder_value);
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_params_resp_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_dh_nonce_params_resp_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_DH_NONCE_PARAMS_RESP_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_file_meas.c b/src/libpts/tcg/tcg_pts_attr_file_meas.c
new file mode 100644
index 000000000..737da65c1
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_file_meas.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_file_meas.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_file_meas_t private_tcg_pts_attr_file_meas_t;
+
+/**
+ * File Measurement
+ * see section 3.19.2 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of Files included |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of Files included |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Request ID | Measurement Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement #1 (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Filename Length | Filename (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Filename (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement #2 (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Filename Length | Filename (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Filename (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ...........................
+ */
+
+#define PTS_FILE_MEAS_SIZE 12
+
+/**
+ * Private data of an tcg_pts_attr_file_meas_t object.
+ */
+struct private_tcg_pts_attr_file_meas_t {
+
+ /**
+ * Public members of tcg_pts_attr_file_meas_t
+ */
+ tcg_pts_attr_file_meas_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * PTS File Measurements
+ */
+ pts_file_meas_t *measurements;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_file_meas_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ bio_writer_t *writer;
+ enumerator_t *enumerator;
+ u_int64_t number_of_files;
+ u_int16_t request_id;
+ char *filename;
+ chunk_t measurement;
+ bool first = TRUE;
+
+ number_of_files = this->measurements->get_file_count(this->measurements);
+ request_id = this->measurements->get_request_id(this->measurements);
+
+ writer = bio_writer_create(PTS_FILE_MEAS_SIZE);
+ writer->write_uint64(writer, number_of_files);
+ writer->write_uint16(writer, request_id);
+
+ enumerator = this->measurements->create_enumerator(this->measurements);
+ while (enumerator->enumerate(enumerator, &filename, &measurement))
+ {
+ if (first)
+ {
+ writer->write_uint16(writer, measurement.len);
+ first = FALSE;
+ }
+ writer->write_data (writer, measurement);
+ writer->write_uint16(writer, strlen(filename));
+ writer->write_data (writer, chunk_create(filename, strlen(filename)));
+ }
+ enumerator->destroy(enumerator);
+
+ if (first)
+ {
+ /* no attached measurements */
+ writer->write_uint16(writer, 0);
+ }
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_file_meas_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int64_t number_of_files;
+ u_int16_t request_id, meas_len, filename_len;
+ size_t len;
+ chunk_t measurement, filename;
+ char buf[BUF_LEN];
+ status_t status = FAILED;
+
+ if (this->value.len < PTS_FILE_MEAS_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS file measurement header");
+ *offset = 0;
+ return FAILED;
+ }
+
+ reader = bio_reader_create(this->value);
+ reader->read_uint64(reader, &number_of_files);
+ reader->read_uint16(reader, &request_id);
+ reader->read_uint16(reader, &meas_len);
+
+ this->measurements = pts_file_meas_create(request_id);
+
+ while (number_of_files--)
+ {
+ if (!reader->read_data(reader, meas_len, &measurement))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS file measurement");
+ goto end;
+ }
+ if (!reader->read_uint16(reader, &filename_len))
+ {
+ DBG1(DBG_TNC, "insufficient data for filename length");
+ goto end;
+ }
+ if (!reader->read_data(reader, filename_len, &filename))
+ {
+ DBG1(DBG_TNC, "insufficient data for filename");
+ goto end;
+ }
+
+ len = min(filename.len, BUF_LEN-1);
+ memcpy(buf, filename.ptr, len);
+ buf[len] = '\0';
+ this->measurements->add(this->measurements, buf, measurement);
+ }
+ status = SUCCESS;
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->measurements->destroy(this->measurements);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_file_meas_t, get_measurements, pts_file_meas_t*,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ return this->measurements;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_file_meas_create(pts_file_meas_t *measurements)
+{
+ private_tcg_pts_attr_file_meas_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_measurements = _get_measurements,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_FILE_MEAS,
+ .measurements = measurements,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_file_meas_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_file_meas_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_measurements = _get_measurements,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_FILE_MEAS,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_file_meas.h b/src/libpts/tcg/tcg_pts_attr_file_meas.h
new file mode 100644
index 000000000..c432ba9a9
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_file_meas.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_file_meas tcg_pts_attr_file_meas
+ * @{ @ingroup tcg_pts_attr_file_meas
+ */
+
+#ifndef TCG_PTS_ATTR_FILE_MEAS_H_
+#define TCG_PTS_ATTR_FILE_MEAS_H_
+
+typedef struct tcg_pts_attr_file_meas_t tcg_pts_attr_file_meas_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts.h"
+#include "pts/pts_file_meas.h"
+
+/**
+ * Class implementing the TCG PTS File Measurement attribute
+ *
+ */
+struct tcg_pts_attr_file_meas_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get PTS File Measurements
+ *
+ * @return PTS File Measurements
+ */
+ pts_file_meas_t* (*get_measurements)(tcg_pts_attr_file_meas_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_file_meas_t object
+ *
+ * @param measurements PTS File Measurements
+ */
+pa_tnc_attr_t* tcg_pts_attr_file_meas_create(pts_file_meas_t *measurements);
+
+/**
+ * Creates an tcg_pts_attr_file_meas_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_file_meas_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_FILE_MEAS_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c b/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c
new file mode 100644
index 000000000..054285c4e
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_gen_attest_evid.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_gen_attest_evid_t
+ private_tcg_pts_attr_gen_attest_evid_t;
+
+/**
+ * Generate Attestation Evidence
+ * see section 3.14.2 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_GEN_ATTEST_EVID_SIZE 4
+#define PTS_GEN_ATTEST_EVID_RESERVED 0x00
+
+/**
+ * Private data of an tcg_pts_attr_gen_attest_evid_t object.
+ */
+struct private_tcg_pts_attr_gen_attest_evid_t {
+
+ /**
+ * Public members of tcg_pts_attr_gen_attest_evid_t
+ */
+ tcg_pts_attr_gen_attest_evid_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_gen_attest_evid_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ bio_writer_t *writer;
+
+ writer = bio_writer_create(PTS_GEN_ATTEST_EVID_SIZE);
+ writer->write_uint32 (writer, PTS_GEN_ATTEST_EVID_RESERVED);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_gen_attest_evid_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int32_t reserved;
+
+ if (this->value.len < PTS_GEN_ATTEST_EVID_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Generate Attestation Evidence");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint32 (reader, &reserved);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create()
+{
+ private_tcg_pts_attr_gen_attest_evid_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_GEN_ATTEST_EVID,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_gen_attest_evid_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_GEN_ATTEST_EVID,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.h b/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.h
new file mode 100644
index 000000000..0a65f2143
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_gen_attest_evid tcg_pts_attr_gen_attest_evid
+ * @{ @ingroup tcg_pts_attr_gen_attest_evid
+ */
+
+#ifndef TCG_PTS_ATTR_GEN_ATTEST_EVID_H_
+#define TCG_PTS_ATTR_GEN_ATTEST_EVID_H_
+
+typedef struct tcg_pts_attr_gen_attest_evid_t tcg_pts_attr_gen_attest_evid_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Generate Attestation Evidence Attribute
+ *
+ */
+struct tcg_pts_attr_gen_attest_evid_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+};
+
+/**
+ * Creates an tcg_pts_attr_gen_attest_evid_t object
+ */
+pa_tnc_attr_t* tcg_pts_attr_gen_attest_evid_create();
+
+/**
+ * Creates an tcg_pts_attr_gen_attest_evid_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_gen_attest_evid_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_GEN_ATTEST_EVID_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_get_aik.c b/src/libpts/tcg/tcg_pts_attr_get_aik.c
new file mode 100644
index 000000000..1875375a4
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_get_aik.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_get_aik.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_get_aik_t private_tcg_pts_attr_get_aik_t;
+
+/**
+ * Get Attestation Identity Key
+ * see section 3.12 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_GET_AIK_SIZE 4
+#define PTS_GET_AIK_RESERVED 0x00000000
+
+/**
+ * Private data of an tcg_pts_attr_get_aik_t object.
+ */
+struct private_tcg_pts_attr_get_aik_t {
+
+ /**
+ * Public members of tcg_pts_attr_get_aik_t
+ */
+ tcg_pts_attr_get_aik_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_get_aik_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ bio_writer_t *writer;
+
+ writer = bio_writer_create(PTS_GET_AIK_SIZE);
+ writer->write_uint32 (writer, PTS_GET_AIK_RESERVED);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_get_aik_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int32_t reserved;
+
+ if (this->value.len < PTS_GET_AIK_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Get AIK");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint32 (reader, &reserved);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_get_aik_create()
+{
+ private_tcg_pts_attr_get_aik_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_GET_AIK,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_get_aik_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_get_aik_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_GET_AIK,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_get_aik.h b/src/libpts/tcg/tcg_pts_attr_get_aik.h
new file mode 100644
index 000000000..e5c74b4dc
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_get_aik.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_get_aik tcg_pts_attr_get_aik
+ * @{ @ingroup tcg_pts_attr_get_aik
+ */
+
+#ifndef TCG_PTS_ATTR_GET_AIK_H_
+#define TCG_PTS_ATTR_GET_AIK_H_
+
+typedef struct tcg_pts_attr_get_aik_t tcg_pts_attr_get_aik_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Get Attestation Identity Key Attribute
+ *
+ */
+struct tcg_pts_attr_get_aik_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+};
+
+/**
+ * Creates an tcg_pts_attr_get_aik_t object
+ */
+pa_tnc_attr_t* tcg_pts_attr_get_aik_create();
+
+/**
+ * Creates an tcg_pts_attr_get_aik_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_get_aik_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_GET_AIK_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c b/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c
new file mode 100644
index 000000000..cb6834ca5
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_get_tpm_version_info.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_get_tpm_version_info_t
+ private_tcg_pts_attr_get_tpm_version_info_t;
+
+/**
+ * Get TPM Version Information
+ * see section 3.10 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_GET_TPM_VER_INFO_SIZE 4
+#define PTS_GET_TPM_VER_INFO_RESERVED 0x00
+
+/**
+ * Private data of an tcg_pts_attr_get_tpm_version_info_t object.
+ */
+struct private_tcg_pts_attr_get_tpm_version_info_t {
+
+ /**
+ * Public members of tcg_pts_attr_get_tpm_version_info_t
+ */
+ tcg_pts_attr_get_tpm_version_info_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_get_tpm_version_info_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ bio_writer_t *writer;
+
+ writer = bio_writer_create(PTS_GET_TPM_VER_INFO_SIZE);
+ writer->write_uint32 (writer, PTS_GET_TPM_VER_INFO_RESERVED);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_get_tpm_version_info_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int32_t reserved;
+
+ if (this->value.len < PTS_GET_TPM_VER_INFO_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Get TPM Version Information");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint32 (reader, &reserved);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create()
+{
+ private_tcg_pts_attr_get_tpm_version_info_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_GET_TPM_VERSION_INFO,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_get_tpm_version_info_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_GET_TPM_VERSION_INFO,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.h b/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.h
new file mode 100644
index 000000000..1b693402a
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_get_tpm_version_info tcg_pts_attr_get_tpm_version_info
+ * @{ @ingroup tcg_pts_attr_get_tpm_version_info
+ */
+
+#ifndef TCG_PTS_ATTR_GET_TPM_VERSION_INFO_H_
+#define TCG_PTS_ATTR_GET_TPM_VERSION_INFO_H_
+
+typedef struct tcg_pts_attr_get_tpm_version_info_t
+ tcg_pts_attr_get_tpm_version_info_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Get TPM Version Info Attribute
+ *
+ */
+struct tcg_pts_attr_get_tpm_version_info_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+};
+
+/**
+ * Creates an tcg_pts_attr_get_tpm_version_info_t object
+ */
+pa_tnc_attr_t* tcg_pts_attr_get_tpm_version_info_create();
+
+/**
+ * Creates an tcg_pts_attr_get_tpm_version_info_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_get_tpm_version_info_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_GET_TPM_VERSION_INFO_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_meas_algo.c b/src/libpts/tcg/tcg_pts_attr_meas_algo.c
new file mode 100644
index 000000000..ed520e3cd
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_meas_algo.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_meas_algo.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_meas_algo_t private_tcg_pts_attr_meas_algo_t;
+
+/**
+ * PTS Measurement Algorithm
+ * see section 3.9.1 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | Hash Algorithm Set |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_MEAS_ALGO_SIZE 4
+#define PTS_MEAS_ALGO_RESERVED 0x0000
+
+/**
+ * Private data of an tcg_pts_attr_meas_algo_t object.
+ */
+struct private_tcg_pts_attr_meas_algo_t {
+
+ /**
+ * Public members of tcg_pts_attr_meas_algo_t
+ */
+ tcg_pts_attr_meas_algo_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Set of algorithms
+ */
+ pts_meas_algorithms_t algorithms;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_meas_algo_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ bio_writer_t *writer;
+
+ writer = bio_writer_create(PTS_MEAS_ALGO_SIZE);
+ writer->write_uint16(writer, PTS_MEAS_ALGO_RESERVED);
+ writer->write_uint16(writer, this->algorithms);
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_meas_algo_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int16_t reserved, algorithms;
+
+ if (this->value.len < PTS_MEAS_ALGO_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Measurement Algorithm");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint16(reader, &reserved);
+ reader->read_uint16(reader, &algorithms);
+ this->algorithms = algorithms;
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(tcg_pts_attr_meas_algo_t, get_algorithms, pts_meas_algorithms_t,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ return this->algorithms;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_meas_algo_create(pts_meas_algorithms_t algorithms,
+ bool selection)
+{
+ private_tcg_pts_attr_meas_algo_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_algorithms = _get_algorithms,
+ },
+ .vendor_id = PEN_TCG,
+ .type = selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO,
+ .algorithms = algorithms,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_meas_algo_create_from_data(chunk_t data,
+ bool selection)
+{
+ private_tcg_pts_attr_meas_algo_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_algorithms = _get_algorithms,
+ },
+ .vendor_id = PEN_TCG,
+ .type = selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_meas_algo.h b/src/libpts/tcg/tcg_pts_attr_meas_algo.h
new file mode 100644
index 000000000..885e2c16b
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_meas_algo.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_meas_algo tcg_pts_attr_meas_algo
+ * @{ @ingroup tcg_pts_attr_meas_algo
+ */
+
+#ifndef TCG_PTS_ATTR_MEAS_ALGO_H_
+#define TCG_PTS_ATTR_MEAS_ALGO_H_
+
+typedef struct tcg_pts_attr_meas_algo_t tcg_pts_attr_meas_algo_t;
+
+#include "tcg_attr.h"
+#include "pts/pts_meas_algo.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG Measurement Algorithm Attribute
+ *
+ */
+struct tcg_pts_attr_meas_algo_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get PTS Measurement Algorithm Set
+ *
+ * @return set of algorithms
+ */
+ pts_meas_algorithms_t (*get_algorithms)(tcg_pts_attr_meas_algo_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_meas_algo_t object
+ *
+ * @param algorithms set of algorithms
+ * @param selection TRUE if a selection
+ */
+pa_tnc_attr_t* tcg_pts_attr_meas_algo_create(pts_meas_algorithms_t algorithms,
+ bool selection);
+
+/**
+ * Creates an tcg_pts_attr_meas_algo_t object from received data
+ *
+ * @param value unparsed attribute value
+ * @param selection TRUE if a selection
+ */
+pa_tnc_attr_t* tcg_pts_attr_meas_algo_create_from_data(chunk_t value,
+ bool selection);
+
+#endif /** TCG_PTS_ATTR_MEAS_ALGO_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_proto_caps.c b/src/libpts/tcg/tcg_pts_attr_proto_caps.c
new file mode 100644
index 000000000..055c750ff
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_proto_caps.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_proto_caps.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_proto_caps_t private_tcg_pts_attr_proto_caps_t;
+
+/**
+ * PTS Protocol Capabilities
+ * see section 3.7 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved |C|V|D|T|X|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_PROTO_CAPS_SIZE 4
+#define PTS_PROTO_CAPS_RESERVED 0x0000
+
+/**
+ * Private data of an tcg_pts_attr_proto_caps_t object.
+ */
+struct private_tcg_pts_attr_proto_caps_t {
+
+ /**
+ * Public members of tcg_pts_attr_proto_caps_t
+ */
+ tcg_pts_attr_proto_caps_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Set of flags
+ */
+ pts_proto_caps_flag_t flags;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_proto_caps_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ bio_writer_t *writer;
+
+ writer = bio_writer_create(PTS_PROTO_CAPS_SIZE);
+ writer->write_uint16(writer, PTS_PROTO_CAPS_RESERVED);
+ writer->write_uint16(writer, this->flags);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_proto_caps_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int16_t reserved, flags;
+
+ if (this->value.len < PTS_PROTO_CAPS_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Protocol Capabilities");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint16(reader, &reserved);
+ reader->read_uint16(reader, &flags);
+ this->flags = flags;
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(tcg_pts_attr_proto_caps_t, get_flags, pts_proto_caps_flag_t,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ return this->flags;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_proto_caps_create(pts_proto_caps_flag_t flags,
+ bool request)
+{
+ private_tcg_pts_attr_proto_caps_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_flags = _get_flags,
+ },
+ .vendor_id = PEN_TCG,
+ .type = request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS,
+ .flags = flags,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_proto_caps_create_from_data(chunk_t data,
+ bool request)
+{
+ private_tcg_pts_attr_proto_caps_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_flags = _get_flags,
+ },
+ .vendor_id = PEN_TCG,
+ .type = request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_proto_caps.h b/src/libpts/tcg/tcg_pts_attr_proto_caps.h
new file mode 100644
index 000000000..15cfbc7cb
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_proto_caps.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_proto_caps tcg_pts_attr_proto_caps
+ * @{ @ingroup tcg_pts_attr_proto_caps
+ */
+
+#ifndef TCG_PTS_ATTR_PROTO_CAPS_H_
+#define TCG_PTS_ATTR_PROTO_CAPS_H_
+
+typedef struct tcg_pts_attr_proto_caps_t tcg_pts_attr_proto_caps_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts_proto_caps.h"
+
+/**
+ * Class implementing the TCG PTS Protocol Capabilities Attribute
+ */
+struct tcg_pts_attr_proto_caps_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get PTS procol capabilities flags
+ *
+ * @return set of flags
+ */
+ pts_proto_caps_flag_t (*get_flags)(tcg_pts_attr_proto_caps_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_proto_caps_t object
+ *
+ * @param flags set of flags
+ * @param request TRUE for a PTS protocol capabilities request
+ */
+pa_tnc_attr_t* tcg_pts_attr_proto_caps_create(pts_proto_caps_flag_t flags,
+ bool request);
+
+/**
+ * Creates an tcg_pts_attr_proto_caps_t object from received data
+ *
+ * @param value unparsed attribute value
+ * @param request TRUE for a PTS protocol capabilities request
+ */
+pa_tnc_attr_t* tcg_pts_attr_proto_caps_create_from_data(chunk_t value,
+ bool request);
+
+#endif /** TCG_PTS_ATTR_PROTO_CAPS_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_req_file_meas.c b/src/libpts/tcg/tcg_pts_attr_req_file_meas.c
new file mode 100644
index 000000000..17781f745
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_req_file_meas.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_req_file_meas.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_req_file_meas_t private_tcg_pts_attr_req_file_meas_t;
+
+/**
+ * Request File Measurement
+ * see section 3.19.1 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Reserved | Request ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Delimiter |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Fully Qualified File Pathname (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_REQ_FILE_MEAS_SIZE 8
+#define PTS_REQ_FILE_MEAS_RESERVED 0x00
+#define PTS_REQ_FILE_MEAS_NO_FLAGS 0x00
+
+#define DIRECTORY_CONTENTS_FLAG (1<<7)
+
+/**
+ * Private data of an tcg_pts_attr_req_file_meas_t object.
+ */
+struct private_tcg_pts_attr_req_file_meas_t {
+
+ /**
+ * Public members of tcg_pts_attr_req_file_meas_t
+ */
+ tcg_pts_attr_req_file_meas_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Directory Contents flag
+ */
+ bool directory_flag;
+
+ /**
+ * Request ID
+ */
+ u_int16_t request_id;
+
+ /**
+ * UTF8 Encoding of Delimiter Character
+ */
+ u_int32_t delimiter;
+
+ /**
+ * Fully Qualified File Pathname
+ */
+ char *pathname;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_req_file_meas_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ u_int8_t flags = PTS_REQ_FILE_MEAS_NO_FLAGS;
+ chunk_t pathname;
+ bio_writer_t *writer;
+
+ if (this->directory_flag)
+ {
+ flags |= DIRECTORY_CONTENTS_FLAG;
+ }
+ pathname = chunk_create(this->pathname, strlen(this->pathname));
+
+ writer = bio_writer_create(PTS_REQ_FILE_MEAS_SIZE);
+ writer->write_uint8 (writer, flags);
+ writer->write_uint8 (writer, PTS_REQ_FILE_MEAS_RESERVED);
+ writer->write_uint16(writer, this->request_id);
+ writer->write_uint32(writer, this->delimiter);
+ writer->write_data (writer, pathname);
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_req_file_meas_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t flags;
+ u_int8_t reserved;
+ chunk_t pathname;
+
+ if (this->value.len < PTS_REQ_FILE_MEAS_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Request File Measurement");
+ *offset = 0;
+ return FAILED;
+ }
+
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint8 (reader, &reserved);
+ reader->read_uint16(reader, &this->request_id);
+ reader->read_uint32(reader, &this->delimiter);
+ reader->read_data (reader, reader->remaining(reader), &pathname);
+
+ this->directory_flag = (flags & DIRECTORY_CONTENTS_FLAG) !=
+ PTS_REQ_FILE_MEAS_NO_FLAGS;
+
+ this->pathname = malloc(pathname.len + 1);
+ memcpy(this->pathname, pathname.ptr, pathname.len);
+ this->pathname[pathname.len] = '\0';
+
+ reader->destroy(reader);
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->pathname);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_req_file_meas_t, get_directory_flag, bool,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->directory_flag;
+}
+
+METHOD(tcg_pts_attr_req_file_meas_t, get_request_id, u_int16_t,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->request_id;
+}
+
+METHOD(tcg_pts_attr_req_file_meas_t, get_delimiter, u_int32_t,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->delimiter;
+}
+
+METHOD(tcg_pts_attr_req_file_meas_t, get_pathname, char*,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->pathname;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create(bool directory_flag,
+ u_int16_t request_id,
+ u_int32_t delimiter,
+ char *pathname)
+{
+ private_tcg_pts_attr_req_file_meas_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_directory_flag = _get_directory_flag,
+ .get_request_id = _get_request_id,
+ .get_delimiter = _get_delimiter,
+ .get_pathname = _get_pathname,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_REQ_FILE_MEAS,
+ .directory_flag = directory_flag,
+ .request_id = request_id,
+ .delimiter = delimiter,
+ .pathname = strdup(pathname),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_req_file_meas_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_directory_flag = _get_directory_flag,
+ .get_request_id = _get_request_id,
+ .get_delimiter = _get_delimiter,
+ .get_pathname = _get_pathname,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_REQ_FILE_MEAS,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_req_file_meas.h b/src/libpts/tcg/tcg_pts_attr_req_file_meas.h
new file mode 100644
index 000000000..19d189eff
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_req_file_meas.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_req_file_meas tcg_pts_attr_req_file_meas
+ * @{ @ingroup tcg_pts_attr_req_file_meas
+ */
+
+#ifndef TCG_PTS_ATTR_REQ_FILE_MEAS_H_
+#define TCG_PTS_ATTR_REQ_FILE_MEAS_H_
+
+typedef struct tcg_pts_attr_req_file_meas_t tcg_pts_attr_req_file_meas_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Request File Measurement attribute
+ *
+ */
+struct tcg_pts_attr_req_file_meas_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get flag for PTS Request File Measurement
+ *
+ * @return Directory Contents flag
+ */
+ bool (*get_directory_flag)(tcg_pts_attr_req_file_meas_t *this);
+
+ /**
+ * Get Request ID
+ *
+ * @return Request ID
+ */
+ u_int16_t (*get_request_id)(tcg_pts_attr_req_file_meas_t *this);
+
+
+ /**
+ * Get Delimiter
+ *
+ * @return UTF-8 encoding of a Delimiter Character
+ */
+ u_int32_t (*get_delimiter)(tcg_pts_attr_req_file_meas_t *this);
+
+ /**
+ * Get Fully Qualified File Pathname
+ *
+ * @return Pathname
+ */
+ char* (*get_pathname)(tcg_pts_attr_req_file_meas_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_req_file_meas_t object
+ *
+ * @param directory_flag Directory Contents Flag
+ * @param request_id Request ID
+ * @param delimiter Delimiter Character
+ * @param pathname File Pathname
+ */
+pa_tnc_attr_t* tcg_pts_attr_req_file_meas_create(bool directory_flag,
+ u_int16_t request_id,
+ u_int32_t delimiter,
+ char *pathname);
+
+/**
+ * Creates an tcg_pts_attr_req_file_meas_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_req_file_meas_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_REQ_FILE_MEAS_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_req_file_meta.c b/src/libpts/tcg/tcg_pts_attr_req_file_meta.c
new file mode 100644
index 000000000..bef6b5db6
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_req_file_meta.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_req_file_meta.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_req_file_meta_t private_tcg_pts_attr_req_file_meta_t;
+
+/**
+ * Request File Metadata
+ * see section 3.17.1 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Delimiter | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Fully Qualified File Pathname (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_REQ_FILE_META_SIZE 4
+#define PTS_REQ_FILE_META_RESERVED 0x00
+#define PTS_REQ_FILE_META_NO_FLAGS 0x00
+
+#define DIRECTORY_CONTENTS_FLAG (1<<7)
+
+/**
+ * Private data of an tcg_pts_attr_req_file_meta_t object.
+ */
+struct private_tcg_pts_attr_req_file_meta_t {
+
+ /**
+ * Public members of tcg_pts_attr_req_file_meta_t
+ */
+ tcg_pts_attr_req_file_meta_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Directory Contents flag
+ */
+ bool directory_flag;
+
+ /**
+ * UTF8 Encoding of Delimiter Character
+ */
+ u_int8_t delimiter;
+
+ /**
+ * Fully Qualified File Pathname
+ */
+ char *pathname;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_req_file_meta_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ u_int8_t flags = PTS_REQ_FILE_META_NO_FLAGS;
+ chunk_t pathname;
+ bio_writer_t *writer;
+
+ if (this->directory_flag)
+ {
+ flags |= DIRECTORY_CONTENTS_FLAG;
+ }
+ pathname = chunk_create(this->pathname, strlen(this->pathname));
+
+ writer = bio_writer_create(PTS_REQ_FILE_META_SIZE);
+ writer->write_uint8 (writer, flags);
+ writer->write_uint8 (writer, this->delimiter);
+ writer->write_uint16(writer, PTS_REQ_FILE_META_RESERVED);
+
+ writer->write_data (writer, pathname);
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_req_file_meta_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t flags;
+ u_int16_t reserved;
+ chunk_t pathname;
+
+ if (this->value.len < PTS_REQ_FILE_META_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Request File Metadata");
+ *offset = 0;
+ return FAILED;
+ }
+
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint8 (reader, &this->delimiter);
+ reader->read_uint16(reader, &reserved);
+
+ reader->read_data (reader, reader->remaining(reader), &pathname);
+
+ this->directory_flag = (flags & DIRECTORY_CONTENTS_FLAG) !=
+ PTS_REQ_FILE_META_NO_FLAGS;
+
+ this->pathname = malloc(pathname.len + 1);
+ memcpy(this->pathname, pathname.ptr, pathname.len);
+ this->pathname[pathname.len] = '\0';
+
+ reader->destroy(reader);
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->pathname);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(tcg_pts_attr_req_file_meta_t, get_directory_flag, bool,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->directory_flag;
+}
+
+METHOD(tcg_pts_attr_req_file_meta_t, get_delimiter, u_int8_t,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->delimiter;
+}
+
+METHOD(tcg_pts_attr_req_file_meta_t, get_pathname, char*,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->pathname;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create(bool directory_flag,
+ u_int8_t delimiter,
+ char *pathname)
+{
+ private_tcg_pts_attr_req_file_meta_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_directory_flag = _get_directory_flag,
+ .get_delimiter = _get_delimiter,
+ .get_pathname = _get_pathname,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_REQ_FILE_META,
+ .directory_flag = directory_flag,
+ .delimiter = delimiter,
+ .pathname = strdup(pathname),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_req_file_meta_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_directory_flag = _get_directory_flag,
+ .get_delimiter = _get_delimiter,
+ .get_pathname = _get_pathname,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_REQ_FILE_META,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_req_file_meta.h b/src/libpts/tcg/tcg_pts_attr_req_file_meta.h
new file mode 100644
index 000000000..7620c50ab
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_req_file_meta.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_req_file_meta tcg_pts_attr_req_file_meta
+ * @{ @ingroup tcg_pts_attr_req_file_meta
+ */
+
+#ifndef TCG_PTS_ATTR_REQ_FILE_META_H_
+#define TCG_PTS_ATTR_REQ_FILE_META_H_
+
+typedef struct tcg_pts_attr_req_file_meta_t tcg_pts_attr_req_file_meta_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Request File Metadata attribute
+ *
+ */
+struct tcg_pts_attr_req_file_meta_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get directory flag for PTS Request File Metadata
+ *
+ * @return Directory Contents flag
+ */
+ bool (*get_directory_flag)(tcg_pts_attr_req_file_meta_t *this);
+
+ /**
+ * Get Delimiter
+ *
+ * @return UTF-8 encoding of a Delimiter Character
+ */
+ u_int8_t (*get_delimiter)(tcg_pts_attr_req_file_meta_t *this);
+
+ /**
+ * Get Fully Qualified File Pathname
+ *
+ * @return Pathname
+ */
+ char* (*get_pathname)(tcg_pts_attr_req_file_meta_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_req_file_meta_t object
+ *
+ * @param directory_flag Directory Contents Flag
+ * @param delimiter Delimiter Character
+ * @param pathname File Pathname
+ */
+pa_tnc_attr_t* tcg_pts_attr_req_file_meta_create(bool directory_flag,
+ u_int8_t delimiter,
+ char *pathname);
+
+/**
+ * Creates an tcg_pts_attr_req_file_meta_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_req_file_meta_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_REQ_FILE_META_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c b/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c
new file mode 100644
index 000000000..bfd108b9f
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_req_func_comp_evid.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_req_func_comp_evid_t private_tcg_pts_attr_req_func_comp_evid_t;
+
+/**
+ * Request Functional Component Evidence
+ * see section 3.14.1 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Sub-component Depth (for Component #1) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name #1 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name #1 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ........ |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Sub-component Depth (for Component #N) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name #N |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name #N |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Component Functional Name Structure
+ * (see section 5.1 of PTS Protocol: Binding to TNC IF-M Specification)
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name Vendor ID |Fam| Qualifier |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_REQ_FUNC_COMP_EVID_SIZE 12
+#define PTS_REQ_FUNC_COMP_FAMILY_MASK 0xC0
+
+/**
+ * Private data of an tcg_pts_attr_req_func_comp_evid_t object.
+ */
+struct private_tcg_pts_attr_req_func_comp_evid_t {
+
+ /**
+ * Public members of tcg_pts_attr_req_func_comp_evid_t
+ */
+ tcg_pts_attr_req_func_comp_evid_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * List of Functional Components
+ */
+ linked_list_t *list;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+typedef struct entry_t entry_t;
+
+/**
+ * Functional component entry
+ */
+struct entry_t {
+ u_int8_t flags;
+ u_int32_t depth;
+ pts_comp_func_name_t *name;
+};
+
+/**
+ * Enumerate functional component entries
+ */
+static bool entry_filter(void *null, entry_t **entry, u_int8_t *flags,
+ void *i2, u_int32_t *depth, void *i3,
+ pts_comp_func_name_t **name)
+{
+ *flags = (*entry)->flags;
+ *depth = (*entry)->depth;
+ *name = (*entry)->name;
+
+ return TRUE;
+}
+
+/**
+ * Free an entry_t object
+ */
+static void free_entry(entry_t *this)
+{
+ if (this)
+ {
+ this->name->destroy(this->name);
+ free(this);
+ }
+}
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_req_func_comp_evid_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ bio_writer_t *writer;
+ enumerator_t *enumerator;
+ entry_t *entry;
+
+ writer = bio_writer_create(PTS_REQ_FUNC_COMP_EVID_SIZE);
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ writer->write_uint8 (writer, entry->flags);
+ writer->write_uint24(writer, entry->depth);
+ writer->write_uint24(writer, entry->name->get_vendor_id(entry->name));
+ writer->write_uint8 (writer, entry->name->get_qualifier(entry->name));
+ writer->write_uint32(writer, entry->name->get_name(entry->name));
+ }
+ enumerator->destroy(enumerator);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_req_func_comp_evid_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int32_t depth, vendor_id, name;
+ u_int8_t flags, fam_and_qualifier, qualifier;
+ status_t status = FAILED;
+ entry_t *entry = NULL;
+
+ if (this->value.len < PTS_REQ_FUNC_COMP_EVID_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Request Functional "
+ "Component Evidence");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+
+ while (reader->remaining(reader))
+ {
+ if (!reader->read_uint8(reader, &flags))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
+ "Component Evidence Flags");
+ goto end;
+ }
+ if (!reader->read_uint24(reader, &depth))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
+ "Component Evidence Sub Component Depth");
+ goto end;
+ }
+ if (!reader->read_uint24(reader, &vendor_id))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
+ "Component Evidence Component Name Vendor ID");
+ goto end;
+ }
+ if (!reader->read_uint8(reader, &fam_and_qualifier))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
+ "Component Evidence Family and Qualifier");
+ goto end;
+ }
+ if (fam_and_qualifier & PTS_REQ_FUNC_COMP_FAMILY_MASK)
+ {
+ DBG1(DBG_TNC, "the Functional Name Encoding Family "
+ "is not Binary Enumeration");
+ goto end;
+ }
+ if (!reader->read_uint32(reader, &name))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
+ "Component Evidence Component Functional Name");
+ goto end;
+ }
+ qualifier = fam_and_qualifier & ~PTS_REQ_FUNC_COMP_FAMILY_MASK;
+
+ entry = malloc_thing(entry_t);
+ entry->flags = flags;
+ entry->depth = depth;
+ entry->name = pts_comp_func_name_create(vendor_id, name, qualifier);
+
+ this->list->insert_last(this->list, entry);
+ }
+ status = SUCCESS;
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->list->destroy_function(this->list, (void *)free_entry);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_req_func_comp_evid_t, add_component, void,
+ private_tcg_pts_attr_req_func_comp_evid_t *this, u_int8_t flags,
+ u_int32_t depth, pts_comp_func_name_t *name)
+{
+ entry_t *entry;
+
+ entry = malloc_thing(entry_t);
+ entry->flags = flags;
+ entry->depth = depth;
+ entry->name = name;
+ this->list->insert_last(this->list, entry);
+}
+
+METHOD(tcg_pts_attr_req_func_comp_evid_t, get_count, int,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ return this->list->get_count(this->list);
+}
+
+METHOD(tcg_pts_attr_req_func_comp_evid_t, create_enumerator, enumerator_t*,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ return enumerator_create_filter(this->list->create_enumerator(this->list),
+ (void*)entry_filter, NULL, NULL);
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create(void)
+{
+ private_tcg_pts_attr_req_func_comp_evid_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .add_component = _add_component,
+ .get_count = _get_count,
+ .create_enumerator = _create_enumerator,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_REQ_FUNC_COMP_EVID,
+ .list = linked_list_create(),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_req_func_comp_evid_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .add_component = _add_component,
+ .get_count = _get_count,
+ .create_enumerator = _create_enumerator,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_REQ_FUNC_COMP_EVID,
+ .list = linked_list_create(),
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.h b/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.h
new file mode 100644
index 000000000..031955aca
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_req_func_comp_evid tcg_pts_attr_req_func_comp_evid
+ * @{ @ingroup tcg_pts_attr_req_func_comp_evid
+ */
+
+#ifndef TCG_PTS_ATTR_REQ_FUNC_COMP_EVID_H_
+#define TCG_PTS_ATTR_REQ_FUNC_COMP_EVID_H_
+
+typedef struct tcg_pts_attr_req_func_comp_evid_t tcg_pts_attr_req_func_comp_evid_t;
+
+#include "tcg_attr.h"
+#include "pts/components/pts_comp_func_name.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Request Functional Component Evidence attribute
+ *
+ */
+struct tcg_pts_attr_req_func_comp_evid_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Add a component to the Functional Component Evidence Request
+ *
+ * @param flags Component Evidence Request Flags
+ * @param depth Sub-component Depth
+ * @param name Functional Component Name
+ */
+ void (*add_component)(tcg_pts_attr_req_func_comp_evid_t *this,
+ u_int8_t flags, u_int32_t depth,
+ pts_comp_func_name_t *name);
+
+ /**
+ * Returns the number of Functional Component entries
+ *
+ * @return Number of entries
+ */
+ int (*get_count)(tcg_pts_attr_req_func_comp_evid_t *this);
+
+ /**
+ * Enumerator over Functional Component entries
+ *
+ * @return Entry enumerator
+ */
+ enumerator_t* (*create_enumerator)(tcg_pts_attr_req_func_comp_evid_t *this);
+
+};
+
+/**
+ * Creates a tcg_pts_attr_req_func_comp_evid_t object
+ */
+pa_tnc_attr_t* tcg_pts_attr_req_func_comp_evid_create(void);
+
+/**
+ * Creates a tcg_pts_attr_req_func_comp_evid_t object from received data
+ *
+ * @param value Unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_req_func_comp_evid_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_REQ_FUNC_COMP_EVID_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c b/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c
new file mode 100644
index 000000000..d2c197ac4
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c
@@ -0,0 +1,514 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_simple_comp_evid.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+#include <time.h>
+
+typedef struct private_tcg_pts_attr_simple_comp_evid_t private_tcg_pts_attr_simple_comp_evid_t;
+
+/**
+ * Simple Component Evidence
+ * see section 3.15.1 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Sub-Component Depth |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Specific Functional Component |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Specific Functional Component |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measure. Type | Extended into PCR |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Hash Algorithm | PCR Transform | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement Date/Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement Date/Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement Date/Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement Date/Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement Date/Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Optional Policy URI Length | Opt. Verification Policy URI ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional Verification Policy URI ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Optional PCR Length | Optional PCR Before Value ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional PCR Before Value (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional PCR After Value (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Component Measurement (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Specific Functional Component -> Component Functional Name Structure
+ * see section 5.1 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name Vendor ID |Fam| Qualifier |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_SIMPLE_COMP_EVID_SIZE 40
+#define PTS_SIMPLE_COMP_EVID_MEAS_TIME_SIZE 20
+#define PTS_SIMPLE_COMP_EVID_RESERVED 0x00
+#define PTS_SIMPLE_COMP_EVID_FAMILY_MASK 0xC0
+#define PTS_SIMPLE_COMP_EVID_VALIDATION_MASK 0x60
+#define PTS_SIMPLE_COMP_EVID_MEAS_TYPE (1<<7)
+#define PTS_SIMPLE_COMP_EVID_FLAG_PCR (1<<7)
+
+static char *utc_undefined_time_str = "0000-00-00T00:00:00Z";
+
+/**
+ * Private data of an tcg_pts_attr_simple_comp_evid_t object.
+ */
+struct private_tcg_pts_attr_simple_comp_evid_t {
+
+ /**
+ * Public members of tcg_pts_attr_simple_comp_evid_t
+ */
+ tcg_pts_attr_simple_comp_evid_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * PTS Component Evidence
+ */
+ pts_comp_evidence_t *evidence;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_simple_comp_evid_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+/**
+ * Convert time_t to Simple Component Evidence UTS string format
+ */
+void measurement_time_to_utc(time_t measurement_time, chunk_t *utc_time)
+{
+ struct tm t;
+
+ if (measurement_time == UNDEFINED_TIME)
+ {
+ utc_time->ptr = utc_undefined_time_str;
+ }
+ else
+ {
+ gmtime_r(&measurement_time, &t);
+ sprintf(utc_time->ptr, "%04d-%02d-%02dT%02d:%02d:%02dZ",
+ t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
+ t.tm_hour, t.tm_min, t.tm_sec);
+ }
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ bio_writer_t *writer;
+ bool has_pcr_info;
+ char utc_time_buf[25];
+ u_int8_t flags;
+ u_int32_t depth, extended_pcr;
+ pts_comp_func_name_t *name;
+ pts_meas_algorithms_t hash_algorithm;
+ pts_pcr_transform_t transform;
+ pts_comp_evid_validation_t validation;
+ time_t measurement_time;
+ chunk_t measurement, utc_time, pcr_before, pcr_after, policy_uri;
+
+ /* Extract parameters from comp_evidence_t object */
+ name = this->evidence->get_comp_func_name(this->evidence,
+ &depth);
+ measurement = this->evidence->get_measurement(this->evidence,
+ &extended_pcr, &hash_algorithm, &transform,
+ &measurement_time);
+ has_pcr_info = this->evidence->get_pcr_info(this->evidence,
+ &pcr_before, &pcr_after);
+ validation = this->evidence->get_validation(this->evidence,
+ &policy_uri);
+
+ /* Determine the flags to set*/
+ flags = validation;
+ if (has_pcr_info)
+ {
+ flags |= PTS_SIMPLE_COMP_EVID_FLAG_PCR;
+ }
+
+ utc_time = chunk_create(utc_time_buf, PTS_SIMPLE_COMP_EVID_MEAS_TIME_SIZE);
+ measurement_time_to_utc(measurement_time, &utc_time);
+
+ writer = bio_writer_create(PTS_SIMPLE_COMP_EVID_SIZE);
+
+ writer->write_uint8 (writer, flags);
+ writer->write_uint24(writer, depth);
+ writer->write_uint24(writer, name->get_vendor_id(name));
+ writer->write_uint8 (writer, name->get_qualifier(name));
+ writer->write_uint32(writer, name->get_name(name));
+ writer->write_uint8 (writer, PTS_SIMPLE_COMP_EVID_MEAS_TYPE);
+ writer->write_uint24(writer, extended_pcr);
+ writer->write_uint16(writer, hash_algorithm);
+ writer->write_uint8 (writer, transform);
+ writer->write_uint8 (writer, PTS_SIMPLE_COMP_EVID_RESERVED);
+ writer->write_data (writer, utc_time);
+
+ /* Optional fields */
+ if (validation == PTS_COMP_EVID_VALIDATION_FAILED ||
+ validation == PTS_COMP_EVID_VALIDATION_PASSED)
+ {
+ writer->write_uint16(writer, policy_uri.len);
+ writer->write_data (writer, policy_uri);
+ }
+ if (has_pcr_info)
+ {
+ writer->write_uint16(writer, pcr_before.len);
+ writer->write_data (writer, pcr_before);
+ writer->write_data (writer, pcr_after);
+ }
+
+ writer->write_data(writer, measurement);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+static const int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+static const int tm_leap_1970 = 477;
+
+/**
+ * Convert Simple Component Evidence UTS string format to time_t
+ */
+bool measurement_time_from_utc(time_t *measurement_time, chunk_t utc_time)
+{
+ int tm_year, tm_mon, tm_day, tm_days, tm_hour, tm_min, tm_sec, tm_secs;
+ int tm_leap_4, tm_leap_100, tm_leap_400, tm_leap;
+
+ if (memeq(utc_undefined_time_str, utc_time.ptr, utc_time.len))
+ {
+ *measurement_time = 0;
+ return TRUE;
+ }
+ if (sscanf(utc_time.ptr, "%4d-%2d-%2dT%2d:%2d:%2dZ",
+ &tm_year, &tm_mon, &tm_day, &tm_hour, &tm_min, &tm_sec) != 6)
+ {
+ return FALSE;
+ }
+
+ /* representation of months as 0..11 */
+ tm_mon--;
+
+ /* representation of days as 0..30 */
+ tm_day--;
+
+ /* number of leap years between last year and 1970? */
+ tm_leap_4 = (tm_year - 1) / 4;
+ tm_leap_100 = tm_leap_4 / 25;
+ tm_leap_400 = tm_leap_100 / 4;
+ tm_leap = tm_leap_4 - tm_leap_100 + tm_leap_400 - tm_leap_1970;
+
+ /* if date later then February, is the current year a leap year? */
+ if (tm_mon > 1 && (tm_year % 4 == 0) &&
+ (tm_year % 100 != 0 || tm_year % 400 == 0))
+ {
+ tm_leap++;
+ }
+ tm_days = 365 * (tm_year - 1970) + days[tm_mon] + tm_day + tm_leap;
+ tm_secs = 60 * (60 * (24 * tm_days + tm_hour) + tm_min) + tm_sec;
+
+ *measurement_time = tm_secs;
+ return TRUE;
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_simple_comp_evid_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ pts_comp_func_name_t *name;
+ u_int8_t flags, fam_and_qualifier, qualifier, reserved;
+ u_int8_t measurement_type, transform, validation;
+ u_int16_t hash_algorithm, len;
+ u_int32_t depth, vendor_id, comp_name, extended_pcr;
+ chunk_t measurement, utc_time, policy_uri, pcr_before, pcr_after;
+ time_t measurement_time;
+ bool has_pcr_info = FALSE, has_validation = FALSE;
+ status_t status = FAILED;
+
+ if (this->value.len < PTS_SIMPLE_COMP_EVID_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Simple Component Evidence");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint24(reader, &depth);
+ reader->read_uint24(reader, &vendor_id);
+ reader->read_uint8 (reader, &fam_and_qualifier);
+ reader->read_uint32(reader, &comp_name);
+ reader->read_uint8 (reader, &measurement_type);
+ reader->read_uint24(reader, &extended_pcr);
+ reader->read_uint16(reader, &hash_algorithm);
+ reader->read_uint8 (reader, &transform);
+ reader->read_uint8 (reader, &reserved);
+ reader->read_data (reader, PTS_SIMPLE_COMP_EVID_MEAS_TIME_SIZE, &utc_time);
+
+ if (measurement_type != PTS_SIMPLE_COMP_EVID_MEAS_TYPE)
+ {
+ DBG1(DBG_TNC, "unsupported Measurement Type in "
+ "Simple Component Evidence");
+ *offset = 12;
+ reader->destroy(reader);
+ return FAILED;
+ }
+ if (!measurement_time_from_utc(&measurement_time, utc_time))
+ {
+ DBG1(DBG_TNC, "invalid Measurement Time field in "
+ "Simple Component Evidence");
+ *offset = 20;
+ reader->destroy(reader);
+ return FAILED;
+ }
+ validation = flags & PTS_SIMPLE_COMP_EVID_VALIDATION_MASK;
+ qualifier = fam_and_qualifier & ~PTS_SIMPLE_COMP_EVID_FAMILY_MASK;
+
+ /* Is optional Policy URI field included? */
+ if (validation == PTS_COMP_EVID_VALIDATION_FAILED ||
+ validation == PTS_COMP_EVID_VALIDATION_PASSED)
+ {
+ if (!reader->read_uint16(reader, &len))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence "
+ "Verification Policy URI Length");
+ goto end;
+ }
+ if (!reader->read_data(reader, len, &policy_uri))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence "
+ "Verification Policy URI");
+ goto end;
+ }
+ has_validation = TRUE;
+ }
+
+ /* Are optional PCR value fields included? */
+ if (flags & PTS_SIMPLE_COMP_EVID_FLAG_PCR)
+ {
+ if (!reader->read_uint16(reader, &len))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence "
+ "PCR Value length");
+ goto end;
+ }
+ if (!reader->read_data(reader, len, &pcr_before))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence "
+ "PCR Before Value");
+ goto end;
+ }
+ if (!reader->read_data(reader, len, &pcr_after))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence "
+ "PCR After Value");
+ goto end;
+ }
+ has_pcr_info = TRUE;
+ }
+
+ /* Measurement field comes at the very end */
+ reader->read_data(reader,reader->remaining(reader), &measurement);
+ reader->destroy(reader);
+
+ /* Create Component Functional Name object */
+ name = pts_comp_func_name_create(vendor_id, comp_name, qualifier);
+
+ /* Create Component Evidence object */
+ measurement = chunk_clone(measurement);
+ this->evidence = pts_comp_evidence_create(name, depth, extended_pcr,
+ hash_algorithm, transform,
+ measurement_time, measurement);
+
+ /* Add options */
+ if (has_validation)
+ {
+ policy_uri = chunk_clone(policy_uri);
+ this->evidence->set_validation(this->evidence, validation, policy_uri);
+ }
+ if (has_pcr_info)
+ {
+ pcr_before = chunk_clone(pcr_before);
+ pcr_after = chunk_clone(pcr_after);
+ this->evidence->set_pcr_info(this->evidence, pcr_before, pcr_after);
+ }
+
+ return SUCCESS;
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->evidence->destroy(this->evidence);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_simple_comp_evid_t, get_comp_evidence, pts_comp_evidence_t*,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ return this->evidence;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create(pts_comp_evidence_t *evid)
+{
+ private_tcg_pts_attr_simple_comp_evid_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_comp_evidence = _get_comp_evidence,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_SIMPLE_COMP_EVID,
+ .evidence = evid,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_simple_comp_evid_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_comp_evidence = _get_comp_evidence,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_SIMPLE_COMP_EVID,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.h b/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.h
new file mode 100644
index 000000000..3a80904c8
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_simple_comp_evid tcg_pts_attr_simple_comp_evid
+ * @{ @ingroup tcg_pts_attr_simple_comp_evid
+ */
+
+#ifndef TCG_PTS_ATTR_SIMPLE_COMP_EVID_H_
+#define TCG_PTS_ATTR_SIMPLE_COMP_EVID_H_
+
+typedef struct tcg_pts_attr_simple_comp_evid_t tcg_pts_attr_simple_comp_evid_t;
+
+#include "tcg_attr.h"
+#include "pts/components/pts_comp_evidence.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Simple Component Evidence attribute
+ *
+ */
+struct tcg_pts_attr_simple_comp_evid_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get Component Evidence
+ *
+ * @return Component Evidence
+ */
+ pts_comp_evidence_t* (*get_comp_evidence)(tcg_pts_attr_simple_comp_evid_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_simple_comp_evid_t object
+ *
+ * @param evid Component Evidence
+ */
+pa_tnc_attr_t* tcg_pts_attr_simple_comp_evid_create(pts_comp_evidence_t *evid);
+
+/**
+ * Creates an tcg_pts_attr_simple_comp_evid_t object from received data
+ *
+ * @param value Unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_simple_comp_evid_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_SIMPLE_COMP_EVID_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_simple_evid_final.c b/src/libpts/tcg/tcg_pts_attr_simple_evid_final.c
new file mode 100644
index 000000000..27720d509
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_simple_evid_final.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_simple_evid_final.h"
+#include "pts/pts_simple_evid_final.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_simple_evid_final_t private_tcg_pts_attr_simple_evid_final_t;
+
+/**
+ * Simple Evidence Final
+ * see section 3.15.2 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Reserved | Optional Composite Hash Alg |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Optional TPM PCR Composite Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional TPM PCR Composite (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Optional TPM Quote Signature Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional TPM Quote Signature (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional Evidence Signature (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_SIMPLE_EVID_FINAL_SIZE 2
+#define PTS_SIMPLE_EVID_FINAL_RESERVED 0x00
+#define PTS_SIMPLE_EVID_FINAL_FLAG_MASK 0xC0
+/**
+ * Private data of an tcg_pts_attr_simple_evid_final_t object.
+ */
+struct private_tcg_pts_attr_simple_evid_final_t {
+
+ /**
+ * Public members of tcg_pts_attr_simple_evid_final_t
+ */
+ tcg_pts_attr_simple_evid_final_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Set of flags for Simple Evidence Final
+ */
+ u_int8_t flags;
+
+ /**
+ * Optional Composite Hash Algorithm
+ */
+ pts_meas_algorithms_t comp_hash_algorithm;
+
+ /**
+ * Optional TPM PCR Composite
+ */
+ chunk_t pcr_comp;
+
+ /**
+ * Optional TPM Quote Signature
+ */
+ chunk_t tpm_quote_sig;
+
+ /**
+ * Is Evidence Signature included?
+ */
+ bool has_evid_sig;
+
+ /**
+ * Optional Evidence Signature
+ */
+ chunk_t evid_sig;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_simple_evid_final_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this->pcr_comp.ptr);
+ free(this->tpm_quote_sig.ptr);
+ free(this->evid_sig.ptr);
+ free(this);
+ }
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ bio_writer_t *writer;
+ u_int8_t flags;
+
+ flags = this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_MASK;
+
+ if (this->has_evid_sig)
+ {
+ flags |= PTS_SIMPLE_EVID_FINAL_EVID_SIG;
+ }
+
+ writer = bio_writer_create(PTS_SIMPLE_EVID_FINAL_SIZE);
+ writer->write_uint8 (writer, flags);
+ writer->write_uint8 (writer, PTS_SIMPLE_EVID_FINAL_RESERVED);
+
+ /** Optional Composite Hash Algorithm field is always present
+ * Field has value of all zeroes if not used.
+ * Implemented adhering the suggestion of Paul Sangster 28.Oct.2011
+ */
+ writer->write_uint16(writer, this->comp_hash_algorithm);
+
+ /* Optional fields */
+ if (this->flags != PTS_SIMPLE_EVID_FINAL_NO)
+ {
+ writer->write_uint32 (writer, this->pcr_comp.len);
+ writer->write_data (writer, this->pcr_comp);
+
+ writer->write_uint32 (writer, this->tpm_quote_sig.len);
+ writer->write_data (writer, this->tpm_quote_sig);
+ }
+
+ if (this->has_evid_sig)
+ {
+ writer->write_data (writer, this->evid_sig);
+ }
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_simple_evid_final_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t flags, reserved;
+ u_int16_t algorithm;
+ u_int32_t pcr_comp_len, tpm_quote_sig_len, evid_sig_len;
+ status_t status = FAILED;
+
+ if (this->value.len < PTS_SIMPLE_EVID_FINAL_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Simple Evidence Final");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+
+ reader->read_uint8(reader, &flags);
+ reader->read_uint8(reader, &reserved);
+
+ this->flags = flags & PTS_SIMPLE_EVID_FINAL_FLAG_MASK;
+
+ this->has_evid_sig = (flags & PTS_SIMPLE_EVID_FINAL_EVID_SIG) != 0;
+
+ /** Optional Composite Hash Algorithm field is always present
+ * Field has value of all zeroes if not used.
+ * Implemented adhering the suggestion of Paul Sangster 28.Oct.2011
+ */
+
+ reader->read_uint16(reader, &algorithm);
+ this->comp_hash_algorithm = algorithm;
+
+ /* Optional Composite Hash Algorithm and TPM PCR Composite fields */
+ if (this->flags != PTS_SIMPLE_EVID_FINAL_NO)
+ {
+ if (!reader->read_uint32(reader, &pcr_comp_len))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
+ "PCR Composite Length");
+ goto end;
+ }
+ if (!reader->read_data(reader, pcr_comp_len, &this->pcr_comp))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
+ "PCR Composite");
+ goto end;
+ }
+ this->pcr_comp = chunk_clone(this->pcr_comp);
+
+ if (!reader->read_uint32(reader, &tpm_quote_sig_len))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
+ "TPM Quote Singature Length");
+ goto end;
+ }
+ if (!reader->read_data(reader, tpm_quote_sig_len, &this->tpm_quote_sig))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
+ "TPM Quote Singature");
+ goto end;
+ }
+ this->tpm_quote_sig = chunk_clone(this->tpm_quote_sig);
+ }
+
+ /* Optional Evidence Signature field */
+ if (this->has_evid_sig)
+ {
+ evid_sig_len = reader->remaining(reader);
+ reader->read_data(reader, evid_sig_len, &this->evid_sig);
+ this->evid_sig = chunk_clone(this->evid_sig);
+ }
+
+ reader->destroy(reader);
+ return SUCCESS;
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(tcg_pts_attr_simple_evid_final_t, get_quote_info, u_int8_t,
+ private_tcg_pts_attr_simple_evid_final_t *this,
+ pts_meas_algorithms_t *comp_hash_algo, chunk_t *pcr_comp, chunk_t *tpm_quote_sig)
+{
+ if (comp_hash_algo)
+ {
+ *comp_hash_algo = this->comp_hash_algorithm;
+ }
+ if (pcr_comp)
+ {
+ *pcr_comp = this->pcr_comp;
+ }
+ if (tpm_quote_sig)
+ {
+ *tpm_quote_sig = this->tpm_quote_sig;
+ }
+ return this->flags;
+}
+
+METHOD(tcg_pts_attr_simple_evid_final_t, get_evid_sig, bool,
+ private_tcg_pts_attr_simple_evid_final_t *this, chunk_t *evid_sig)
+{
+ if (evid_sig)
+ {
+ *evid_sig = this->evid_sig;
+ }
+ return this->has_evid_sig;
+}
+
+METHOD(tcg_pts_attr_simple_evid_final_t, set_evid_sig, void,
+ private_tcg_pts_attr_simple_evid_final_t *this, chunk_t evid_sig)
+{
+ this->evid_sig = evid_sig;
+ this->has_evid_sig = TRUE;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(u_int8_t flags,
+ pts_meas_algorithms_t comp_hash_algorithm,
+ chunk_t pcr_comp, chunk_t tpm_quote_sig)
+{
+ private_tcg_pts_attr_simple_evid_final_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_quote_info = _get_quote_info,
+ .get_evid_sig = _get_evid_sig,
+ .set_evid_sig = _set_evid_sig,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_SIMPLE_EVID_FINAL,
+ .flags = flags,
+ .comp_hash_algorithm = comp_hash_algorithm,
+ .pcr_comp = pcr_comp,
+ .tpm_quote_sig = tpm_quote_sig,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_simple_evid_final_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_quote_info = _get_quote_info,
+ .get_evid_sig = _get_evid_sig,
+ .set_evid_sig = _set_evid_sig,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_SIMPLE_EVID_FINAL,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_simple_evid_final.h b/src/libpts/tcg/tcg_pts_attr_simple_evid_final.h
new file mode 100644
index 000000000..3d98bfce7
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_simple_evid_final.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_simple_evid_final tcg_pts_attr_simple_evid_final
+ * @{ @ingroup tcg_pts_attr_simple_evid_final
+ */
+
+#ifndef TCG_PTS_ATTR_SIMPLE_EVID_FINAL_H_
+#define TCG_PTS_ATTR_SIMPLE_EVID_FINAL_H_
+
+typedef struct tcg_pts_attr_simple_evid_final_t tcg_pts_attr_simple_evid_final_t;
+
+#include "tcg_attr.h"
+#include "tcg_pts_attr_meas_algo.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Simple Evidence Final attribute
+ *
+ */
+struct tcg_pts_attr_simple_evid_final_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get Optional PCR Composite and TPM Quote Signature
+ *
+ * @param comp_hash_algo Optional Composite Hash Algorithm
+ * @param pcr_comp Optional PCR Composite
+ * @param tpm_quote sig Optional TPM Quote Signature
+ * @return PTS_SIMPLE_EVID_FINAL flags
+ */
+ u_int8_t (*get_quote_info)(tcg_pts_attr_simple_evid_final_t *this,
+ pts_meas_algorithms_t *comp_hash_algo,
+ chunk_t *pcr_comp, chunk_t *tpm_quote_sig);
+
+ /**
+ * Get Optional Evidence Signature
+ *
+ * @evid_sig Optional Evidence Signature
+ * @return TRUE if Evidence Signature is available
+ */
+ bool (*get_evid_sig)(tcg_pts_attr_simple_evid_final_t *this, chunk_t *evid_sig);
+
+ /**
+ * Set Optional Evidence Signature
+ *
+ * @evid_sig Optional Evidence Signature
+ */
+ void (*set_evid_sig)(tcg_pts_attr_simple_evid_final_t *this, chunk_t evid_sig);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_simple_evid_final_t object
+ *
+ * @param flags Set of flags
+ * @param comp_hash_algorithm Composite Hash Algorithm
+ * @param pcr_comp Optional TPM PCR Composite
+ * @param tpm_quote_sign Optional TPM Quote Signature
+ */
+pa_tnc_attr_t* tcg_pts_attr_simple_evid_final_create(
+ u_int8_t flags,
+ pts_meas_algorithms_t comp_hash_algorithm,
+ chunk_t pcr_comp,
+ chunk_t tpm_quote_sign);
+
+/**
+ * Creates an tcg_pts_attr_simple_evid_final_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_simple_evid_final_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_SIMPLE_EVID_FINAL_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_tpm_version_info.c b/src/libpts/tcg/tcg_pts_attr_tpm_version_info.c
new file mode 100644
index 000000000..944a12cc9
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_tpm_version_info.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_tpm_version_info.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_tpm_version_info_t private_tcg_pts_attr_tpm_version_info_t;
+
+/**
+ * TPM Version Information
+ * see section 3.11 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | TPM Version Information (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * see TPM Structure Specification Part 2, section 21.6: TPM_CAP_VERSION_INFO
+ */
+
+#define PTS_TPM_VER_INFO_SIZE 4
+
+/**
+ * Private data of an tcg_pts_attr_tpm_version_info_t object.
+ */
+struct private_tcg_pts_attr_tpm_version_info_t {
+
+ /**
+ * Public members of tcg_pts_attr_tpm_version_info_t
+ */
+ tcg_pts_attr_tpm_version_info_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * TPM Version Information
+ */
+ chunk_t tpm_version_info;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_tpm_version_info_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ bio_writer_t *writer;
+
+ writer = bio_writer_create(PTS_TPM_VER_INFO_SIZE);
+ writer->write_data(writer, this->tpm_version_info);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_tpm_version_info_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+
+ if (this->value.len < PTS_TPM_VER_INFO_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for TPM Version Information");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_data (reader, this->value.len, &this->tpm_version_info);
+ this->tpm_version_info = chunk_clone(this->tpm_version_info);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this->tpm_version_info.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_tpm_version_info_t, get_tpm_version_info, chunk_t,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ return this->tpm_version_info;
+}
+
+METHOD(tcg_pts_attr_tpm_version_info_t, set_tpm_version_info, void,
+ private_tcg_pts_attr_tpm_version_info_t *this,
+ chunk_t tpm_version_info)
+{
+ this->tpm_version_info = tpm_version_info;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create(chunk_t tpm_version_info)
+{
+ private_tcg_pts_attr_tpm_version_info_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_tpm_version_info = _get_tpm_version_info,
+ .set_tpm_version_info = _set_tpm_version_info,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_TPM_VERSION_INFO,
+ .tpm_version_info = chunk_clone(tpm_version_info),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_tpm_version_info_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_tpm_version_info = _get_tpm_version_info,
+ .set_tpm_version_info = _set_tpm_version_info,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_TPM_VERSION_INFO,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_tpm_version_info.h b/src/libpts/tcg/tcg_pts_attr_tpm_version_info.h
new file mode 100644
index 000000000..2c12bb068
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_tpm_version_info.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_tpm_version_info tcg_pts_attr_tpm_version_info
+ * @{ @ingroup tcg_pts_attr_tpm_version_info
+ */
+
+#ifndef TCG_PTS_ATTR_TPM_VERSION_INFO_H_
+#define TCG_PTS_ATTR_TPM_VERSION_INFO_H_
+
+typedef struct tcg_pts_attr_tpm_version_info_t tcg_pts_attr_tpm_version_info_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS TPM Version Info Attribute
+ *
+ */
+struct tcg_pts_attr_tpm_version_info_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get TPM Version Info
+ *
+ * @return TPM version info
+ */
+ chunk_t (*get_tpm_version_info)(tcg_pts_attr_tpm_version_info_t *this);
+
+ /**
+ * Set TPM Version Info
+ *
+ * @param tpm_version_info TPM version info
+ */
+ void (*set_tpm_version_info)(tcg_pts_attr_tpm_version_info_t *this,
+ chunk_t tpm_version_info);
+};
+
+/**
+ * Creates an tcg_pts_attr_tpm_version_info_t object
+ *
+ * @param tpm_version_info TPM version info
+ */
+pa_tnc_attr_t* tcg_pts_attr_tpm_version_info_create(chunk_t tpm_version_info);
+
+/**
+ * Creates an tcg_pts_attr_tpm_version_info_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_tpm_version_info_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_TPM_VERSION_INFO_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c
new file mode 100644
index 000000000..a9f4a115d
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_unix_file_meta.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_file_meta_t private_tcg_pts_attr_file_meta_t;
+
+/**
+ * Unix-Style File Metadata
+ * see section 3.17.3 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of Files included |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of Files included |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File metadata Length | Type | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Create Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Create Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Modify Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Modify Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Access Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Access Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Owner ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Owner ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Group ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Group ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Filename (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ...........................
+ */
+
+#define PTS_FILE_META_SIZE 8
+#define PTS_FILE_MEAS_RESERVED 0x00
+#define PTS_FILE_METADATA_SIZE 52
+
+/**
+ * Private data of an tcg_pts_attr_file_meta_t object.
+ */
+struct private_tcg_pts_attr_file_meta_t {
+
+ /**
+ * Public members of tcg_pts_attr_file_meta_t
+ */
+ tcg_pts_attr_file_meta_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * PTS File Metadata
+ */
+ pts_file_meta_t *metadata;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_file_meta_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ bio_writer_t *writer;
+ enumerator_t *enumerator;
+ pts_file_metadata_t *entry;
+ u_int64_t number_of_files;
+
+ number_of_files = this->metadata->get_file_count(this->metadata);
+ writer = bio_writer_create(PTS_FILE_META_SIZE);
+
+ writer->write_uint64(writer, number_of_files);
+
+ enumerator = this->metadata->create_enumerator(this->metadata);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ writer->write_uint16(writer, PTS_FILE_METADATA_SIZE +
+ strlen(entry->filename));
+ writer->write_uint8 (writer, entry->type);
+ writer->write_uint8 (writer, PTS_FILE_MEAS_RESERVED);
+ writer->write_uint64(writer, entry->filesize);
+ writer->write_uint64(writer, entry->created);
+ writer->write_uint64(writer, entry->modified);
+ writer->write_uint64(writer, entry->accessed);
+ writer->write_uint64(writer, entry->owner);
+ writer->write_uint64(writer, entry->group);
+ writer->write_data (writer, chunk_create(entry->filename,
+ strlen(entry->filename)));
+ }
+ enumerator->destroy(enumerator);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_file_meta_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ pts_file_metadata_t *entry;
+ u_int8_t type, reserved;
+ u_int16_t len;
+ u_int64_t number_of_files, filesize, created, modified, accessed;
+ u_int64_t owner, group;
+ chunk_t filename;
+ status_t status = FAILED;
+
+ if (this->value.len < PTS_FILE_META_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Unix-Style file metadata header");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint64(reader, &number_of_files);
+
+ this->metadata = pts_file_meta_create();
+
+ while (number_of_files--)
+ {
+ if (!reader->read_uint16(reader, &len))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS file metadata length");
+ goto end;
+ }
+ if (!reader->read_uint8(reader, &type))
+ {
+ DBG1(DBG_TNC, "insufficient data for file type");
+ goto end;
+ }
+ if (!reader->read_uint8(reader, &reserved))
+ {
+ DBG1(DBG_TNC, "insufficient data for reserved field");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &filesize))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &created))
+ {
+ DBG1(DBG_TNC, "insufficient data for file create time");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &modified))
+ {
+ DBG1(DBG_TNC, "insufficient data for last modify time");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &accessed))
+ {
+ DBG1(DBG_TNC, "insufficient data for last access time");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &owner))
+ {
+ DBG1(DBG_TNC, "insufficient data for owner id");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &group))
+ {
+ DBG1(DBG_TNC, "insufficient data for group id");
+ goto end;
+ }
+ if (!reader->read_data(reader, len - PTS_FILE_METADATA_SIZE, &filename))
+ {
+ DBG1(DBG_TNC, "insufficient data for filename");
+ goto end;
+ }
+
+ entry = malloc_thing(pts_file_metadata_t);
+ entry->type = type;
+ entry->filesize = filesize;
+ entry->created = created;
+ entry->modified = modified;
+ entry->accessed = accessed;
+ entry->owner = owner;
+ entry->group = group;
+ entry->filename = malloc(filename.len + 1);
+ entry->filename[filename.len] = '\0';
+ memcpy(entry->filename, filename.ptr, filename.len);
+
+ this->metadata->add(this->metadata, entry);
+ }
+ status = SUCCESS;
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->metadata->destroy(this->metadata);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_file_meta_t, get_metadata, pts_file_meta_t*,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->metadata;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata)
+{
+ private_tcg_pts_attr_file_meta_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_metadata = _get_metadata,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_UNIX_FILE_META,
+ .metadata = metadata,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_file_meta_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_metadata = _get_metadata,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_UNIX_FILE_META,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_unix_file_meta.h b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.h
new file mode 100644
index 000000000..8a594eab5
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_unix_file_meta tcg_pts_attr_unix_file_meta
+ * @{ @ingroup tcg_pts_attr_unix_file_meta
+ */
+
+#ifndef TCG_PTS_ATTR_UNIX_FILE_META_H_
+#define TCG_PTS_ATTR_UNIX_FILE_META_H_
+
+typedef struct tcg_pts_attr_file_meta_t tcg_pts_attr_file_meta_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts.h"
+#include "pts/pts_file_meta.h"
+
+/**
+ * Class implementing the TCG PTS File Measurement attribute
+ *
+ */
+struct tcg_pts_attr_file_meta_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get PTS File Metadata
+ *
+ * @return PTS File Metadata
+ */
+ pts_file_meta_t* (*get_metadata)(tcg_pts_attr_file_meta_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_file_meta_t object
+ *
+ * @param metadata PTS File Metadata
+ */
+pa_tnc_attr_t* tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata);
+
+/**
+ * Creates an tcg_pts_attr_file_meta_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_unix_file_meta_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_UNIX_FILE_META_H_ @}*/
diff --git a/src/libradius/Makefile.am b/src/libradius/Makefile.am
new file mode 100644
index 000000000..5672f7b84
--- /dev/null
+++ b/src/libradius/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+ipseclib_LTLIBRARIES = libradius.la
+libradius_la_SOURCES = \
+ radius_message.h radius_message.c \
+ radius_socket.h radius_socket.c \
+ radius_client.h radius_client.c \
+ radius_config.h radius_config.c \
+ radius_mppe.h
+
diff --git a/src/libradius/Makefile.in b/src/libradius/Makefile.in
new file mode 100644
index 000000000..bcc38792a
--- /dev/null
+++ b/src/libradius/Makefile.in
@@ -0,0 +1,598 @@
+# 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/libradius
+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)$(ipseclibdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
+libradius_la_LIBADD =
+am_libradius_la_OBJECTS = radius_message.lo radius_socket.lo \
+ radius_client.lo radius_config.lo
+libradius_la_OBJECTS = $(am_libradius_la_OBJECTS)
+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 = $(libradius_la_SOURCES)
+DIST_SOURCES = $(libradius_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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
+ipseclib_LTLIBRARIES = libradius.la
+libradius_la_SOURCES = \
+ radius_message.h radius_message.c \
+ radius_socket.h radius_socket.c \
+ radius_client.h radius_client.c \
+ radius_config.h radius_config.c \
+ radius_mppe.h
+
+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/libradius/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libradius/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):
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
+ }
+
+uninstall-ipseclibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
+ done
+
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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
+libradius.la: $(libradius_la_OBJECTS) $(libradius_la_DEPENDENCIES)
+ $(LINK) -rpath $(ipseclibdir) $(libradius_la_OBJECTS) $(libradius_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_client.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_config.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_message.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radius_socket.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)$(ipseclibdir)"; 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-ipseclibLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-ipseclibLTLIBRARIES
+
+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-ipseclibLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-ipseclibLTLIBRARIES clean-libtool 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-ipseclibLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-ipseclibLTLIBRARIES
+
+
+# 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_radius/radius_client.c b/src/libradius/radius_client.c
index 245308e59..acdac78c9 100644
--- a/src/libcharon/plugins/eap_radius/radius_client.c
+++ b/src/libradius/radius_client.c
@@ -14,14 +14,12 @@
*/
#include "radius_client.h"
-
-#include "eap_radius_plugin.h"
-#include "radius_server.h"
+#include "radius_config.h"
#include <unistd.h>
#include <errno.h>
-#include <daemon.h>
+#include <debug.h>
#include <utils/host.h>
#include <utils/linked_list.h>
#include <threading/condvar.h>
@@ -40,9 +38,9 @@ struct private_radius_client_t {
radius_client_t public;
/**
- * Selected RADIUS server
+ * Selected RADIUS server configuration
*/
- radius_server_t *server;
+ radius_config_t *config;
/**
* RADIUS servers State attribute
@@ -86,37 +84,41 @@ METHOD(radius_client_t, request, radius_message_t*,
char virtual[] = {0x00,0x00,0x00,0x05};
radius_socket_t *socket;
radius_message_t *res;
+ chunk_t data;
/* we add the "Virtual" NAS-Port-Type, as we SHOULD include one */
req->add(req, RAT_NAS_PORT_TYPE, chunk_create(virtual, sizeof(virtual)));
/* add our NAS-Identifier */
req->add(req, RAT_NAS_IDENTIFIER,
- this->server->get_nas_identifier(this->server));
+ this->config->get_nas_identifier(this->config));
/* add State attribute, if server sent one */
if (this->state.ptr)
{
req->add(req, RAT_STATE, this->state);
}
- socket = this->server->get_socket(this->server);
+ socket = this->config->get_socket(this->config);
DBG1(DBG_CFG, "sending RADIUS %N to server '%s'", radius_message_code_names,
- req->get_code(req), this->server->get_name(this->server));
+ req->get_code(req), this->config->get_name(this->config));
+
res = socket->request(socket, req);
if (res)
{
DBG1(DBG_CFG, "received RADIUS %N from server '%s'",
radius_message_code_names, res->get_code(res),
- this->server->get_name(this->server));
+ this->config->get_name(this->config));
+ data = res->get_encoding(res);
+ DBG3(DBG_CFG, "%B", &data);
+
save_state(this, res);
if (res->get_code(res) == RMC_ACCESS_ACCEPT)
{
chunk_clear(&this->msk);
this->msk = socket->decrypt_msk(socket, req, res);
}
- this->server->put_socket(this->server, socket, TRUE);
+ this->config->put_socket(this->config, socket, TRUE);
return res;
}
- this->server->put_socket(this->server, socket, FALSE);
- charon->bus->alert(charon->bus, ALERT_RADIUS_NOT_RESPONDING);
+ this->config->put_socket(this->config, socket, FALSE);
return NULL;
}
@@ -129,7 +131,7 @@ METHOD(radius_client_t, get_msk, chunk_t,
METHOD(radius_client_t, destroy, void,
private_radius_client_t *this)
{
- this->server->destroy(this->server);
+ this->config->destroy(this->config);
chunk_clear(&this->msk);
free(this->state.ptr);
free(this);
@@ -138,12 +140,9 @@ METHOD(radius_client_t, destroy, void,
/**
* See header
*/
-radius_client_t *radius_client_create()
+radius_client_t *radius_client_create(radius_config_t *config)
{
private_radius_client_t *this;
- enumerator_t *enumerator;
- radius_server_t *server;
- int current, best = -1;
INIT(this,
.public = {
@@ -151,36 +150,8 @@ radius_client_t *radius_client_create()
.get_msk = _get_msk,
.destroy = _destroy,
},
+ .config = config,
);
- enumerator = eap_radius_create_server_enumerator();
- while (enumerator->enumerate(enumerator, &server))
- {
- current = server->get_preference(server);
- if (current > best ||
- /* for two with equal preference, 50-50 chance */
- (current == best && random() % 2 == 0))
- {
- DBG2(DBG_CFG, "RADIUS server '%s' is candidate: %d",
- server->get_name(server), current);
- best = current;
- DESTROY_IF(this->server);
- this->server = server->get_ref(server);
- }
- else
- {
- DBG2(DBG_CFG, "RADIUS server '%s' skipped: %d",
- server->get_name(server), current);
- }
- }
- enumerator->destroy(enumerator);
-
- if (!this->server)
- {
- free(this);
- return NULL;
- }
-
return &this->public;
}
-
diff --git a/src/libcharon/plugins/eap_radius/radius_client.h b/src/libradius/radius_client.h
index e4f3a7222..cf5f79b6c 100644
--- a/src/libcharon/plugins/eap_radius/radius_client.h
+++ b/src/libradius/radius_client.h
@@ -15,13 +15,14 @@
/**
* @defgroup radius_client radius_client
- * @{ @ingroup eap_radius
+ * @{ @ingroup libradius
*/
#ifndef RADIUS_CLIENT_H_
#define RADIUS_CLIENT_H_
#include "radius_message.h"
+#include "radius_config.h"
typedef struct radius_client_t radius_client_t;
@@ -59,8 +60,9 @@ struct radius_client_t {
/**
* Create a RADIUS client.
*
+ * @param config reference to a server configuration, gets owned
* @return radius_client_t object
*/
-radius_client_t *radius_client_create();
+radius_client_t *radius_client_create(radius_config_t *config);
#endif /** RADIUS_CLIENT_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/radius_server.c b/src/libradius/radius_config.c
index 3baf39807..6e3394bb0 100644
--- a/src/libcharon/plugins/eap_radius/radius_server.c
+++ b/src/libradius/radius_config.c
@@ -13,23 +13,23 @@
* for more details.
*/
-#include "radius_server.h"
+#include "radius_config.h"
#include <threading/mutex.h>
#include <threading/condvar.h>
#include <utils/linked_list.h>
-typedef struct private_radius_server_t private_radius_server_t;
+typedef struct private_radius_config_t private_radius_config_t;
/**
- * Private data of an radius_server_t object.
+ * Private data of an radius_config_t object.
*/
-struct private_radius_server_t {
+struct private_radius_config_t {
/**
- * Public radius_server_t interface.
+ * Public radius_config_t interface.
*/
- radius_server_t public;
+ radius_config_t public;
/**
* list of radius sockets, as radius_socket_t
@@ -82,8 +82,8 @@ struct private_radius_server_t {
refcount_t ref;
};
-METHOD(radius_server_t, get_socket, radius_socket_t*,
- private_radius_server_t *this)
+METHOD(radius_config_t, get_socket, radius_socket_t*,
+ private_radius_config_t *this)
{
radius_socket_t *skt;
@@ -96,8 +96,8 @@ METHOD(radius_server_t, get_socket, radius_socket_t*,
return skt;
}
-METHOD(radius_server_t, put_socket, void,
- private_radius_server_t *this, radius_socket_t *skt, bool result)
+METHOD(radius_config_t, put_socket, void,
+ private_radius_config_t *this, radius_socket_t *skt, bool result)
{
this->mutex->lock(this->mutex);
this->sockets->insert_last(this->sockets, skt);
@@ -106,14 +106,14 @@ METHOD(radius_server_t, put_socket, void,
this->reachable = result;
}
-METHOD(radius_server_t, get_nas_identifier, chunk_t,
- private_radius_server_t *this)
+METHOD(radius_config_t, get_nas_identifier, chunk_t,
+ private_radius_config_t *this)
{
return this->nas_identifier;
}
-METHOD(radius_server_t, get_preference, int,
- private_radius_server_t *this)
+METHOD(radius_config_t, get_preference, int,
+ private_radius_config_t *this)
{
int pref;
@@ -147,22 +147,22 @@ METHOD(radius_server_t, get_preference, int,
return pref;
}
-METHOD(radius_server_t, get_name, char*,
- private_radius_server_t *this)
+METHOD(radius_config_t, get_name, char*,
+ private_radius_config_t *this)
{
return this->name;
}
-METHOD(radius_server_t, get_ref, radius_server_t*,
- private_radius_server_t *this)
+METHOD(radius_config_t, get_ref, radius_config_t*,
+ private_radius_config_t *this)
{
ref_get(&this->ref);
return &this->public;
}
-METHOD(radius_server_t, destroy, void,
- private_radius_server_t *this)
+METHOD(radius_config_t, destroy, void,
+ private_radius_config_t *this)
{
if (ref_put(&this->ref))
{
@@ -177,10 +177,12 @@ METHOD(radius_server_t, destroy, void,
/**
* See header
*/
-radius_server_t *radius_server_create(char *name, char *address, u_int16_t port,
- char *nas_identifier, char *secret, int sockets, int preference)
+radius_config_t *radius_config_create(char *name, char *address,
+ u_int16_t auth_port, u_int16_t acct_port,
+ char *nas_identifier, char *secret,
+ int sockets, int preference)
{
- private_radius_server_t *this;
+ private_radius_config_t *this;
radius_socket_t *socket;
INIT(this,
@@ -206,7 +208,7 @@ radius_server_t *radius_server_create(char *name, char *address, u_int16_t port,
while (sockets--)
{
- socket = radius_socket_create(address, port,
+ socket = radius_socket_create(address, auth_port, acct_port,
chunk_create(secret, strlen(secret)));
if (!socket)
{
diff --git a/src/libcharon/plugins/eap_radius/radius_server.h b/src/libradius/radius_config.h
index c59361c49..40ed6197a 100644
--- a/src/libcharon/plugins/eap_radius/radius_server.h
+++ b/src/libradius/radius_config.h
@@ -14,28 +14,28 @@
*/
/**
- * @defgroup radius_server radius_server
- * @{ @ingroup eap_radius
+ * @defgroup radius_config radius_config
+ * @{ @ingroup libradius
*/
-#ifndef RADIUS_SERVER_H_
-#define RADIUS_SERVER_H_
+#ifndef RADIUS_CONFIG_H_
+#define RADIUS_CONFIG_H_
-typedef struct radius_server_t radius_server_t;
+typedef struct radius_config_t radius_config_t;
#include "radius_socket.h"
/**
* RADIUS server configuration.
*/
-struct radius_server_t {
+struct radius_config_t {
/**
- * Get a RADIUS socket from the pool to communicate with this server.
+ * Get a RADIUS socket from the pool to communicate with this config.
*
* @return RADIUS socket
*/
- radius_socket_t* (*get_socket)(radius_server_t *this);
+ radius_socket_t* (*get_socket)(radius_config_t *this);
/**
* Release a socket to the pool after use.
@@ -43,14 +43,14 @@ struct radius_server_t {
* @param skt RADIUS socket to release
* @param result result of the socket use, TRUE for success
*/
- void (*put_socket)(radius_server_t *this, radius_socket_t *skt, bool result);
+ void (*put_socket)(radius_config_t *this, radius_socket_t *skt, bool result);
/**
* Get the NAS-Identifier to use with this server.
*
* @return NAS-Identifier, internal data
*/
- chunk_t (*get_nas_identifier)(radius_server_t *this);
+ chunk_t (*get_nas_identifier)(radius_config_t *this);
/**
* Get the preference of this server.
@@ -58,40 +58,43 @@ struct radius_server_t {
* Based on the available sockets and the server reachability a preference
* value is calculated: better servers return a higher value.
*/
- int (*get_preference)(radius_server_t *this);
+ int (*get_preference)(radius_config_t *this);
/**
* Get the name of the RADIUS server.
*
* @return server name
*/
- char* (*get_name)(radius_server_t *this);
+ char* (*get_name)(radius_config_t *this);
/**
- * Increase reference count of this server.
+ * Increase reference count of this server configuration.
*
* @return this
*/
- radius_server_t* (*get_ref)(radius_server_t *this);
+ radius_config_t* (*get_ref)(radius_config_t *this);
/**
- * Destroy a radius_server_t.
+ * Destroy a radius_config_t.
*/
- void (*destroy)(radius_server_t *this);
+ void (*destroy)(radius_config_t *this);
};
/**
- * Create a radius_server instance.
+ * Create a radius_config_t instance.
*
* @param name server name
* @param address server address
- * @param port server port
+ * @param auth_port server port for authentication
+ * @param acct_port server port for accounting
* @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
*/
-radius_server_t *radius_server_create(char *name, char *address, u_int16_t port,
- char *nas_identifier, char *secret, int sockets, int preference);
+radius_config_t *radius_config_create(char *name, char *address,
+ u_int16_t auth_port, u_int16_t acct_port,
+ char *nas_identifier, char *secret,
+ int sockets, int preference);
-#endif /** RADIUS_SERVER_H_ @}*/
+#endif /** RADIUS_CONFIG_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/radius_message.c b/src/libradius/radius_message.c
index 23a29b772..17fa7357b 100644
--- a/src/libcharon/plugins/eap_radius/radius_message.c
+++ b/src/libradius/radius_message.c
@@ -15,7 +15,7 @@
#include "radius_message.h"
-#include <daemon.h>
+#include <debug.h>
#include <crypto/hashers/hasher.h>
typedef struct private_radius_message_t private_radius_message_t;
@@ -66,6 +66,14 @@ struct private_radius_message_t {
rmsg_t *msg;
};
+/**
+ * Described in header.
+ */
+void libradius_init(void)
+{
+ /* empty */
+}
+
ENUM_BEGIN(radius_message_code_names, RMC_ACCESS_REQUEST, RMC_ACCOUNTING_RESPONSE,
"Access-Request",
"Access-Accept",
@@ -74,7 +82,14 @@ ENUM_BEGIN(radius_message_code_names, RMC_ACCESS_REQUEST, RMC_ACCOUNTING_RESPONS
"Accounting-Response");
ENUM_NEXT(radius_message_code_names, RMC_ACCESS_CHALLENGE, RMC_ACCESS_CHALLENGE, RMC_ACCOUNTING_RESPONSE,
"Access-Challenge");
-ENUM_END(radius_message_code_names, RMC_ACCESS_CHALLENGE);
+ENUM_NEXT(radius_message_code_names, RMC_DISCONNECT_REQUEST, RMC_COA_NAK, RMC_ACCESS_CHALLENGE,
+ "Disconnect-Request",
+ "Disconnect-ACK",
+ "Disconnect-NAK",
+ "CoA-Request",
+ "CoA-ACK",
+ "CoA-NAK");
+ENUM_END(radius_message_code_names, RMC_COA_NAK);
ENUM(radius_attribute_type_names, RAT_USER_NAME, RAT_MIP6_HOME_LINK_PREFIX,
"User-Name",
@@ -261,7 +276,7 @@ METHOD(radius_message_t, add, void,
{
rattr_t *attribute;
- data.len = min(data.len, 253);
+ data.len = min(data.len, MAX_RADIUS_ATTRIBUTE_SIZE);
this->msg = realloc(this->msg,
ntohs(this->msg->length) + sizeof(rattr_t) + data.len);
attribute = ((void*)this->msg) + ntohs(this->msg->length);
@@ -272,19 +287,48 @@ METHOD(radius_message_t, add, void,
}
METHOD(radius_message_t, sign, void,
- private_radius_message_t *this, rng_t *rng, signer_t *signer)
+ private_radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
+ hasher_t *hasher, signer_t *signer, rng_t *rng, bool msg_auth)
{
- char buf[HASH_SIZE_MD5];
+ if (rng)
+ {
+ /* build Request-Authenticator */
+ rng->get_bytes(rng, HASH_SIZE_MD5, this->msg->authenticator);
+ }
+ else
+ {
+ /* prepare build of Response-Authenticator */
+ if (req_auth)
+ {
+ memcpy(this->msg->authenticator, req_auth, HASH_SIZE_MD5);
+ }
+ else
+ {
+ memset(this->msg->authenticator, 0, sizeof(this->msg->authenticator));
+ }
+ }
- /* build Request-Authenticator */
- rng->get_bytes(rng, HASH_SIZE_MD5, this->msg->authenticator);
+ if (msg_auth)
+ {
+ char buf[HASH_SIZE_MD5];
- /* build Message-Authenticator attribute, using 16 null bytes */
- memset(buf, 0, sizeof(buf));
- add(this, RAT_MESSAGE_AUTHENTICATOR, chunk_create(buf, sizeof(buf)));
- signer->get_signature(signer,
+ /* build Message-Authenticator attribute, using 16 null bytes */
+ memset(buf, 0, sizeof(buf));
+ add(this, RAT_MESSAGE_AUTHENTICATOR, chunk_create(buf, sizeof(buf)));
+ signer->get_signature(signer,
chunk_create((u_char*)this->msg, ntohs(this->msg->length)),
((u_char*)this->msg) + ntohs(this->msg->length) - HASH_SIZE_MD5);
+ }
+
+ if (!rng)
+ {
+ chunk_t msg;
+
+ /* build Response-Authenticator */
+ msg = chunk_create((u_char*)this->msg, ntohs(this->msg->length));
+ hasher->get_hash(hasher, msg, NULL);
+ hasher->get_hash(hasher, secret, this->msg->authenticator);
+ }
}
METHOD(radius_message_t, verify, bool,
@@ -297,18 +341,29 @@ METHOD(radius_message_t, verify, bool,
chunk_t data, msg;
bool has_eap = FALSE, has_auth = FALSE;
- /* replace Response by Request Authenticator for verification */
- memcpy(res_auth, this->msg->authenticator, HASH_SIZE_MD5);
- memcpy(this->msg->authenticator, req_auth, HASH_SIZE_MD5);
msg = chunk_create((u_char*)this->msg, ntohs(this->msg->length));
- /* verify Response-Authenticator */
- hasher->get_hash(hasher, msg, NULL);
- hasher->get_hash(hasher, secret, buf);
- if (!memeq(buf, res_auth, HASH_SIZE_MD5))
+ if (this->msg->code != RMC_ACCESS_REQUEST)
{
- DBG1(DBG_CFG, "RADIUS Response-Authenticator verification failed");
- return FALSE;
+ /* replace Response by Request Authenticator for verification */
+ memcpy(res_auth, this->msg->authenticator, HASH_SIZE_MD5);
+ if (req_auth)
+ {
+ memcpy(this->msg->authenticator, req_auth, HASH_SIZE_MD5);
+ }
+ else
+ {
+ memset(this->msg->authenticator, 0, HASH_SIZE_MD5);
+ }
+
+ /* verify Response-Authenticator */
+ hasher->get_hash(hasher, msg, NULL);
+ hasher->get_hash(hasher, secret, buf);
+ if (!memeq(buf, res_auth, HASH_SIZE_MD5))
+ {
+ DBG1(DBG_CFG, "RADIUS Response-Authenticator verification failed");
+ return FALSE;
+ }
}
/* verify Message-Authenticator attribute */
@@ -346,8 +401,12 @@ METHOD(radius_message_t, verify, bool,
}
}
enumerator->destroy(enumerator);
- /* restore Response-Authenticator */
- memcpy(this->msg->authenticator, res_auth, HASH_SIZE_MD5);
+
+ if (this->msg->code != RMC_ACCESS_REQUEST)
+ {
+ /* restore Response-Authenticator */
+ memcpy(this->msg->authenticator, res_auth, HASH_SIZE_MD5);
+ }
if (has_eap && !has_auth)
{ /* Message-Authenticator is required if we have an EAP-Message */
@@ -398,7 +457,7 @@ METHOD(radius_message_t, destroy, void,
/**
* Generic constructor
*/
-static private_radius_message_t *radius_message_create()
+static private_radius_message_t *radius_message_create_empty()
{
private_radius_message_t *this;
@@ -423,12 +482,12 @@ static private_radius_message_t *radius_message_create()
/**
* See header
*/
-radius_message_t *radius_message_create_request()
+radius_message_t *radius_message_create(radius_message_code_t code)
{
- private_radius_message_t *this = radius_message_create();
+ private_radius_message_t *this = radius_message_create_empty();
INIT(this->msg,
- .code = RMC_ACCESS_REQUEST,
+ .code = code,
.identifier = 0,
.length = htons(sizeof(rmsg_t)),
);
@@ -439,9 +498,9 @@ radius_message_t *radius_message_create_request()
/**
* See header
*/
-radius_message_t *radius_message_parse_response(chunk_t data)
+radius_message_t *radius_message_parse(chunk_t data)
{
- private_radius_message_t *this = radius_message_create();
+ private_radius_message_t *this = radius_message_create_empty();
this->msg = malloc(data.len);
memcpy(this->msg, data.ptr, data.len);
@@ -454,4 +513,3 @@ radius_message_t *radius_message_parse_response(chunk_t data)
}
return &this->public;
}
-
diff --git a/src/libcharon/plugins/eap_radius/radius_message.h b/src/libradius/radius_message.h
index 266839d3b..6d0df53c3 100644
--- a/src/libcharon/plugins/eap_radius/radius_message.h
+++ b/src/libradius/radius_message.h
@@ -14,8 +14,13 @@
*/
/**
+ * @defgroup libradius libradius
+ *
+ * @addtogroup libradius
+ * RADIUS protocol support library.
+ *
* @defgroup radius_message radius_message
- * @{ @ingroup eap_radius
+ * @{ @ingroup libradius
*/
#ifndef RADIUS_MESSAGE_H_
@@ -23,6 +28,10 @@
#include <library.h>
+#define MAX_RADIUS_ATTRIBUTE_SIZE 253
+
+#define RADIUS_TUNNEL_TYPE_ESP 9
+
typedef struct radius_message_t radius_message_t;
typedef enum radius_message_code_t radius_message_code_t;
typedef enum radius_attribute_type_t radius_attribute_type_t;
@@ -37,6 +46,12 @@ enum radius_message_code_t {
RMC_ACCOUNTING_REQUEST = 4,
RMC_ACCOUNTING_RESPONSE = 5,
RMC_ACCESS_CHALLENGE = 11,
+ RMC_DISCONNECT_REQUEST = 40,
+ RMC_DISCONNECT_ACK = 41,
+ RMC_DISCONNECT_NAK = 42,
+ RMC_COA_REQUEST = 43,
+ RMC_COA_ACK = 44,
+ RMC_COA_NAK = 45,
};
/**
@@ -236,18 +251,23 @@ struct radius_message_t {
/**
* Calculate and add the Message-Authenticator attribute to the message.
*
- * @param rng RNG to create Request-Authenticator
+ * @param req_auth 16 byte Authenticator of request, or NULL
+ * @param secret shared RADIUS secret
* @param signer HMAC-MD5 signer with secret set
+ * @param hasher MD5 hasher
+ * @param rng RNG to create Request-Authenticator, NULL to omit
+ * @param msg_auth calculate and add Message-Authenticator
*/
- void (*sign)(radius_message_t *this, rng_t *rng, signer_t *signer);
+ void (*sign)(radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
+ hasher_t *hasher, signer_t *signer, rng_t *rng, bool msg_auth);
/**
- * Verify the integrity of a received RADIUS response.
+ * Verify the integrity of a received RADIUS message.
*
- * @param req_auth 16 byte Authenticator of the corresponding request
+ * @param req_auth 16 byte Authenticator of request, or NULL
* @param secret shared RADIUS secret
- * @param hasher hasher to verify Response-Authenticator
- * @param signer signer to verify Message-Authenticator attribute
+ * @param signer HMAC-MD5 signer with secret set
+ * @param hasher MD5 hasher
*/
bool (*verify)(radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
hasher_t *hasher, signer_t *signer);
@@ -259,18 +279,24 @@ struct radius_message_t {
};
/**
- * Create an empty RADIUS request message (RMT_ACCESS_REQUEST).
+ * Dummy libradius initialization function needed for integrity test
+ */
+void libradius_init(void);
+
+/**
+ * Create an empty RADIUS message.
*
+ * @param code request type
* @return radius_message_t object
*/
-radius_message_t *radius_message_create_request();
+radius_message_t *radius_message_create(radius_message_code_t code);
/**
- * Parse and verify a recevied RADIUS response.
+ * Parse and verify a recevied RADIUS message.
*
* @param data received message data
* @return radius_message_t object, NULL if length invalid
*/
-radius_message_t *radius_message_parse_response(chunk_t data);
+radius_message_t *radius_message_parse(chunk_t data);
#endif /** RADIUS_MESSAGE_H_ @}*/
diff --git a/src/libradius/radius_mppe.h b/src/libradius/radius_mppe.h
new file mode 100644
index 000000000..1b7a732ec
--- /dev/null
+++ b/src/libradius/radius_mppe.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 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 radius_mppe radius_mppe
+ * @{ @ingroup libradius
+ */
+
+#ifndef RADIUS_MPPE_H_
+#define RADIUS_MPPE_H_
+
+/**
+ * Microsoft specific vendor attributes
+ */
+#define MS_MPPE_SEND_KEY 16
+#define MS_MPPE_RECV_KEY 17
+
+typedef struct mppe_key_t mppe_key_t;
+
+struct mppe_key_t {
+ u_int32_t id;
+ u_int8_t type;
+ u_int8_t length;
+ u_int16_t salt;
+ u_int8_t key[];
+} __attribute__((packed));
+
+#endif /** RADIUS_MPPE_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/radius_socket.c b/src/libradius/radius_socket.c
index b3229c288..048c8814e 100644
--- a/src/libcharon/plugins/eap_radius/radius_socket.c
+++ b/src/libradius/radius_socket.c
@@ -14,23 +14,14 @@
*/
#include "radius_socket.h"
+#include "radius_mppe.h"
#include <errno.h>
#include <unistd.h>
+#include <pen/pen.h>
#include <debug.h>
-/**
- * Vendor-Id of Microsoft specific attributes
- */
-#define VENDOR_ID_MICROSOFT 311
-
-/**
- * Microsoft specific vendor attributes
- */
-#define MS_MPPE_SEND_KEY 16
-#define MS_MPPE_RECV_KEY 17
-
typedef struct private_radius_socket_t private_radius_socket_t;
/**
@@ -44,19 +35,29 @@ struct private_radius_socket_t {
radius_socket_t public;
/**
- * socket file descriptor
+ * Server port for authentication
*/
- int fd;
+ u_int16_t auth_port;
/**
- * Server address
+ * socket file descriptor for authentication
*/
- char *address;
+ int auth_fd;
/**
- * Server port
+ * Server port for accounting
*/
- u_int16_t port;
+ u_int16_t acct_port;
+
+ /**
+ * socket file descriptor for accounting
+ */
+ int acct_fd;
+
+ /**
+ * Server address
+ */
+ char *address;
/**
* current RADIUS identifier
@@ -87,35 +88,36 @@ struct private_radius_socket_t {
/**
* Check or establish RADIUS connection
*/
-static bool check_connection(private_radius_socket_t *this)
+static bool check_connection(private_radius_socket_t *this,
+ int *fd, u_int16_t port)
{
- if (this->fd == -1)
+ if (*fd == -1)
{
host_t *server;
- server = host_create_from_dns(this->address, AF_UNSPEC, this->port);
+ server = host_create_from_dns(this->address, AF_UNSPEC, port);
if (!server)
{
DBG1(DBG_CFG, "resolving RADIUS server address '%s' failed",
this->address);
return FALSE;
}
- this->fd = socket(server->get_family(server), SOCK_DGRAM, IPPROTO_UDP);
- if (this->fd == -1)
+ *fd = socket(server->get_family(server), SOCK_DGRAM, IPPROTO_UDP);
+ if (*fd == -1)
{
DBG1(DBG_CFG, "opening RADIUS socket for %#H failed: %s",
server, strerror(errno));
server->destroy(server);
return FALSE;
}
- if (connect(this->fd, server->get_sockaddr(server),
+ if (connect(*fd, server->get_sockaddr(server),
*server->get_sockaddr_len(server)) < 0)
{
DBG1(DBG_CFG, "connecting RADIUS socket to %#H failed: %s",
server, strerror(errno));
server->destroy(server);
- close(this->fd);
- this->fd = -1;
+ close(*fd);
+ *fd = -1;
return FALSE;
}
server->destroy(server);
@@ -127,19 +129,36 @@ METHOD(radius_socket_t, request, radius_message_t*,
private_radius_socket_t *this, radius_message_t *request)
{
chunk_t data;
- int i;
+ int i, *fd;
+ u_int16_t port;
+ rng_t *rng = NULL;
+
+ if (request->get_code(request) == RMC_ACCOUNTING_REQUEST)
+ {
+ fd = &this->acct_fd;
+ port = this->acct_port;
+ }
+ else
+ {
+ fd = &this->auth_fd;
+ port = this->auth_port;
+ rng = this->rng;
+ }
/* set Message Identifier */
request->set_identifier(request, this->identifier++);
/* sign the request */
- request->sign(request, this->rng, this->signer);
+ request->sign(request, NULL, this->secret, this->hasher, this->signer,
+ rng, rng != NULL);
- if (!check_connection(this))
+ if (!check_connection(this, fd, port))
{
return NULL;
}
data = request->get_encoding(request);
+ DBG3(DBG_CFG, "%B", &data);
+
/* timeout after 2, 3, 4, 5 seconds */
for (i = 2; i <= 5; i++)
{
@@ -150,7 +169,7 @@ METHOD(radius_socket_t, request, radius_message_t*,
fd_set fds;
int res;
- if (send(this->fd, data.ptr, data.len, 0) != data.len)
+ if (send(*fd, data.ptr, data.len, 0) != data.len)
{
DBG1(DBG_CFG, "sending RADIUS message failed: %s", strerror(errno));
return NULL;
@@ -161,8 +180,8 @@ METHOD(radius_socket_t, request, radius_message_t*,
while (TRUE)
{
FD_ZERO(&fds);
- FD_SET(this->fd, &fds);
- res = select(this->fd + 1, &fds, NULL, NULL, &tv);
+ FD_SET(*fd, &fds);
+ res = select((*fd) + 1, &fds, NULL, NULL, &tv);
/* TODO: updated tv to time not waited. Linux does this for us. */
if (res < 0)
{ /* failed */
@@ -176,14 +195,14 @@ METHOD(radius_socket_t, request, radius_message_t*,
retransmit = TRUE;
break;
}
- res = recv(this->fd, buf, sizeof(buf), MSG_DONTWAIT);
+ res = recv(*fd, buf, sizeof(buf), MSG_DONTWAIT);
if (res <= 0)
{
DBG1(DBG_CFG, "receiving RADIUS message failed: %s",
strerror(errno));
break;
}
- response = radius_message_parse_response(chunk_create(buf, res));
+ response = radius_message_parse(chunk_create(buf, res));
if (response)
{
if (response->verify(response,
@@ -262,13 +281,7 @@ METHOD(radius_socket_t, decrypt_msk, chunk_t,
private_radius_socket_t *this, radius_message_t *request,
radius_message_t *response)
{
- struct {
- u_int32_t id;
- u_int8_t type;
- u_int8_t length;
- u_int16_t salt;
- u_int8_t key[];
- } __attribute__((packed)) *mppe_key;
+ mppe_key_t *mppe_key;
enumerator_t *enumerator;
chunk_t data, send = chunk_empty, recv = chunk_empty;
int type;
@@ -276,14 +289,13 @@ METHOD(radius_socket_t, decrypt_msk, chunk_t,
enumerator = response->create_enumerator(response);
while (enumerator->enumerate(enumerator, &type, &data))
{
- if (type == RAT_VENDOR_SPECIFIC &&
- data.len > sizeof(*mppe_key))
+ if (type == RAT_VENDOR_SPECIFIC && data.len > sizeof(mppe_key_t))
{
- mppe_key = (void*)data.ptr;
- if (ntohl(mppe_key->id) == VENDOR_ID_MICROSOFT &&
+ mppe_key = (mppe_key_t*)data.ptr;
+ if (ntohl(mppe_key->id) == PEN_MICROSOFT &&
mppe_key->length == data.len - sizeof(mppe_key->id))
{
- data = chunk_create(mppe_key->key, data.len - sizeof(*mppe_key));
+ data = chunk_create(mppe_key->key, data.len - sizeof(mppe_key_t));
if (mppe_key->type == MS_MPPE_SEND_KEY)
{
send = decrypt_mppe_key(this, mppe_key->salt, data, request);
@@ -311,9 +323,13 @@ METHOD(radius_socket_t, destroy, void,
DESTROY_IF(this->hasher);
DESTROY_IF(this->signer);
DESTROY_IF(this->rng);
- if (this->fd != -1)
+ if (this->auth_fd != -1)
+ {
+ close(this->auth_fd);
+ };
+ if (this->acct_fd != -1)
{
- close(this->fd);
+ close(this->acct_fd);
}
free(this);
}
@@ -321,8 +337,8 @@ METHOD(radius_socket_t, destroy, void,
/**
* See header
*/
-radius_socket_t *radius_socket_create(char *address, u_int16_t port,
- chunk_t secret)
+radius_socket_t *radius_socket_create(char *address, u_int16_t auth_port,
+ u_int16_t acct_port, chunk_t secret)
{
private_radius_socket_t *this;
@@ -333,13 +349,15 @@ radius_socket_t *radius_socket_create(char *address, u_int16_t port,
.destroy = _destroy,
},
.address = address,
- .port = port,
- .fd = -1,
+ .auth_port = auth_port,
+ .auth_fd = -1,
+ .acct_port = acct_port,
+ .acct_fd = -1,
+ .hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5),
+ .signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_MD5_128),
+ .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
);
- this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
- this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_MD5_128);
- this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
if (!this->hasher || !this->signer || !this->rng)
{
DBG1(DBG_CFG, "RADIUS initialization failed, HMAC/MD5/RNG required");
diff --git a/src/libcharon/plugins/eap_radius/radius_socket.h b/src/libradius/radius_socket.h
index 2875008eb..07d642c08 100644
--- a/src/libcharon/plugins/eap_radius/radius_socket.h
+++ b/src/libradius/radius_socket.h
@@ -15,7 +15,7 @@
/**
* @defgroup radius_socket radius_socket
- * @{ @ingroup eap_radius
+ * @{ @ingroup libradius
*/
#ifndef RADIUS_SOCKET_H_
@@ -67,10 +67,11 @@ struct radius_socket_t {
* Create a radius_socket instance.
*
* @param address server name
- * @param port server port
+ * @param auth_port server port for authentication
+ * @param acct_port server port for accounting
* @param secret RADIUS secret
*/
-radius_socket_t *radius_socket_create(char *address, u_int16_t port,
- chunk_t secret);
+radius_socket_t *radius_socket_create(char *address, u_int16_t auth_port,
+ u_int16_t acct_port, chunk_t secret);
#endif /** RADIUS_SOCKET_H_ @}*/
diff --git a/src/libsimaka/Makefile.am b/src/libsimaka/Makefile.am
index 8e7a1f0d3..80d4fb814 100644
--- a/src/libsimaka/Makefile.am
+++ b/src/libsimaka/Makefile.am
@@ -1,6 +1,7 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra -I$(top_srcdir)/src/libcharon
-noinst_LTLIBRARIES = libsimaka.la
+ipseclib_LTLIBRARIES = libsimaka.la
libsimaka_la_SOURCES = simaka_message.h simaka_message.c \
- simaka_crypto.h simaka_crypto.c
+ simaka_crypto.h simaka_crypto.c simaka_manager.h simaka_manager.c \
+ simaka_card.h simaka_provider.h simaka_hooks.h
diff --git a/src/libsimaka/Makefile.in b/src/libsimaka/Makefile.in
index 30af27406..59919e559 100644
--- a/src/libsimaka/Makefile.in
+++ b/src/libsimaka/Makefile.in
@@ -51,9 +51,32 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-LTLIBRARIES = $(noinst_LTLIBRARIES)
+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)$(ipseclibdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
libsimaka_la_LIBADD =
-am_libsimaka_la_OBJECTS = simaka_message.lo simaka_crypto.lo
+am_libsimaka_la_OBJECTS = simaka_message.lo simaka_crypto.lo \
+ simaka_manager.lo
libsimaka_la_OBJECTS = $(am_libsimaka_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -164,6 +187,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -172,6 +198,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -188,11 +215,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -236,6 +265,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -247,9 +277,10 @@ 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
-noinst_LTLIBRARIES = libsimaka.la
+ipseclib_LTLIBRARIES = libsimaka.la
libsimaka_la_SOURCES = simaka_message.h simaka_message.c \
- simaka_crypto.h simaka_crypto.c
+ simaka_crypto.h simaka_crypto.c simaka_manager.h simaka_manager.c \
+ simaka_card.h simaka_provider.h simaka_hooks.h
all: all-am
@@ -285,17 +316,39 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
+ }
+
+uninstall-ipseclibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
+ done
-clean-noinstLTLIBRARIES:
- -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
- @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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
libsimaka.la: $(libsimaka_la_OBJECTS) $(libsimaka_la_DEPENDENCIES)
- $(LINK) $(libsimaka_la_OBJECTS) $(libsimaka_la_LIBADD) $(LIBS)
+ $(LINK) -rpath $(ipseclibdir) $(libsimaka_la_OBJECTS) $(libsimaka_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -304,6 +357,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simaka_crypto.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simaka_manager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simaka_message.Plo@am__quote@
.c.o:
@@ -419,6 +473,9 @@ check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
+ for dir in "$(DESTDIR)$(ipseclibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
@@ -446,7 +503,7 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
@@ -467,7 +524,7 @@ info: info-am
info-am:
-install-data-am:
+install-data-am: install-ipseclibLTLIBRARIES
install-dvi: install-dvi-am
@@ -513,22 +570,23 @@ ps: ps-am
ps-am:
-uninstall-am:
+uninstall-am: uninstall-ipseclibLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ clean-ipseclibLTLIBRARIES clean-libtool 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-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
+ install-html-am install-info install-info-am \
+ install-ipseclibLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-ipseclibLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/libcharon/sa/authenticators/eap/sim_card.h b/src/libsimaka/simaka_card.h
index 5f5dc580b..52cb32514 100644
--- a/src/libcharon/sa/authenticators/eap/sim_card.h
+++ b/src/libsimaka/simaka_card.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 Martin Willi
+ * Copyright (C) 2008-2011 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -14,14 +14,18 @@
*/
/**
- * @defgroup sim_card sim_card
- * @{ @ingroup eap
+ * @defgroup simaka_card simaka_card
+ * @{ @ingroup libsimaka
*/
-#ifndef SIM_CARD_H_
-#define SIM_CARD_H_
+#ifndef SIMAKA_CARD_H_
+#define SIMAKA_CARD_H_
-typedef struct sim_card_t sim_card_t;
+typedef struct simaka_card_t simaka_card_t;
+
+#include "simaka_manager.h"
+
+#include <utils/identification.h>
/**
* Interface for a (U)SIM card (used as EAP client).
@@ -31,7 +35,7 @@ typedef struct sim_card_t sim_card_t;
* An implementation supporting only one of SIM/AKA authentication may
* implement the other methods with return_false()/return NOT_SUPPORTED/NULL.
*/
-struct sim_card_t {
+struct simaka_card_t {
/**
* Calculate SRES/KC from a RAND for SIM authentication.
@@ -42,7 +46,7 @@ struct sim_card_t {
* @param kc KC output buffer, fixed size 8 bytes
* @return TRUE if SRES/KC calculated, FALSE on error/wrong identity
*/
- bool (*get_triplet)(sim_card_t *this, identification_t *id,
+ bool (*get_triplet)(simaka_card_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
char kc[SIM_KC_LEN]);
@@ -65,7 +69,7 @@ struct sim_card_t {
* @param res_len nubmer of bytes written to res buffer
* @return SUCCESS, FAILED, or INVALID_STATE if out of sync
*/
- status_t (*get_quintuplet)(sim_card_t *this, identification_t *id,
+ status_t (*get_quintuplet)(simaka_card_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN],
char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
char res[AKA_RES_MAX], int *res_len);
@@ -78,7 +82,7 @@ struct sim_card_t {
* @param auts resynchronization parameter auts
* @return TRUE if parameter generated successfully
*/
- bool (*resync)(sim_card_t *this, identification_t *id,
+ bool (*resync)(simaka_card_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
/**
@@ -87,7 +91,7 @@ struct sim_card_t {
* @param id permanent identity of the peer
* @param pseudonym pseudonym identity received from the server
*/
- void (*set_pseudonym)(sim_card_t *this, identification_t *id,
+ void (*set_pseudonym)(simaka_card_t *this, identification_t *id,
identification_t *pseudonym);
/**
@@ -96,7 +100,7 @@ struct sim_card_t {
* @param id permanent identity of the peer
* @return associated pseudonym identity, NULL if none stored
*/
- identification_t* (*get_pseudonym)(sim_card_t *this, identification_t *id);
+ identification_t* (*get_pseudonym)(simaka_card_t *this, identification_t *id);
/**
* Store parameters to use for the next fast reauthentication.
@@ -106,7 +110,7 @@ struct sim_card_t {
* @param mk master key MK to store for reauthentication
* @param counter counter value to store, host order
*/
- void (*set_reauth)(sim_card_t *this, identification_t *id,
+ void (*set_reauth)(simaka_card_t *this, identification_t *id,
identification_t *next, char mk[HASH_SIZE_SHA1],
u_int16_t counter);
@@ -118,8 +122,8 @@ struct sim_card_t {
* @param counter pointer receiving counter value, in host order
* @return fast reauthentication identity, NULL if not found
*/
- identification_t* (*get_reauth)(sim_card_t *this, identification_t *id,
+ identification_t* (*get_reauth)(simaka_card_t *this, identification_t *id,
char mk[HASH_SIZE_SHA1], u_int16_t *counter);
};
-#endif /** SIM_CARD_H_ @}*/
+#endif /** SIMAKA_CARD_H_ @}*/
diff --git a/src/libsimaka/simaka_crypto.c b/src/libsimaka/simaka_crypto.c
index b85502012..4819d1b99 100644
--- a/src/libsimaka/simaka_crypto.c
+++ b/src/libsimaka/simaka_crypto.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Martin Willi
+ * Copyright (C) 2009-2011 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,7 +15,9 @@
#include "simaka_crypto.h"
-#include <daemon.h>
+#include "simaka_manager.h"
+
+#include <debug.h>
/** length of the k_encr key */
#define KENCR_LEN 16
@@ -39,6 +41,11 @@ struct private_simaka_crypto_t {
simaka_crypto_t public;
/**
+ * EAP type this crypto is used, SIM or AKA
+ */
+ eap_type_t type;
+
+ /**
* signer to create/verify AT_MAC
*/
signer_t *signer;
@@ -69,35 +76,48 @@ struct private_simaka_crypto_t {
bool derived;
};
-/**
- * Implementation of simaka_crypto_t.get_signer
- */
-static signer_t* get_signer(private_simaka_crypto_t *this)
+METHOD(simaka_crypto_t, get_signer, signer_t*,
+ private_simaka_crypto_t *this)
{
return this->derived ? this->signer : NULL;
}
-/**
- * Implementation of simaka_crypto_t.get_crypter
- */
-static crypter_t* get_crypter(private_simaka_crypto_t *this)
+METHOD(simaka_crypto_t, get_crypter, crypter_t*,
+ private_simaka_crypto_t *this)
{
return this->derived ? this->crypter : NULL;
}
-/**
- * Implementation of simaka_crypto_t.get_rng
- */
-static rng_t* get_rng(private_simaka_crypto_t *this)
+METHOD(simaka_crypto_t, get_rng, rng_t*,
+ private_simaka_crypto_t *this)
{
return this->rng;
}
/**
- * Implementation of simaka_crypto_t.derive_keys_full
+ * Call SIM/AKA key hook
*/
-static chunk_t derive_keys_full(private_simaka_crypto_t *this,
- identification_t *id, chunk_t data, chunk_t *mk)
+static void call_hook(private_simaka_crypto_t *this, chunk_t encr, chunk_t auth)
+{
+ simaka_manager_t *mgr;
+
+ switch (this->type)
+ {
+ case EAP_SIM:
+ mgr = lib->get(lib, "sim-manager");
+ break;
+ case EAP_AKA:
+ mgr = lib->get(lib, "aka-manager");
+ break;
+ default:
+ return;
+ }
+ mgr->key_hook(mgr, encr, auth);
+}
+
+METHOD(simaka_crypto_t, derive_keys_full, chunk_t,
+ private_simaka_crypto_t *this, identification_t *id,
+ chunk_t data, chunk_t *mk)
{
chunk_t str, msk, k_encr, k_auth;
int i;
@@ -106,7 +126,7 @@ static chunk_t derive_keys_full(private_simaka_crypto_t *this,
* For AKA: MK = SHA1(Identity|IK|CK) */
this->hasher->get_hash(this->hasher, id->get_encoding(id), NULL);
this->hasher->allocate_hash(this->hasher, data, mk);
- DBG3(DBG_IKE, "MK %B", mk);
+ DBG3(DBG_LIB, "MK %B", mk);
/* K_encr | K_auth | MSK | EMSK = prf() | prf() | prf() | prf() */
this->prf->set_key(this->prf, *mk);
@@ -119,21 +139,19 @@ static chunk_t derive_keys_full(private_simaka_crypto_t *this,
k_encr = chunk_create(str.ptr, KENCR_LEN);
k_auth = chunk_create(str.ptr + KENCR_LEN, KAUTH_LEN);
msk = chunk_create(str.ptr + KENCR_LEN + KAUTH_LEN, MSK_LEN);
- DBG3(DBG_IKE, "K_encr %B\nK_auth %B\nMSK %B", &k_encr, &k_auth, &msk);
+ DBG3(DBG_LIB, "K_encr %B\nK_auth %B\nMSK %B", &k_encr, &k_auth, &msk);
this->signer->set_key(this->signer, k_auth);
this->crypter->set_key(this->crypter, k_encr);
- charon->sim->key_hook(charon->sim, k_encr, k_auth);
+ call_hook(this, k_encr, k_auth);
this->derived = TRUE;
return chunk_clone(msk);
}
-/**
- * Implementation of simaka_crypto_t.derive_keys_reauth
- */
-static void derive_keys_reauth(private_simaka_crypto_t *this, chunk_t mk)
+METHOD(simaka_crypto_t, derive_keys_reauth, void,
+ private_simaka_crypto_t *this, chunk_t mk)
{
chunk_t str, k_encr, k_auth;
int i;
@@ -147,22 +165,19 @@ static void derive_keys_reauth(private_simaka_crypto_t *this, chunk_t mk)
}
k_encr = chunk_create(str.ptr, KENCR_LEN);
k_auth = chunk_create(str.ptr + KENCR_LEN, KAUTH_LEN);
- DBG3(DBG_IKE, "K_encr %B\nK_auth %B", &k_encr, &k_auth);
+ DBG3(DBG_LIB, "K_encr %B\nK_auth %B", &k_encr, &k_auth);
this->signer->set_key(this->signer, k_auth);
this->crypter->set_key(this->crypter, k_encr);
- charon->sim->key_hook(charon->sim, k_encr, k_auth);
+ call_hook(this, k_encr, k_auth);
this->derived = TRUE;
}
-/**
- * Implementation of simaka_crypto_t.derive_keys_reauth_msk
- */
-static chunk_t derive_keys_reauth_msk(private_simaka_crypto_t *this,
- identification_t *id, chunk_t counter,
- chunk_t nonce_s, chunk_t mk)
+METHOD(simaka_crypto_t, derive_keys_reauth_msk, chunk_t,
+ private_simaka_crypto_t *this, identification_t *id, chunk_t counter,
+ chunk_t nonce_s, chunk_t mk)
{
char xkey[HASH_SIZE_SHA1];
chunk_t str, msk;
@@ -181,23 +196,19 @@ static chunk_t derive_keys_reauth_msk(private_simaka_crypto_t *this,
this->prf->get_bytes(this->prf, chunk_empty, str.ptr + str.len / 2 * i);
}
msk = chunk_create(str.ptr, MSK_LEN);
- DBG3(DBG_IKE, "MSK %B", &msk);
+ DBG3(DBG_LIB, "MSK %B", &msk);
return chunk_clone(msk);
}
-/**
- * Implementation of simaka_crypto_t.clear_keys
- */
-static void clear_keys(private_simaka_crypto_t *this)
+METHOD(simaka_crypto_t, clear_keys, void,
+ private_simaka_crypto_t *this)
{
this->derived = FALSE;
}
-/**
- * Implementation of simaka_crypto_t.destroy.
- */
-static void destroy(private_simaka_crypto_t *this)
+METHOD(simaka_crypto_t, destroy, void,
+ private_simaka_crypto_t *this)
{
DESTROY_IF(this->rng);
DESTROY_IF(this->hasher);
@@ -210,32 +221,35 @@ static void destroy(private_simaka_crypto_t *this)
/**
* See header
*/
-simaka_crypto_t *simaka_crypto_create()
+simaka_crypto_t *simaka_crypto_create(eap_type_t type)
{
- private_simaka_crypto_t *this = malloc_thing(private_simaka_crypto_t);
-
- this->public.get_signer = (signer_t*(*)(simaka_crypto_t*))get_signer;
- this->public.get_crypter = (crypter_t*(*)(simaka_crypto_t*))get_crypter;
- this->public.get_rng = (rng_t*(*)(simaka_crypto_t*))get_rng;
- this->public.derive_keys_full = (chunk_t(*)(simaka_crypto_t*, identification_t *id, chunk_t data, chunk_t *mk))derive_keys_full;
- this->public.derive_keys_reauth = (void(*)(simaka_crypto_t*, chunk_t mk))derive_keys_reauth;
- this->public.derive_keys_reauth_msk = (chunk_t(*)(simaka_crypto_t*, identification_t *id, chunk_t counter, chunk_t nonce_s, chunk_t mk))derive_keys_reauth_msk;
- this->public.clear_keys = (void(*)(simaka_crypto_t*))clear_keys;
- this->public.destroy = (void(*)(simaka_crypto_t*))destroy;
-
- this->derived = FALSE;
- this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- this->prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160);
- this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA1_128);
- this->crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, 16);
+ private_simaka_crypto_t *this;
+
+ INIT(this,
+ .public = {
+ .get_signer = _get_signer,
+ .get_crypter = _get_crypter,
+ .get_rng = _get_rng,
+ .derive_keys_full = _derive_keys_full,
+ .derive_keys_reauth = _derive_keys_reauth,
+ .derive_keys_reauth_msk = _derive_keys_reauth_msk,
+ .clear_keys = _clear_keys,
+ .destroy = _destroy,
+ },
+ .type = type,
+ .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK),
+ .hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1),
+ .prf = lib->crypto->create_prf(lib->crypto, PRF_FIPS_SHA1_160),
+ .signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_SHA1_128),
+ .crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, 16),
+ );
if (!this->rng || !this->hasher || !this->prf ||
!this->signer || !this->crypter)
{
- DBG1(DBG_IKE, "unable to use EAP-SIM, missing algorithms");
+ DBG1(DBG_LIB, "unable to use %N, missing algorithms",
+ eap_type_names, type);
destroy(this);
return NULL;
}
return &this->public;
}
-
diff --git a/src/libcharon/sa/authenticators/eap/sim_hooks.h b/src/libsimaka/simaka_hooks.h
index 0a675e4ab..ffe1c25b6 100644
--- a/src/libcharon/sa/authenticators/eap/sim_hooks.h
+++ b/src/libsimaka/simaka_hooks.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 Martin Willi
+ * Copyright (C) 2008-2011 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -14,19 +14,21 @@
*/
/**
- * @defgroup sim_hooks sim_hooks
- * @{ @ingroup eap
+ * @defgroup simaka_hooks simaka_hooks
+ * @{ @ingroup libsimaka
*/
-#ifndef SIM_HOOKS_H_
-#define SIM_HOOKS_H_
+#ifndef SIMAKA_HOOKS_H_
+#define SIMAKA_HOOKS_H_
-typedef struct sim_hooks_t sim_hooks_t;
+typedef struct simaka_hooks_t simaka_hooks_t;
+
+#include "simaka_message.h"
/**
* Additional hooks invoked during EAP-SIM/AKA message processing.
*/
-struct sim_hooks_t {
+struct simaka_hooks_t {
/**
* SIM/AKA message parsing.
@@ -38,7 +40,7 @@ struct sim_hooks_t {
* @param inbound TRUE for incoming messages, FALSE for outgoing
* @param decrypted TRUE if AT_ENCR_DATA has been decrypted
*/
- void (*message)(sim_hooks_t *this, simaka_message_t *message,
+ void (*message)(simaka_hooks_t *this, simaka_message_t *message,
bool inbound, bool decrypted);
/**
@@ -47,7 +49,7 @@ struct sim_hooks_t {
* @param k_encr derived SIM/AKA encryption key k_encr
* @param k_auth derived SIM/AKA authentication key k_auth
*/
- void (*keys)(sim_hooks_t *this, chunk_t k_encr, chunk_t k_auth);
+ void (*keys)(simaka_hooks_t *this, chunk_t k_encr, chunk_t k_auth);
};
-#endif /** SIM_HOOKS_H_ @}*/
+#endif /** SIMAKA_HOOKS_H_ @}*/
diff --git a/src/libcharon/sa/authenticators/eap/sim_manager.c b/src/libsimaka/simaka_manager.c
index 9ccaf5298..65de1c5ab 100644
--- a/src/libcharon/sa/authenticators/eap/sim_manager.c
+++ b/src/libsimaka/simaka_manager.c
@@ -13,23 +13,23 @@
* for more details.
*/
-#include "sim_manager.h"
+#include "simaka_manager.h"
-#include <daemon.h>
+#include <debug.h>
#include <utils/linked_list.h>
#include <threading/rwlock.h>
-typedef struct private_sim_manager_t private_sim_manager_t;
+typedef struct private_simaka_manager_t private_simaka_manager_t;
/**
- * Private data of an sim_manager_t object.
+ * Private data of an simaka_manager_t object.
*/
-struct private_sim_manager_t {
+struct private_simaka_manager_t {
/**
- * Public sim_manager_t interface.
+ * Public simaka_manager_t interface.
*/
- sim_manager_t public;
+ simaka_manager_t public;
/**
* list of added cards
@@ -52,28 +52,36 @@ struct private_sim_manager_t {
rwlock_t *lock;
};
-METHOD(sim_manager_t, add_card, void,
- private_sim_manager_t *this, sim_card_t *card)
+/**
+ * Described in header.
+ */
+void libsimaka_init(void)
+{
+ /* empty */
+}
+
+METHOD(simaka_manager_t, add_card, void,
+ private_simaka_manager_t *this, simaka_card_t *card)
{
this->lock->write_lock(this->lock);
this->cards->insert_last(this->cards, card);
this->lock->unlock(this->lock);
}
-METHOD(sim_manager_t, remove_card, void,
- private_sim_manager_t *this, sim_card_t *card)
+METHOD(simaka_manager_t, remove_card, void,
+ private_simaka_manager_t *this, simaka_card_t *card)
{
this->lock->write_lock(this->lock);
this->cards->remove(this->cards, card, NULL);
this->lock->unlock(this->lock);
}
-METHOD(sim_manager_t, card_get_triplet, bool,
- private_sim_manager_t *this, identification_t *id,
+METHOD(simaka_manager_t, card_get_triplet, bool,
+ private_simaka_manager_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
enumerator_t *enumerator;
- sim_card_t *card;
+ simaka_card_t *card;
int tried = 0;
this->lock->read_lock(this->lock);
@@ -90,18 +98,18 @@ METHOD(sim_manager_t, card_get_triplet, bool,
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
- DBG1(DBG_IKE, "tried %d SIM cards, but none has triplets for '%Y'",
+ DBG1(DBG_LIB, "tried %d SIM cards, but none has triplets for '%Y'",
tried, id);
return FALSE;
}
-METHOD(sim_manager_t, card_get_quintuplet, status_t,
- private_sim_manager_t *this, identification_t *id, char rand[AKA_RAND_LEN],
+METHOD(simaka_manager_t, card_get_quintuplet, status_t,
+ private_simaka_manager_t *this, identification_t *id, char rand[AKA_RAND_LEN],
char autn[AKA_AUTN_LEN], char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
char res[AKA_RES_MAX], int *res_len)
{
enumerator_t *enumerator;
- sim_card_t *card;
+ simaka_card_t *card;
status_t status = NOT_FOUND;
int tried = 0;
@@ -126,17 +134,17 @@ METHOD(sim_manager_t, card_get_quintuplet, status_t,
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
- DBG1(DBG_IKE, "tried %d SIM cards, but none has quintuplets for '%Y'",
+ DBG1(DBG_LIB, "tried %d SIM cards, but none has quintuplets for '%Y'",
tried, id);
return status;
}
-METHOD(sim_manager_t, card_resync, bool,
- private_sim_manager_t *this, identification_t *id,
+METHOD(simaka_manager_t, card_resync, bool,
+ private_simaka_manager_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
{
enumerator_t *enumerator;
- sim_card_t *card;
+ simaka_card_t *card;
this->lock->read_lock(this->lock);
enumerator = this->cards->create_enumerator(this->cards);
@@ -154,14 +162,14 @@ METHOD(sim_manager_t, card_resync, bool,
return FALSE;
}
-METHOD(sim_manager_t, card_set_pseudonym, void,
- private_sim_manager_t *this, identification_t *id,
+METHOD(simaka_manager_t, card_set_pseudonym, void,
+ private_simaka_manager_t *this, identification_t *id,
identification_t *pseudonym)
{
enumerator_t *enumerator;
- sim_card_t *card;
+ simaka_card_t *card;
- DBG1(DBG_IKE, "storing pseudonym '%Y' for '%Y'", pseudonym, id);
+ DBG1(DBG_LIB, "storing pseudonym '%Y' for '%Y'", pseudonym, id);
this->lock->read_lock(this->lock);
enumerator = this->cards->create_enumerator(this->cards);
@@ -173,11 +181,11 @@ METHOD(sim_manager_t, card_set_pseudonym, void,
this->lock->unlock(this->lock);
}
-METHOD(sim_manager_t, card_get_pseudonym, identification_t*,
- private_sim_manager_t *this, identification_t *id)
+METHOD(simaka_manager_t, card_get_pseudonym, identification_t*,
+ private_simaka_manager_t *this, identification_t *id)
{
enumerator_t *enumerator;
- sim_card_t *card;
+ simaka_card_t *card;
identification_t *pseudonym = NULL;
this->lock->read_lock(this->lock);
@@ -187,7 +195,7 @@ METHOD(sim_manager_t, card_get_pseudonym, identification_t*,
pseudonym = card->get_pseudonym(card, id);
if (pseudonym)
{
- DBG1(DBG_IKE, "using stored pseudonym identity '%Y' "
+ DBG1(DBG_LIB, "using stored pseudonym identity '%Y' "
"instead of '%Y'", pseudonym, id);
break;
}
@@ -197,14 +205,14 @@ METHOD(sim_manager_t, card_get_pseudonym, identification_t*,
return pseudonym;
}
-METHOD(sim_manager_t, card_set_reauth, void,
- private_sim_manager_t *this, identification_t *id, identification_t *next,
+METHOD(simaka_manager_t, card_set_reauth, void,
+ private_simaka_manager_t *this, identification_t *id, identification_t *next,
char mk[HASH_SIZE_SHA1], u_int16_t counter)
{
enumerator_t *enumerator;
- sim_card_t *card;
+ simaka_card_t *card;
- DBG1(DBG_IKE, "storing next reauthentication identity '%Y' for '%Y'",
+ DBG1(DBG_LIB, "storing next reauthentication identity '%Y' for '%Y'",
next, id);
this->lock->read_lock(this->lock);
@@ -217,12 +225,12 @@ METHOD(sim_manager_t, card_set_reauth, void,
this->lock->unlock(this->lock);
}
-METHOD(sim_manager_t, card_get_reauth, identification_t*,
- private_sim_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1],
+METHOD(simaka_manager_t, card_get_reauth, identification_t*,
+ private_simaka_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1],
u_int16_t *counter)
{
enumerator_t *enumerator;
- sim_card_t *card;
+ simaka_card_t *card;
identification_t *reauth = NULL;
this->lock->read_lock(this->lock);
@@ -232,7 +240,7 @@ METHOD(sim_manager_t, card_get_reauth, identification_t*,
reauth = card->get_reauth(card, id, mk, counter);
if (reauth)
{
- DBG1(DBG_IKE, "using stored reauthentication identity '%Y' "
+ DBG1(DBG_LIB, "using stored reauthentication identity '%Y' "
"instead of '%Y'", reauth, id);
break;
}
@@ -242,28 +250,28 @@ METHOD(sim_manager_t, card_get_reauth, identification_t*,
return reauth;
}
-METHOD(sim_manager_t, add_provider, void,
- private_sim_manager_t *this, sim_provider_t *provider)
+METHOD(simaka_manager_t, add_provider, void,
+ private_simaka_manager_t *this, simaka_provider_t *provider)
{
this->lock->write_lock(this->lock);
this->providers->insert_last(this->providers, provider);
this->lock->unlock(this->lock);
}
-METHOD(sim_manager_t, remove_provider, void,
- private_sim_manager_t *this, sim_provider_t *provider)
+METHOD(simaka_manager_t, remove_provider, void,
+ private_simaka_manager_t *this, simaka_provider_t *provider)
{
this->lock->write_lock(this->lock);
this->providers->remove(this->providers, provider, NULL);
this->lock->unlock(this->lock);
}
-METHOD(sim_manager_t, provider_get_triplet, bool,
- private_sim_manager_t *this, identification_t *id, char rand[SIM_RAND_LEN],
- char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
+METHOD(simaka_manager_t, provider_get_triplet, bool,
+ private_simaka_manager_t *this, identification_t *id,
+ char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN], char kc[SIM_KC_LEN])
{
enumerator_t *enumerator;
- sim_provider_t *provider;
+ simaka_provider_t *provider;
int tried = 0;
this->lock->read_lock(this->lock);
@@ -280,18 +288,18 @@ METHOD(sim_manager_t, provider_get_triplet, bool,
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
- DBG1(DBG_IKE, "tried %d SIM providers, but none had a triplet for '%Y'",
+ DBG1(DBG_LIB, "tried %d SIM providers, but none had a triplet for '%Y'",
tried, id);
return FALSE;
}
-METHOD(sim_manager_t, provider_get_quintuplet, bool,
- private_sim_manager_t *this, identification_t *id, char rand[AKA_RAND_LEN],
- char xres[AKA_RES_MAX], int *xres_len, char ck[AKA_CK_LEN],
- char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN])
+METHOD(simaka_manager_t, provider_get_quintuplet, bool,
+ private_simaka_manager_t *this, identification_t *id,
+ char rand[AKA_RAND_LEN], char xres[AKA_RES_MAX], int *xres_len,
+ char ck[AKA_CK_LEN], char ik[AKA_IK_LEN], char autn[AKA_AUTN_LEN])
{
enumerator_t *enumerator;
- sim_provider_t *provider;
+ simaka_provider_t *provider;
int tried = 0;
this->lock->read_lock(this->lock);
@@ -308,17 +316,17 @@ METHOD(sim_manager_t, provider_get_quintuplet, bool,
}
enumerator->destroy(enumerator);
this->lock->unlock(this->lock);
- DBG1(DBG_IKE, "tried %d SIM providers, but none had a quintuplet for '%Y'",
+ DBG1(DBG_LIB, "tried %d SIM providers, but none had a quintuplet for '%Y'",
tried, id);
return FALSE;
}
-METHOD(sim_manager_t, provider_resync, bool,
- private_sim_manager_t *this, identification_t *id,
+METHOD(simaka_manager_t, provider_resync, bool,
+ private_simaka_manager_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN])
{
enumerator_t *enumerator;
- sim_provider_t *provider;
+ simaka_provider_t *provider;
this->lock->read_lock(this->lock);
enumerator = this->providers->create_enumerator(this->providers);
@@ -336,11 +344,11 @@ METHOD(sim_manager_t, provider_resync, bool,
return FALSE;
}
-METHOD(sim_manager_t, provider_is_pseudonym, identification_t*,
- private_sim_manager_t *this, identification_t *id)
+METHOD(simaka_manager_t, provider_is_pseudonym, identification_t*,
+ private_simaka_manager_t *this, identification_t *id)
{
enumerator_t *enumerator;
- sim_provider_t *provider;
+ simaka_provider_t *provider;
identification_t *permanent = NULL;
this->lock->read_lock(this->lock);
@@ -350,7 +358,7 @@ METHOD(sim_manager_t, provider_is_pseudonym, identification_t*,
permanent = provider->is_pseudonym(provider, id);
if (permanent)
{
- DBG1(DBG_IKE, "received pseudonym identity '%Y' "
+ DBG1(DBG_LIB, "received pseudonym identity '%Y' "
"mapping to '%Y'", id, permanent);
break;
}
@@ -360,11 +368,11 @@ METHOD(sim_manager_t, provider_is_pseudonym, identification_t*,
return permanent;
}
-METHOD(sim_manager_t, provider_gen_pseudonym, identification_t*,
- private_sim_manager_t *this, identification_t *id)
+METHOD(simaka_manager_t, provider_gen_pseudonym, identification_t*,
+ private_simaka_manager_t *this, identification_t *id)
{
enumerator_t *enumerator;
- sim_provider_t *provider;
+ simaka_provider_t *provider;
identification_t *pseudonym = NULL;
this->lock->read_lock(this->lock);
@@ -374,7 +382,7 @@ METHOD(sim_manager_t, provider_gen_pseudonym, identification_t*,
pseudonym = provider->gen_pseudonym(provider, id);
if (pseudonym)
{
- DBG1(DBG_IKE, "proposing new pseudonym '%Y'", pseudonym);
+ DBG1(DBG_LIB, "proposing new pseudonym '%Y'", pseudonym);
break;
}
}
@@ -383,12 +391,12 @@ METHOD(sim_manager_t, provider_gen_pseudonym, identification_t*,
return pseudonym;
}
-METHOD(sim_manager_t, provider_is_reauth, identification_t*,
- private_sim_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1],
+METHOD(simaka_manager_t, provider_is_reauth, identification_t*,
+ private_simaka_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1],
u_int16_t *counter)
{
enumerator_t *enumerator;
- sim_provider_t *provider;
+ simaka_provider_t *provider;
identification_t *permanent = NULL;
this->lock->read_lock(this->lock);
@@ -398,7 +406,7 @@ METHOD(sim_manager_t, provider_is_reauth, identification_t*,
permanent = provider->is_reauth(provider, id, mk, counter);
if (permanent)
{
- DBG1(DBG_IKE, "received reauthentication identity '%Y' "
+ DBG1(DBG_LIB, "received reauthentication identity '%Y' "
"mapping to '%Y'", id, permanent);
break;
}
@@ -408,11 +416,11 @@ METHOD(sim_manager_t, provider_is_reauth, identification_t*,
return permanent;
}
-METHOD(sim_manager_t, provider_gen_reauth, identification_t*,
- private_sim_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1])
+METHOD(simaka_manager_t, provider_gen_reauth, identification_t*,
+ private_simaka_manager_t *this, identification_t *id, char mk[HASH_SIZE_SHA1])
{
enumerator_t *enumerator;
- sim_provider_t *provider;
+ simaka_provider_t *provider;
identification_t *reauth = NULL;
this->lock->read_lock(this->lock);
@@ -422,7 +430,7 @@ METHOD(sim_manager_t, provider_gen_reauth, identification_t*,
reauth = provider->gen_reauth(provider, id, mk);
if (reauth)
{
- DBG1(DBG_IKE, "proposing new reauthentication identity '%Y'", reauth);
+ DBG1(DBG_LIB, "proposing new reauthentication identity '%Y'", reauth);
break;
}
}
@@ -431,28 +439,28 @@ METHOD(sim_manager_t, provider_gen_reauth, identification_t*,
return reauth;
}
-METHOD(sim_manager_t, add_hooks, void,
- private_sim_manager_t *this, sim_hooks_t *hooks)
+METHOD(simaka_manager_t, add_hooks, void,
+ private_simaka_manager_t *this, simaka_hooks_t *hooks)
{
this->lock->write_lock(this->lock);
this->hooks->insert_last(this->hooks, hooks);
this->lock->unlock(this->lock);
}
-METHOD(sim_manager_t, remove_hooks, void,
- private_sim_manager_t *this, sim_hooks_t *hooks)
+METHOD(simaka_manager_t, remove_hooks, void,
+ private_simaka_manager_t *this, simaka_hooks_t *hooks)
{
this->lock->write_lock(this->lock);
this->hooks->remove(this->hooks, hooks, NULL);
this->lock->unlock(this->lock);
}
-METHOD(sim_manager_t, message_hook, void,
- private_sim_manager_t *this, simaka_message_t *message,
+METHOD(simaka_manager_t, message_hook, void,
+ private_simaka_manager_t *this, simaka_message_t *message,
bool inbound, bool decrypted)
{
enumerator_t *enumerator;
- sim_hooks_t *hooks;
+ simaka_hooks_t *hooks;
this->lock->read_lock(this->lock);
enumerator = this->hooks->create_enumerator(this->hooks);
@@ -464,11 +472,11 @@ METHOD(sim_manager_t, message_hook, void,
this->lock->unlock(this->lock);
}
-METHOD(sim_manager_t, key_hook, void,
- private_sim_manager_t *this, chunk_t k_encr, chunk_t k_auth)
+METHOD(simaka_manager_t, key_hook, void,
+ private_simaka_manager_t *this, chunk_t k_encr, chunk_t k_auth)
{
enumerator_t *enumerator;
- sim_hooks_t *hooks;
+ simaka_hooks_t *hooks;
this->lock->read_lock(this->lock);
enumerator = this->hooks->create_enumerator(this->hooks);
@@ -480,8 +488,8 @@ METHOD(sim_manager_t, key_hook, void,
this->lock->unlock(this->lock);
}
-METHOD(sim_manager_t, destroy, void,
- private_sim_manager_t *this)
+METHOD(simaka_manager_t, destroy, void,
+ private_simaka_manager_t *this)
{
this->cards->destroy(this->cards);
this->providers->destroy(this->providers);
@@ -493,9 +501,9 @@ METHOD(sim_manager_t, destroy, void,
/**
* See header
*/
-sim_manager_t *sim_manager_create()
+simaka_manager_t *simaka_manager_create()
{
- private_sim_manager_t *this;
+ private_simaka_manager_t *this;
INIT(this,
.public = {
@@ -532,3 +540,87 @@ sim_manager_t *sim_manager_create()
return &this->public;
}
+/**
+ * (Un-)register a provider to a simaka manager
+ */
+static bool register_card(char *mgr_name, bool reg, simaka_card_t *card)
+{
+ simaka_manager_t *mgr;
+
+ if (!card)
+ {
+ return FALSE;
+ }
+ mgr = lib->get(lib, mgr_name);
+ if (mgr)
+ {
+ if (reg)
+ {
+ mgr->add_card(mgr, card);
+ }
+ else
+ {
+ mgr->remove_card(mgr, card);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * (Un-)register a provider to a simaka manager
+ */
+static bool register_provider(char *mgr_name, bool reg,
+ simaka_provider_t *provider)
+{
+ simaka_manager_t *mgr;
+
+ if (!provider)
+ {
+ return FALSE;
+ }
+ mgr = lib->get(lib, mgr_name);
+ if (mgr)
+ {
+ if (reg)
+ {
+ mgr->add_provider(mgr, provider);
+ }
+ else
+ {
+ mgr->remove_provider(mgr, provider);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ * See header
+ */
+bool simaka_manager_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data)
+{
+ simaka_manager_register_cb_t get = (simaka_manager_register_cb_t)data;
+
+ if (feature->type == FEATURE_CUSTOM)
+ {
+ if (streq(feature->arg.custom, "aka-card"))
+ {
+ return register_card("aka-manager", reg, get(plugin));
+ }
+ else if (streq(feature->arg.custom, "aka-provider"))
+ {
+ return register_provider("aka-manager", reg, get(plugin));
+ }
+ else if (streq(feature->arg.custom, "sim-card"))
+ {
+ return register_card("sim-manager", reg, get(plugin));
+ }
+ else if (streq(feature->arg.custom, "sim-provider"))
+ {
+ return register_provider("sim-manager", reg, get(plugin));
+ }
+ }
+ return FALSE;
+}
diff --git a/src/libcharon/sa/authenticators/eap/sim_manager.h b/src/libsimaka/simaka_manager.h
index db4a65011..64a67e56c 100644
--- a/src/libcharon/sa/authenticators/eap/sim_manager.h
+++ b/src/libsimaka/simaka_manager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 Martin Willi
+ * Copyright (C) 2008-2011 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -14,22 +14,19 @@
*/
/**
- * @defgroup sim_manager sim_manager
- * @{ @ingroup eap
+ * @defgroup simaka_manager simaka_manager
+ * @{ @ingroup libsimaka
*/
-#ifndef SIM_MANAGER_H_
-#define SIM_MANAGER_H_
+#ifndef SIMAKA_MANAGER_H_
+#define SIMAKA_MANAGER_H_
#include <crypto/hashers/hasher.h>
#include <utils/identification.h>
#include <utils/enumerator.h>
-#include <sa/authenticators/eap/eap_method.h>
+#include <plugins/plugin.h>
-typedef struct sim_manager_t sim_manager_t;
-
-/** implemented in libsimaka, but we need it for the message hook */
-typedef struct simaka_message_t simaka_message_t;
+typedef struct simaka_manager_t simaka_manager_t;
#define SIM_RAND_LEN 16
#define SIM_SRES_LEN 4
@@ -42,28 +39,28 @@ typedef struct simaka_message_t simaka_message_t;
#define AKA_AUTN_LEN 16
#define AKA_AUTS_LEN 14
-#include <sa/authenticators/eap/sim_card.h>
-#include <sa/authenticators/eap/sim_provider.h>
-#include <sa/authenticators/eap/sim_hooks.h>
+#include "simaka_card.h"
+#include "simaka_provider.h"
+#include "simaka_hooks.h"
/**
* The SIM manager handles multiple (U)SIM cards/providers and hooks.
*/
-struct sim_manager_t {
+struct simaka_manager_t {
/**
* Register a SIM card (client) at the manager.
*
* @param card sim card to register
*/
- void (*add_card)(sim_manager_t *this, sim_card_t *card);
+ void (*add_card)(simaka_manager_t *this, simaka_card_t *card);
/**
* Unregister a previously registered card from the manager.
*
* @param card sim card to unregister
*/
- void (*remove_card)(sim_manager_t *this, sim_card_t *card);
+ void (*remove_card)(simaka_manager_t *this, simaka_card_t *card);
/**
* Calculate SIM triplets on one of the registered SIM cards.
@@ -74,7 +71,7 @@ struct sim_manager_t {
* @param kc KC output buffer, fixed size 8 bytes
* @return TRUE if calculated, FALSE if no matching card found
*/
- bool (*card_get_triplet)(sim_manager_t *this, identification_t *id,
+ bool (*card_get_triplet)(simaka_manager_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
char kc[SIM_KC_LEN]);
@@ -90,7 +87,7 @@ struct sim_manager_t {
* @param res_len nubmer of bytes written to res buffer
* @return SUCCESS, FAILED, or INVALID_STATE if out of sync
*/
- status_t (*card_get_quintuplet)(sim_manager_t *this, identification_t *id,
+ status_t (*card_get_quintuplet)(simaka_manager_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN],
char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
char res[AKA_RES_MAX], int *res_len);
@@ -103,7 +100,7 @@ struct sim_manager_t {
* @param auts resynchronization parameter auts
* @return TRUE if calculated, FALSE if no matcing card found
*/
- bool (*card_resync)(sim_manager_t *this, identification_t *id,
+ bool (*card_resync)(simaka_manager_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
/**
@@ -112,16 +109,16 @@ struct sim_manager_t {
* @param id permanent identity of the peer
* @param pseudonym pseudonym identity received from the server
*/
- void (*card_set_pseudonym)(sim_manager_t *this, identification_t *id,
+ void (*card_set_pseudonym)(simaka_manager_t *this, identification_t *id,
identification_t *pseudonym);
/**
- * Get a stored pseudonym from one of the registerd SIM cards.
+ * Get a stored pseudonym from one of the registered SIM cards.
*
* @param id permanent identity of the peer
* @return associated pseudonym identity, NULL if none found
*/
- identification_t* (*card_get_pseudonym)(sim_manager_t *this,
+ identification_t* (*card_get_pseudonym)(simaka_manager_t *this,
identification_t *id);
/**
@@ -132,19 +129,19 @@ struct sim_manager_t {
* @param mk master key MK to store for reauthentication
* @param counter counter value to store, host order
*/
- void (*card_set_reauth)(sim_manager_t *this, identification_t *id,
+ void (*card_set_reauth)(simaka_manager_t *this, identification_t *id,
identification_t *next, char mk[HASH_SIZE_SHA1],
u_int16_t counter);
/**
- * Retrieve fast reauthentication parameters from one of the registerd cards.
+ * Retrieve fast reauthentication parameters from one of the registered cards.
*
* @param id permanent identity of the peer
* @param mk buffer receiving master key MK
* @param counter pointer receiving counter value, in host order
* @return fast reauthentication identity, NULL if none found
*/
- identification_t* (*card_get_reauth)(sim_manager_t *this,
+ identification_t* (*card_get_reauth)(simaka_manager_t *this,
identification_t *id, char mk[HASH_SIZE_SHA1],
u_int16_t *counter);
@@ -153,14 +150,14 @@ struct sim_manager_t {
*
* @param card sim card to register
*/
- void (*add_provider)(sim_manager_t *this, sim_provider_t *provider);
+ void (*add_provider)(simaka_manager_t *this, simaka_provider_t *provider);
/**
* Unregister a previously registered provider from the manager.
*
* @param card sim card to unregister
*/
- void (*remove_provider)(sim_manager_t *this, sim_provider_t *provider);
+ void (*remove_provider)(simaka_manager_t *this, simaka_provider_t *provider);
/**
* Get a SIM triplet from one of the registered providers.
@@ -171,7 +168,7 @@ struct sim_manager_t {
* @param kc KC output buffer, fixed size 8 bytes
* @return TRUE if triplet received, FALSE if no match found
*/
- bool (*provider_get_triplet)(sim_manager_t *this, identification_t *id,
+ bool (*provider_get_triplet)(simaka_manager_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
char kc[SIM_KC_LEN]);
@@ -186,7 +183,7 @@ struct sim_manager_t {
* @param autn authentication token autn
* @return TRUE if quintuplet received, FALSE if no match found
*/
- bool (*provider_get_quintuplet)(sim_manager_t *this, identification_t *id,
+ bool (*provider_get_quintuplet)(simaka_manager_t *this, identification_t *id,
char rand[AKA_RAND_LEN],
char xres[AKA_RES_MAX], int *xres_len,
char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
@@ -200,7 +197,7 @@ struct sim_manager_t {
* @param auts synchronization parameter auts
* @return TRUE if resynchronized, FALSE if not handled
*/
- bool (*provider_resync)(sim_manager_t *this, identification_t *id,
+ bool (*provider_resync)(simaka_manager_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
/**
@@ -209,7 +206,7 @@ struct sim_manager_t {
* @param id pseudonym identity candidate
* @return permanent identity, NULL if id not a pseudonym
*/
- identification_t* (*provider_is_pseudonym)(sim_manager_t *this,
+ identification_t* (*provider_is_pseudonym)(simaka_manager_t *this,
identification_t *id);
/**
@@ -218,7 +215,7 @@ struct sim_manager_t {
* @param id permanent identity to generate a pseudonym for
* @return generated pseudonym, NULL to not use a pseudonym identity
*/
- identification_t* (*provider_gen_pseudonym)(sim_manager_t *this,
+ identification_t* (*provider_gen_pseudonym)(simaka_manager_t *this,
identification_t *id);
/**
@@ -229,7 +226,7 @@ struct sim_manager_t {
* @param counter pointer receiving current counter value, host order
* @return permanent identity, NULL if not a known reauth identity
*/
- identification_t* (*provider_is_reauth)(sim_manager_t *this,
+ identification_t* (*provider_is_reauth)(simaka_manager_t *this,
identification_t *id, char mk[HASH_SIZE_SHA1],
u_int16_t *counter);
@@ -240,7 +237,7 @@ struct sim_manager_t {
* @param mk master key to store along with generated identity
* @return fast reauthentication identity, NULL to not use reauth
*/
- identification_t* (*provider_gen_reauth)(sim_manager_t *this,
+ identification_t* (*provider_gen_reauth)(simaka_manager_t *this,
identification_t *id, char mk[HASH_SIZE_SHA1]);
/**
@@ -248,14 +245,14 @@ struct sim_manager_t {
*
* @param hooks hook interface implementation to register
*/
- void (*add_hooks)(sim_manager_t *this, sim_hooks_t *hooks);
+ void (*add_hooks)(simaka_manager_t *this, simaka_hooks_t *hooks);
/**
* Unregister a set of hooks from the manager.
*
* @param hooks hook interface implementation to unregister
*/
- void (*remove_hooks)(sim_manager_t *this, sim_hooks_t *hooks);
+ void (*remove_hooks)(simaka_manager_t *this, simaka_hooks_t *hooks);
/**
* Invoke SIM/AKA message hook.
@@ -264,7 +261,7 @@ struct sim_manager_t {
* @param inbound TRUE for incoming messages, FALSE for outgoing
* @param decrypted TRUE if AT_ENCR_DATA has been decrypted
*/
- void (*message_hook)(sim_manager_t *this, simaka_message_t *message,
+ void (*message_hook)(simaka_manager_t *this, simaka_message_t *message,
bool inbound, bool decrypted);
/**
@@ -273,19 +270,46 @@ struct sim_manager_t {
* @param k_encr SIM/AKA encryption key k_encr
* @param k_auth SIM/AKA authentication key k_auth
*/
- void (*key_hook)(sim_manager_t *this, chunk_t k_encr, chunk_t k_auth);
+ void (*key_hook)(simaka_manager_t *this, chunk_t k_encr, chunk_t k_auth);
/**
* Destroy a manager instance.
*/
- void (*destroy)(sim_manager_t *this);
+ void (*destroy)(simaka_manager_t *this);
};
/**
- * Create an SIM manager to handle multiple (U)SIM cards/providers.
+ * Dummy libsimaka initialization function needed for integrity test
+ */
+void libsimaka_init(void);
+
+/**
+ * Create an SIM/AKA manager to handle multiple (U)SIM cards/providers.
+ *
+ * @return simaka_t object
+ */
+simaka_manager_t *simaka_manager_create();
+
+/**
+ * Callback for the simaka_manager_register_cb_t, provides backend to register.
+ *
+ * @param plugin plugin registering a backend (card or provider)
+ * @return a simaka_card_t* or simaka_provider_t*, NULL on failure
+ */
+typedef void* (*simaka_manager_register_cb_t)(plugin_t *plugin);
+
+/**
+ * Helper function to (un-)register SIM/AKA backend plugin features.
+ *
+ * This function is a plugin_feature_callback_t and can be used with the
+ * PLUGIN_CALLBACK macro to register a SIM/AKA backend.
*
- * @return sim_t object
+ * @param plugin plugin registering the SIM/AKA backend
+ * @param feature associated plugin feature
+ * @param reg TRUE to register, FALSE to unregister.
+ * @param data data passed to callback, an simaka_manager_register_cb_t
*/
-sim_manager_t *sim_manager_create();
+bool simaka_manager_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data);
-#endif /** SIM_MANAGER_H_ @}*/
+#endif /** SIMAKA_MANAGER_H_ @}*/
diff --git a/src/libsimaka/simaka_message.c b/src/libsimaka/simaka_message.c
index 3a8f4beaf..a5754b985 100644
--- a/src/libsimaka/simaka_message.c
+++ b/src/libsimaka/simaka_message.c
@@ -15,6 +15,11 @@
#include "simaka_message.h"
+#include "simaka_manager.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+
typedef struct private_simaka_message_t private_simaka_message_t;
typedef struct hdr_t hdr_t;
typedef struct attr_hdr_t attr_hdr_t;
@@ -134,9 +139,9 @@ ENUM(simaka_client_error_names, SIM_UNABLE_TO_PROCESS, SIM_RANDS_NOT_FRESH,
*/
bool simaka_attribute_skippable(simaka_attribute_t attribute)
{
- bool skippable = !(attribute >= 0 && attribute <= 127);
+ bool skippable = !((int)attribute >= 0 && attribute <= 127);
- DBG1(DBG_IKE, "%sskippable EAP-SIM/AKA attribute %N",
+ DBG1(DBG_LIB, "%sskippable EAP-SIM/AKA attribute %N",
skippable ? "ignoring " : "found non-",
simaka_attribute_names, attribute);
return skippable;
@@ -193,34 +198,26 @@ struct private_simaka_message_t {
chunk_t iv;
};
-/**
- * Implementation of simaka_message_t.is_request
- */
-static bool is_request(private_simaka_message_t *this)
+METHOD(simaka_message_t, is_request, bool,
+ private_simaka_message_t *this)
{
return this->hdr->code == EAP_REQUEST;
}
-/**
- * Implementation of simaka_message_t.get_identifier
- */
-static u_int8_t get_identifier(private_simaka_message_t *this)
+METHOD(simaka_message_t, get_identifier, u_int8_t,
+ private_simaka_message_t *this)
{
return this->hdr->identifier;
}
-/**
- * Implementation of simaka_message_t.get_subtype
- */
-static simaka_subtype_t get_subtype(private_simaka_message_t *this)
+METHOD(simaka_message_t, get_subtype, simaka_subtype_t,
+ private_simaka_message_t *this)
{
return this->hdr->subtype;
}
-/**
- * Implementation of simaka_message_t.get_type
- */
-static eap_type_t get_type(private_simaka_message_t *this)
+METHOD(simaka_message_t, get_type, eap_type_t,
+ private_simaka_message_t *this)
{
return this->hdr->type;
}
@@ -238,21 +235,16 @@ static bool attr_enum_filter(void *null, attr_t **in, simaka_attribute_t *type,
return TRUE;
}
-/**
- * Implementation of simaka_message_t.create_attribute_enumerator
- */
-static enumerator_t* create_attribute_enumerator(private_simaka_message_t *this)
+METHOD(simaka_message_t, create_attribute_enumerator, enumerator_t*,
+ private_simaka_message_t *this)
{
return enumerator_create_filter(
this->attributes->create_enumerator(this->attributes),
(void*)attr_enum_filter, NULL, NULL);
}
-/**
- * Implementation of simaka_message_t.add_attribute
- */
-static void add_attribute(private_simaka_message_t *this,
- simaka_attribute_t type, chunk_t data)
+METHOD(simaka_message_t, add_attribute, void,
+ private_simaka_message_t *this, simaka_attribute_t type, chunk_t data)
{
attr_t *attr;
@@ -269,7 +261,7 @@ static void add_attribute(private_simaka_message_t *this,
*/
static bool not_encrypted(simaka_attribute_t type)
{
- DBG1(DBG_IKE, "received unencrypted %N", simaka_attribute_names, type);
+ DBG1(DBG_LIB, "received unencrypted %N", simaka_attribute_names, type);
return FALSE;
}
@@ -278,11 +270,33 @@ static bool not_encrypted(simaka_attribute_t type)
*/
static bool invalid_length(simaka_attribute_t type)
{
- DBG1(DBG_IKE, "invalid length of %N", simaka_attribute_names, type);
+ DBG1(DBG_LIB, "invalid length of %N", simaka_attribute_names, type);
return FALSE;
}
/**
+ * Call SIM/AKA message hooks
+ */
+static void call_hook(private_simaka_message_t *this,
+ bool inbound, bool decrypted)
+{
+ simaka_manager_t *mgr;
+
+ switch (this->hdr->type)
+ {
+ case EAP_SIM:
+ mgr = lib->get(lib, "sim-manager");
+ break;
+ case EAP_AKA:
+ mgr = lib->get(lib, "aka-manager");
+ break;
+ default:
+ return;
+ }
+ mgr->message_hook(mgr, &this->public, inbound, decrypted);
+}
+
+/**
* Parse attributes from a chunk of data
*/
static bool parse_attributes(private_simaka_message_t *this, chunk_t in)
@@ -294,7 +308,7 @@ static bool parse_attributes(private_simaka_message_t *this, chunk_t in)
if (in.len < sizeof(attr_hdr_t))
{
- DBG1(DBG_IKE, "found short %N attribute header",
+ DBG1(DBG_LIB, "found short %N attribute header",
eap_type_names, this->hdr->type);
return FALSE;
}
@@ -450,7 +464,7 @@ static bool parse_attributes(private_simaka_message_t *this, chunk_t in)
}
else if (!this->encrypted)
{
- DBG1(DBG_IKE, "found P-bit 0 notify in unencrypted message");
+ DBG1(DBG_LIB, "found P-bit 0 notify in unencrypted message");
return FALSE;
}
/* FALL */
@@ -460,7 +474,7 @@ static bool parse_attributes(private_simaka_message_t *this, chunk_t in)
}
}
- charon->sim->message_hook(charon->sim, &this->public, TRUE, this->encrypted);
+ call_hook(this, TRUE, this->encrypted);
return TRUE;
}
@@ -481,7 +495,7 @@ static bool decrypt(private_simaka_message_t *this)
}
if (this->encr.len % crypter->get_block_size(crypter))
{
- DBG1(DBG_IKE, "%N ENCR_DATA not a multiple of block size",
+ DBG1(DBG_LIB, "%N ENCR_DATA not a multiple of block size",
eap_type_names, this->hdr->type);
return FALSE;
}
@@ -495,10 +509,8 @@ static bool decrypt(private_simaka_message_t *this)
return success;
}
-/**
- * Implementation of simaka_message_t.parse
- */
-static bool parse(private_simaka_message_t *this)
+METHOD(simaka_message_t, parse, bool,
+ private_simaka_message_t *this)
{
chunk_t in;
@@ -516,10 +528,8 @@ static bool parse(private_simaka_message_t *this)
return decrypt(this);
}
-/**
- * Implementation of simaka_message_t.verify
- */
-static bool verify(private_simaka_message_t *this, chunk_t sigdata)
+METHOD(simaka_message_t, verify, bool,
+ private_simaka_message_t *this, chunk_t sigdata)
{
chunk_t data, backup;
signer_t *signer;
@@ -543,7 +553,7 @@ static bool verify(private_simaka_message_t *this, chunk_t sigdata)
{
if (!this->mac.ptr || !signer)
{ /* require MAC, but not found */
- DBG1(DBG_IKE, "%N message requires a MAC, but none found",
+ DBG1(DBG_LIB, "%N message requires a MAC, but none found",
simaka_subtype_names, this->hdr->subtype);
return FALSE;
}
@@ -558,7 +568,7 @@ static bool verify(private_simaka_message_t *this, chunk_t sigdata)
}
if (!this->mac.ptr || !signer)
{
- DBG1(DBG_IKE, "%N message has a phase 0 notify, but "
+ DBG1(DBG_LIB, "%N message has a phase 0 notify, but "
"no MAC found", simaka_subtype_names, this->hdr->subtype);
return FALSE;
}
@@ -566,7 +576,7 @@ static bool verify(private_simaka_message_t *this, chunk_t sigdata)
}
default:
/* unknown message? */
- DBG1(DBG_IKE, "signature rule for %N messages missing",
+ DBG1(DBG_LIB, "signature rule for %N messages missing",
simaka_subtype_names, this->hdr->subtype);
return FALSE;
}
@@ -582,17 +592,15 @@ static bool verify(private_simaka_message_t *this, chunk_t sigdata)
}
if (!signer->verify_signature(signer, data, backup))
{
- DBG1(DBG_IKE, "%N MAC verification failed",
+ DBG1(DBG_LIB, "%N MAC verification failed",
eap_type_names, this->hdr->type);
return FALSE;
}
return TRUE;
}
-/**
- * Implementation of simaka_message_t.generate
- */
-static eap_payload_t* generate(private_simaka_message_t *this, chunk_t sigdata)
+METHOD(simaka_message_t, generate, chunk_t,
+ private_simaka_message_t *this, chunk_t sigdata)
{
/* buffers large enough for messages we generate */
char out_buf[1024], encr_buf[512];
@@ -603,7 +611,7 @@ static eap_payload_t* generate(private_simaka_message_t *this, chunk_t sigdata)
u_int16_t len;
signer_t *signer;
- charon->sim->message_hook(charon->sim, &this->public, FALSE, TRUE);
+ call_hook(this, FALSE, TRUE);
out = chunk_create(out_buf, sizeof(out_buf));
encr = chunk_create(encr_buf, sizeof(encr_buf));
@@ -723,7 +731,7 @@ static eap_payload_t* generate(private_simaka_message_t *this, chunk_t sigdata)
}
default:
{
- DBG1(DBG_IKE, "no rule to encode %N, skipped",
+ DBG1(DBG_LIB, "no rule to encode %N, skipped",
simaka_attribute_names, type);
break;
}
@@ -817,15 +825,13 @@ static eap_payload_t* generate(private_simaka_message_t *this, chunk_t sigdata)
signer->get_signature(signer, data, mac.ptr);
}
- charon->sim->message_hook(charon->sim, &this->public, FALSE, FALSE);
+ call_hook(this, FALSE, FALSE);
- return eap_payload_create_data(out);
+ return chunk_clone(out);
}
-/**
- * Implementation of simaka_message_t.destroy.
- */
-static void destroy(private_simaka_message_t *this)
+METHOD(simaka_message_t, destroy, void,
+ private_simaka_message_t *this)
{
this->attributes->destroy_function(this->attributes, free);
free(this->hdr);
@@ -843,43 +849,40 @@ static simaka_message_t *simaka_message_create_data(chunk_t data,
if (data.len < sizeof(hdr_t) || hdr->length != htons(data.len))
{
- DBG1(DBG_IKE, "EAP-SIM/AKA header has invalid length");
+ DBG1(DBG_LIB, "EAP-SIM/AKA header has invalid length");
return NULL;
}
if (hdr->code != EAP_REQUEST && hdr->code != EAP_RESPONSE)
{
- DBG1(DBG_IKE, "invalid EAP code in EAP-SIM/AKA message",
+ DBG1(DBG_LIB, "invalid EAP code in EAP-SIM/AKA message",
eap_type_names, hdr->type);
return NULL;
}
if (hdr->type != EAP_SIM && hdr->type != EAP_AKA)
{
- DBG1(DBG_IKE, "invalid EAP type in EAP-SIM/AKA message",
+ DBG1(DBG_LIB, "invalid EAP type in EAP-SIM/AKA message",
eap_type_names, hdr->type);
return NULL;
}
- this = malloc_thing(private_simaka_message_t);
-
- this->public.is_request = (bool(*)(simaka_message_t*))is_request;
- this->public.get_identifier = (u_int8_t(*)(simaka_message_t*))get_identifier;
- this->public.get_type = (eap_type_t(*)(simaka_message_t*))get_type;
- this->public.get_subtype = (simaka_subtype_t(*)(simaka_message_t*))get_subtype;
- this->public.create_attribute_enumerator = (enumerator_t*(*)(simaka_message_t*))create_attribute_enumerator;
- this->public.add_attribute = (void(*)(simaka_message_t*, simaka_attribute_t type, chunk_t data))add_attribute;
- this->public.parse = (bool(*)(simaka_message_t*))parse;
- this->public.verify = (bool(*)(simaka_message_t*, chunk_t sigdata))verify;
- this->public.generate = (eap_payload_t*(*)(simaka_message_t*, chunk_t sigdata))generate;
- this->public.destroy = (void(*)(simaka_message_t*))destroy;
-
- this->attributes = linked_list_create();
- this->encrypted = FALSE;
- this->crypto = crypto;
- this->p_bit = TRUE;
- this->mac = chunk_empty;
- this->encr = chunk_empty;
- this->iv = chunk_empty;
- this->hdr = malloc(data.len);
+ INIT(this,
+ .public = {
+ .is_request = _is_request,
+ .get_identifier = _get_identifier,
+ .get_type = _get_type,
+ .get_subtype = _get_subtype,
+ .create_attribute_enumerator = _create_attribute_enumerator,
+ .add_attribute = _add_attribute,
+ .parse = _parse,
+ .verify = _verify,
+ .generate = _generate,
+ .destroy = _destroy,
+ },
+ .attributes = linked_list_create(),
+ .crypto = crypto,
+ .p_bit = TRUE,
+ .hdr = malloc(data.len),
+ );
memcpy(this->hdr, hdr, data.len);
return &this->public;
@@ -888,10 +891,10 @@ static simaka_message_t *simaka_message_create_data(chunk_t data,
/**
* See header.
*/
-simaka_message_t *simaka_message_create_from_payload(eap_payload_t *payload,
+simaka_message_t *simaka_message_create_from_payload(chunk_t data,
simaka_crypto_t *crypto)
{
- return simaka_message_create_data(payload->get_data(payload), crypto);
+ return simaka_message_create_data(data, crypto);
}
/**
diff --git a/src/libsimaka/simaka_message.h b/src/libsimaka/simaka_message.h
index 341f72959..28fe21823 100644
--- a/src/libsimaka/simaka_message.h
+++ b/src/libsimaka/simaka_message.h
@@ -27,7 +27,7 @@
#define SIMAKA_MESSAGE_H_
#include <enum.h>
-#include <daemon.h>
+#include <eap/eap.h>
#include "simaka_crypto.h"
@@ -35,6 +35,7 @@ typedef enum simaka_attribute_t simaka_attribute_t;
typedef enum simaka_subtype_t simaka_subtype_t;
typedef enum simaka_notification_t simaka_notification_t;
typedef enum simaka_client_error_t simaka_client_error_t;
+typedef struct simaka_message_t simaka_message_t;
/**
* Subtypes of EAP-SIM/AKA messages
@@ -235,9 +236,9 @@ struct simaka_message_t {
* Generate a message, optionally encrypt attributes and create a MAC.
*
* @param sigdata additional data to include in signature, if any
- * @return generated eap payload, NULL if failed
+ * @return allocated data of generated message
*/
- eap_payload_t* (*generate)(simaka_message_t *this, chunk_t sigdata);
+ chunk_t (*generate)(simaka_message_t *this, chunk_t sigdata);
/**
* Destroy a simaka_message_t.
@@ -262,11 +263,11 @@ simaka_message_t *simaka_message_create(bool request, u_int8_t identifier,
/**
* Create an simaka_message from a chunk of data.
*
- * @param payload payload to create message from
+ * @param data message data to parse
* @param crypto EAP-SIM/AKA crypto helper
* @return EAP message, NULL on error
*/
-simaka_message_t *simaka_message_create_from_payload(eap_payload_t *payload,
+simaka_message_t *simaka_message_create_from_payload(chunk_t data,
simaka_crypto_t *crypto);
#endif /** SIMAKA_MESSAGE_H_ @}*/
diff --git a/src/libcharon/sa/authenticators/eap/sim_provider.h b/src/libsimaka/simaka_provider.h
index 191e094db..f1bf80049 100644
--- a/src/libcharon/sa/authenticators/eap/sim_provider.h
+++ b/src/libsimaka/simaka_provider.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 Martin Willi
+ * Copyright (C) 2008-2011 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -14,14 +14,18 @@
*/
/**
- * @defgroup sim_provider sim_provider
- * @{ @ingroup eap
+ * @defgroup simaka_provider simaka_provider
+ * @{ @ingroup libsimaka
*/
-#ifndef SIM_PROVIDER_H_
-#define SIM_PROVIDER_H_
+#ifndef SIMAKA_PROVIDER_H_
+#define SIMAKA_PROVIDER_H_
-typedef struct sim_provider_t sim_provider_t;
+typedef struct simaka_provider_t simaka_provider_t;
+
+#include "simaka_manager.h"
+
+#include <utils/identification.h>
/**
* Interface for a triplet/quintuplet provider (used as EAP server).
@@ -32,7 +36,7 @@ typedef struct sim_provider_t sim_provider_t;
* An implementation supporting only one of SIM/AKA authentication may
* implement the other methods with return_false().
*/
-struct sim_provider_t {
+struct simaka_provider_t {
/**
* Create a challenge for SIM authentication.
@@ -43,7 +47,7 @@ struct sim_provider_t {
* @param kc KC output buffer, fixed size 8 bytes
* @return TRUE if triplet received, FALSE otherwise
*/
- bool (*get_triplet)(sim_provider_t *this, identification_t *id,
+ bool (*get_triplet)(simaka_provider_t *this, identification_t *id,
char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
char kc[SIM_KC_LEN]);
@@ -64,7 +68,7 @@ struct sim_provider_t {
* @param autn authentication token autn
* @return TRUE if quintuplet generated successfully
*/
- bool (*get_quintuplet)(sim_provider_t *this, identification_t *id,
+ bool (*get_quintuplet)(simaka_provider_t *this, identification_t *id,
char rand[AKA_RAND_LEN],
char xres[AKA_RES_MAX], int *xres_len,
char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
@@ -78,7 +82,7 @@ struct sim_provider_t {
* @param auts synchronization parameter auts
* @return TRUE if resynchronized successfully
*/
- bool (*resync)(sim_provider_t *this, identification_t *id,
+ bool (*resync)(simaka_provider_t *this, identification_t *id,
char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
/**
@@ -87,7 +91,7 @@ struct sim_provider_t {
* @param id pseudonym identity candidate
* @return permanent identity, NULL if id not a pseudonym
*/
- identification_t* (*is_pseudonym)(sim_provider_t *this,
+ identification_t* (*is_pseudonym)(simaka_provider_t *this,
identification_t *id);
/**
@@ -96,7 +100,7 @@ struct sim_provider_t {
* @param id permanent identity to generate a pseudonym for
* @return generated pseudonym, NULL to not use a pseudonym identity
*/
- identification_t* (*gen_pseudonym)(sim_provider_t *this,
+ identification_t* (*gen_pseudonym)(simaka_provider_t *this,
identification_t *id);
/**
@@ -107,7 +111,7 @@ struct sim_provider_t {
* @param counter pointer receiving current counter value, host order
* @return permanent identity, NULL if id not a reauth identity
*/
- identification_t* (*is_reauth)(sim_provider_t *this, identification_t *id,
+ identification_t* (*is_reauth)(simaka_provider_t *this, identification_t *id,
char mk[HASH_SIZE_SHA1], u_int16_t *counter);
/**
@@ -117,8 +121,8 @@ struct sim_provider_t {
* @param mk master key to store along with generated identity
* @return fast reauthentication identity, NULL to not use reauth
*/
- identification_t* (*gen_reauth)(sim_provider_t *this, identification_t *id,
+ identification_t* (*gen_reauth)(simaka_provider_t *this, identification_t *id,
char mk[HASH_SIZE_SHA1]);
};
-#endif /** SIM_CARD_H_ @}*/
+#endif /** SIMAKA_CARD_H_ @}*/
diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk
index 259f0a375..d33bee6c7 100644
--- a/src/libstrongswan/Android.mk
+++ b/src/libstrongswan/Android.mk
@@ -12,6 +12,7 @@ printf_hook.c printf_hook.h \
asn1/asn1.c asn1/asn1.h \
asn1/asn1_parser.c asn1/asn1_parser.h \
asn1/oid.c asn1/oid.h \
+bio/bio_reader.h bio/bio_reader.c bio/bio_writer.h bio/bio_writer.c \
crypto/crypters/crypter.c crypto/crypters/crypter.h \
crypto/hashers/hasher.h crypto/hashers/hasher.c \
crypto/pkcs9.c crypto/pkcs9.h \
@@ -46,12 +47,14 @@ credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
credentials/sets/mem_cred.c credentials/sets/mem_cred.h \
credentials/sets/callback_cred.c credentials/sets/callback_cred.h \
credentials/auth_cfg.c credentials/auth_cfg.h credentials/credential_set.h \
-credentials/cert_validator.h \
-database/database.h database/database_factory.h database/database_factory.c \
+credentials/cert_validator.h database/database.h database/database.c \
+database/database_factory.h database/database_factory.c \
fetcher/fetcher.h fetcher/fetcher.c fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
eap/eap.h eap/eap.c \
+pen/pen.h pen/pen.c \
plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h \
-processing/jobs/job.h \
+plugins/plugin_feature.c plugins/plugin_feature.h \
+processing/jobs/job.h processing/jobs/job.c \
processing/jobs/callback_job.c processing/jobs/callback_job.h \
processing/processor.c processing/processor.h \
processing/scheduler.c processing/scheduler.h \
@@ -64,7 +67,6 @@ threading/lock_profiler.h \
utils.h utils.c \
utils/host.c utils/host.h \
utils/identification.c utils/identification.h \
-utils/iterator.h \
utils/lexparser.c utils/lexparser.h \
utils/linked_list.c utils/linked_list.h \
utils/hashtable.c utils/hashtable.h \
@@ -102,6 +104,8 @@ LOCAL_SRC_FILES += $(call add_plugin, pem)
LOCAL_SRC_FILES += $(call add_plugin, pkcs1)
+LOCAL_SRC_FILES += $(call add_plugin, pkcs11)
+
LOCAL_SRC_FILES += $(call add_plugin, pubkey)
LOCAL_SRC_FILES += $(call add_plugin, random)
@@ -124,6 +128,8 @@ LOCAL_CFLAGS := $(strongswan_CFLAGS) \
LOCAL_MODULE := libstrongswan
+LOCAL_MODULE_TAGS := optional
+
LOCAL_ARM_MODE := arm
LOCAL_PRELINK_MODULE := false
diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am
index b6c70daea..7bb0812bd 100644
--- a/src/libstrongswan/Makefile.am
+++ b/src/libstrongswan/Makefile.am
@@ -1,4 +1,4 @@
-lib_LTLIBRARIES = libstrongswan.la
+ipseclib_LTLIBRARIES = libstrongswan.la
libstrongswan_la_SOURCES = \
library.c library.h \
@@ -10,6 +10,7 @@ printf_hook.c printf_hook.h \
asn1/asn1.c asn1/asn1.h \
asn1/asn1_parser.c asn1/asn1_parser.h \
asn1/oid.c asn1/oid.h \
+bio/bio_reader.h bio/bio_reader.c bio/bio_writer.h bio/bio_writer.c \
crypto/crypters/crypter.c crypto/crypters/crypter.h \
crypto/hashers/hasher.h crypto/hashers/hasher.c \
crypto/pkcs9.c crypto/pkcs9.h \
@@ -44,12 +45,14 @@ credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
credentials/sets/mem_cred.c credentials/sets/mem_cred.h \
credentials/sets/callback_cred.c credentials/sets/callback_cred.h \
credentials/auth_cfg.c credentials/auth_cfg.h credentials/credential_set.h \
-credentials/cert_validator.h \
-database/database.h database/database_factory.h database/database_factory.c \
+credentials/cert_validator.h database/database.h database/database.c \
+database/database_factory.h database/database_factory.c \
fetcher/fetcher.h fetcher/fetcher.c fetcher/fetcher_manager.h fetcher/fetcher_manager.c \
eap/eap.h eap/eap.c \
+pen/pen.h pen/pen.c \
plugins/plugin_loader.c plugins/plugin_loader.h plugins/plugin.h \
-processing/jobs/job.h \
+plugins/plugin_feature.c plugins/plugin_feature.h \
+processing/jobs/job.h processing/jobs/job.c \
processing/jobs/callback_job.c processing/jobs/callback_job.h \
processing/processor.c processing/processor.h \
processing/scheduler.c processing/scheduler.h \
@@ -62,7 +65,6 @@ threading/lock_profiler.h \
utils.h utils.c \
utils/host.c utils/host.h \
utils/identification.c utils/identification.h \
-utils/iterator.h \
utils/lexparser.c utils/lexparser.h \
utils/linked_list.c utils/linked_list.h \
utils/hashtable.c utils/hashtable.h \
@@ -78,6 +80,7 @@ libstrongswan_la_LIBADD = $(PTHREADLIB) $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB)
INCLUDES = -I$(top_srcdir)/src/libstrongswan
AM_CFLAGS = \
-DIPSEC_DIR=\"${ipsecdir}\" \
+-DIPSEC_LIB_DIR=\"${ipseclibdir}\" \
-DPLUGINDIR=\"${plugindir}\" \
-DSTRONGSWAN_CONF=\"${strongswan_conf}\"
@@ -212,6 +215,13 @@ if MONOLITHIC
endif
endif
+if USE_CMAC
+ SUBDIRS += plugins/cmac
+if MONOLITHIC
+ libstrongswan_la_LIBADD += plugins/cmac/libstrongswan-cmac.la
+endif
+endif
+
if USE_XCBC
SUBDIRS += plugins/xcbc
if MONOLITHIC
@@ -254,6 +264,13 @@ if MONOLITHIC
endif
endif
+if USE_PKCS8
+ SUBDIRS += plugins/pkcs8
+if MONOLITHIC
+ libstrongswan_la_LIBADD += plugins/pkcs8/libstrongswan-pkcs8.la
+endif
+endif
+
if USE_PGP
SUBDIRS += plugins/pgp
if MONOLITHIC
diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in
index c9ae8992e..68c83a5aa 100644
--- a/src/libstrongswan/Makefile.in
+++ b/src/libstrongswan/Makefile.in
@@ -66,54 +66,58 @@ host_triplet = @host@
@MONOLITHIC_TRUE@@USE_RANDOM_TRUE@am__append_26 = plugins/random/libstrongswan-random.la
@USE_HMAC_TRUE@am__append_27 = plugins/hmac
@MONOLITHIC_TRUE@@USE_HMAC_TRUE@am__append_28 = plugins/hmac/libstrongswan-hmac.la
-@USE_XCBC_TRUE@am__append_29 = plugins/xcbc
-@MONOLITHIC_TRUE@@USE_XCBC_TRUE@am__append_30 = plugins/xcbc/libstrongswan-xcbc.la
-@USE_X509_TRUE@am__append_31 = plugins/x509
-@MONOLITHIC_TRUE@@USE_X509_TRUE@am__append_32 = plugins/x509/libstrongswan-x509.la
-@USE_REVOCATION_TRUE@am__append_33 = plugins/revocation
-@MONOLITHIC_TRUE@@USE_REVOCATION_TRUE@am__append_34 = plugins/revocation/libstrongswan-revocation.la
-@USE_CONSTRAINTS_TRUE@am__append_35 = plugins/constraints
-@MONOLITHIC_TRUE@@USE_CONSTRAINTS_TRUE@am__append_36 = plugins/constraints/libstrongswan-constraints.la
-@USE_PUBKEY_TRUE@am__append_37 = plugins/pubkey
-@MONOLITHIC_TRUE@@USE_PUBKEY_TRUE@am__append_38 = plugins/pubkey/libstrongswan-pubkey.la
-@USE_PKCS1_TRUE@am__append_39 = plugins/pkcs1
-@MONOLITHIC_TRUE@@USE_PKCS1_TRUE@am__append_40 = plugins/pkcs1/libstrongswan-pkcs1.la
-@USE_PGP_TRUE@am__append_41 = plugins/pgp
-@MONOLITHIC_TRUE@@USE_PGP_TRUE@am__append_42 = plugins/pgp/libstrongswan-pgp.la
-@USE_DNSKEY_TRUE@am__append_43 = plugins/dnskey
-@MONOLITHIC_TRUE@@USE_DNSKEY_TRUE@am__append_44 = plugins/dnskey/libstrongswan-dnskey.la
-@USE_PEM_TRUE@am__append_45 = plugins/pem
-@MONOLITHIC_TRUE@@USE_PEM_TRUE@am__append_46 = plugins/pem/libstrongswan-pem.la
-@USE_CURL_TRUE@am__append_47 = plugins/curl
-@MONOLITHIC_TRUE@@USE_CURL_TRUE@am__append_48 = plugins/curl/libstrongswan-curl.la
-@USE_SOUP_TRUE@am__append_49 = plugins/soup
-@MONOLITHIC_TRUE@@USE_SOUP_TRUE@am__append_50 = plugins/soup/libstrongswan-soup.la
-@USE_LDAP_TRUE@am__append_51 = plugins/ldap
-@MONOLITHIC_TRUE@@USE_LDAP_TRUE@am__append_52 = plugins/ldap/libstrongswan-ldap.la
-@USE_MYSQL_TRUE@am__append_53 = plugins/mysql
-@MONOLITHIC_TRUE@@USE_MYSQL_TRUE@am__append_54 = plugins/mysql/libstrongswan-mysql.la
-@USE_SQLITE_TRUE@am__append_55 = plugins/sqlite
-@MONOLITHIC_TRUE@@USE_SQLITE_TRUE@am__append_56 = plugins/sqlite/libstrongswan-sqlite.la
-@USE_PADLOCK_TRUE@am__append_57 = plugins/padlock
-@MONOLITHIC_TRUE@@USE_PADLOCK_TRUE@am__append_58 = plugins/padlock/libstrongswan-padlock.la
-@USE_OPENSSL_TRUE@am__append_59 = plugins/openssl
-@MONOLITHIC_TRUE@@USE_OPENSSL_TRUE@am__append_60 = plugins/openssl/libstrongswan-openssl.la
-@USE_GCRYPT_TRUE@am__append_61 = plugins/gcrypt
-@MONOLITHIC_TRUE@@USE_GCRYPT_TRUE@am__append_62 = plugins/gcrypt/libstrongswan-gcrypt.la
-@USE_FIPS_PRF_TRUE@am__append_63 = plugins/fips_prf
-@MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE@am__append_64 = plugins/fips_prf/libstrongswan-fips-prf.la
-@USE_AGENT_TRUE@am__append_65 = plugins/agent
-@MONOLITHIC_TRUE@@USE_AGENT_TRUE@am__append_66 = plugins/agent/libstrongswan-agent.la
-@USE_PKCS11_TRUE@am__append_67 = plugins/pkcs11
-@MONOLITHIC_TRUE@@USE_PKCS11_TRUE@am__append_68 = plugins/pkcs11/libstrongswan-pkcs11.la
-@USE_CTR_TRUE@am__append_69 = plugins/ctr
-@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_70 = plugins/ctr/libstrongswan-ctr.la
-@USE_CCM_TRUE@am__append_71 = plugins/ccm
-@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_72 = plugins/ccm/libstrongswan-ccm.la
-@USE_GCM_TRUE@am__append_73 = plugins/gcm
-@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_74 = plugins/gcm/libstrongswan-gcm.la
-@USE_TEST_VECTORS_TRUE@am__append_75 = plugins/test_vectors
-@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_76 = plugins/test_vectors/libstrongswan-test-vectors.la
+@USE_CMAC_TRUE@am__append_29 = plugins/cmac
+@MONOLITHIC_TRUE@@USE_CMAC_TRUE@am__append_30 = plugins/cmac/libstrongswan-cmac.la
+@USE_XCBC_TRUE@am__append_31 = plugins/xcbc
+@MONOLITHIC_TRUE@@USE_XCBC_TRUE@am__append_32 = plugins/xcbc/libstrongswan-xcbc.la
+@USE_X509_TRUE@am__append_33 = plugins/x509
+@MONOLITHIC_TRUE@@USE_X509_TRUE@am__append_34 = plugins/x509/libstrongswan-x509.la
+@USE_REVOCATION_TRUE@am__append_35 = plugins/revocation
+@MONOLITHIC_TRUE@@USE_REVOCATION_TRUE@am__append_36 = plugins/revocation/libstrongswan-revocation.la
+@USE_CONSTRAINTS_TRUE@am__append_37 = plugins/constraints
+@MONOLITHIC_TRUE@@USE_CONSTRAINTS_TRUE@am__append_38 = plugins/constraints/libstrongswan-constraints.la
+@USE_PUBKEY_TRUE@am__append_39 = plugins/pubkey
+@MONOLITHIC_TRUE@@USE_PUBKEY_TRUE@am__append_40 = plugins/pubkey/libstrongswan-pubkey.la
+@USE_PKCS1_TRUE@am__append_41 = plugins/pkcs1
+@MONOLITHIC_TRUE@@USE_PKCS1_TRUE@am__append_42 = plugins/pkcs1/libstrongswan-pkcs1.la
+@USE_PKCS8_TRUE@am__append_43 = plugins/pkcs8
+@MONOLITHIC_TRUE@@USE_PKCS8_TRUE@am__append_44 = plugins/pkcs8/libstrongswan-pkcs8.la
+@USE_PGP_TRUE@am__append_45 = plugins/pgp
+@MONOLITHIC_TRUE@@USE_PGP_TRUE@am__append_46 = plugins/pgp/libstrongswan-pgp.la
+@USE_DNSKEY_TRUE@am__append_47 = plugins/dnskey
+@MONOLITHIC_TRUE@@USE_DNSKEY_TRUE@am__append_48 = plugins/dnskey/libstrongswan-dnskey.la
+@USE_PEM_TRUE@am__append_49 = plugins/pem
+@MONOLITHIC_TRUE@@USE_PEM_TRUE@am__append_50 = plugins/pem/libstrongswan-pem.la
+@USE_CURL_TRUE@am__append_51 = plugins/curl
+@MONOLITHIC_TRUE@@USE_CURL_TRUE@am__append_52 = plugins/curl/libstrongswan-curl.la
+@USE_SOUP_TRUE@am__append_53 = plugins/soup
+@MONOLITHIC_TRUE@@USE_SOUP_TRUE@am__append_54 = plugins/soup/libstrongswan-soup.la
+@USE_LDAP_TRUE@am__append_55 = plugins/ldap
+@MONOLITHIC_TRUE@@USE_LDAP_TRUE@am__append_56 = plugins/ldap/libstrongswan-ldap.la
+@USE_MYSQL_TRUE@am__append_57 = plugins/mysql
+@MONOLITHIC_TRUE@@USE_MYSQL_TRUE@am__append_58 = plugins/mysql/libstrongswan-mysql.la
+@USE_SQLITE_TRUE@am__append_59 = plugins/sqlite
+@MONOLITHIC_TRUE@@USE_SQLITE_TRUE@am__append_60 = plugins/sqlite/libstrongswan-sqlite.la
+@USE_PADLOCK_TRUE@am__append_61 = plugins/padlock
+@MONOLITHIC_TRUE@@USE_PADLOCK_TRUE@am__append_62 = plugins/padlock/libstrongswan-padlock.la
+@USE_OPENSSL_TRUE@am__append_63 = plugins/openssl
+@MONOLITHIC_TRUE@@USE_OPENSSL_TRUE@am__append_64 = plugins/openssl/libstrongswan-openssl.la
+@USE_GCRYPT_TRUE@am__append_65 = plugins/gcrypt
+@MONOLITHIC_TRUE@@USE_GCRYPT_TRUE@am__append_66 = plugins/gcrypt/libstrongswan-gcrypt.la
+@USE_FIPS_PRF_TRUE@am__append_67 = plugins/fips_prf
+@MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE@am__append_68 = plugins/fips_prf/libstrongswan-fips-prf.la
+@USE_AGENT_TRUE@am__append_69 = plugins/agent
+@MONOLITHIC_TRUE@@USE_AGENT_TRUE@am__append_70 = plugins/agent/libstrongswan-agent.la
+@USE_PKCS11_TRUE@am__append_71 = plugins/pkcs11
+@MONOLITHIC_TRUE@@USE_PKCS11_TRUE@am__append_72 = plugins/pkcs11/libstrongswan-pkcs11.la
+@USE_CTR_TRUE@am__append_73 = plugins/ctr
+@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_74 = plugins/ctr/libstrongswan-ctr.la
+@USE_CCM_TRUE@am__append_75 = plugins/ccm
+@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_76 = plugins/ccm/libstrongswan-ccm.la
+@USE_GCM_TRUE@am__append_77 = plugins/gcm
+@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_78 = plugins/gcm/libstrongswan-gcm.la
+@USE_TEST_VECTORS_TRUE@am__append_79 = plugins/test_vectors
+@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_80 = plugins/test_vectors/libstrongswan-test-vectors.la
subdir = src/libstrongswan
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -152,8 +156,8 @@ am__nobase_list = $(am__nobase_strip_setup); \
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)$(libdir)"
-LTLIBRARIES = $(lib_LTLIBRARIES)
+am__installdirs = "$(DESTDIR)$(ipseclibdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
am__DEPENDENCIES_1 =
libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
@@ -169,14 +173,17 @@ libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
$(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_72) $(am__append_74) $(am__append_76) \
+ $(am__append_78) $(am__append_80)
am__libstrongswan_la_SOURCES_DIST = library.c library.h chunk.c \
chunk.h debug.c debug.h enum.c enum.h settings.h settings.c \
printf_hook.c printf_hook.h asn1/asn1.c asn1/asn1.h \
asn1/asn1_parser.c asn1/asn1_parser.h asn1/oid.c asn1/oid.h \
- crypto/crypters/crypter.c crypto/crypters/crypter.h \
- crypto/hashers/hasher.h crypto/hashers/hasher.c crypto/pkcs9.c \
- crypto/pkcs9.h crypto/proposal/proposal_keywords.c \
+ bio/bio_reader.h bio/bio_reader.c bio/bio_writer.h \
+ bio/bio_writer.c crypto/crypters/crypter.c \
+ crypto/crypters/crypter.h crypto/hashers/hasher.h \
+ crypto/hashers/hasher.c crypto/pkcs9.c crypto/pkcs9.h \
+ crypto/proposal/proposal_keywords.c \
crypto/proposal/proposal_keywords.h crypto/prfs/prf.c \
crypto/prfs/prf.h crypto/rngs/rng.c crypto/rngs/rng.h \
crypto/prf_plus.h crypto/prf_plus.c crypto/signers/signer.c \
@@ -215,45 +222,48 @@ am__libstrongswan_la_SOURCES_DIST = library.c library.h chunk.c \
credentials/sets/callback_cred.h credentials/auth_cfg.c \
credentials/auth_cfg.h credentials/credential_set.h \
credentials/cert_validator.h database/database.h \
- database/database_factory.h database/database_factory.c \
- fetcher/fetcher.h fetcher/fetcher.c fetcher/fetcher_manager.h \
- fetcher/fetcher_manager.c eap/eap.h eap/eap.c \
- plugins/plugin_loader.c plugins/plugin_loader.h \
- plugins/plugin.h processing/jobs/job.h \
- processing/jobs/callback_job.c processing/jobs/callback_job.h \
- processing/processor.c processing/processor.h \
- processing/scheduler.c processing/scheduler.h \
- selectors/traffic_selector.c selectors/traffic_selector.h \
- threading/thread.h threading/thread.c threading/thread_value.h \
+ database/database.c database/database_factory.h \
+ database/database_factory.c fetcher/fetcher.h \
+ fetcher/fetcher.c fetcher/fetcher_manager.h \
+ fetcher/fetcher_manager.c eap/eap.h eap/eap.c pen/pen.h \
+ pen/pen.c plugins/plugin_loader.c plugins/plugin_loader.h \
+ plugins/plugin.h plugins/plugin_feature.c \
+ plugins/plugin_feature.h processing/jobs/job.h \
+ processing/jobs/job.c processing/jobs/callback_job.c \
+ processing/jobs/callback_job.h processing/processor.c \
+ processing/processor.h processing/scheduler.c \
+ processing/scheduler.h selectors/traffic_selector.c \
+ selectors/traffic_selector.h threading/thread.h \
+ threading/thread.c threading/thread_value.h \
threading/thread_value.c threading/mutex.h threading/mutex.c \
threading/condvar.h threading/rwlock.h threading/rwlock.c \
threading/lock_profiler.h utils.h utils.c utils/host.c \
utils/host.h utils/identification.c utils/identification.h \
- utils/iterator.h utils/lexparser.c utils/lexparser.h \
- utils/linked_list.c utils/linked_list.h utils/hashtable.c \
- utils/hashtable.h utils/enumerator.c utils/enumerator.h \
- utils/optionsfrom.c utils/optionsfrom.h utils/backtrace.c \
- utils/backtrace.h utils/leak_detective.c \
- utils/leak_detective.h integrity_checker.c integrity_checker.h
+ utils/lexparser.c utils/lexparser.h utils/linked_list.c \
+ utils/linked_list.h utils/hashtable.c utils/hashtable.h \
+ utils/enumerator.c utils/enumerator.h utils/optionsfrom.c \
+ utils/optionsfrom.h utils/backtrace.c utils/backtrace.h \
+ utils/leak_detective.c utils/leak_detective.h \
+ integrity_checker.c integrity_checker.h
@USE_LEAK_DETECTIVE_TRUE@am__objects_1 = leak_detective.lo
@USE_INTEGRITY_TEST_TRUE@am__objects_2 = integrity_checker.lo
am_libstrongswan_la_OBJECTS = library.lo chunk.lo debug.lo enum.lo \
settings.lo printf_hook.lo asn1.lo asn1_parser.lo oid.lo \
- crypter.lo hasher.lo pkcs9.lo proposal_keywords.lo prf.lo \
- rng.lo prf_plus.lo signer.lo crypto_factory.lo \
- crypto_tester.lo diffie_hellman.lo aead.lo transform.lo \
- credential_factory.lo builder.lo cred_encoding.lo \
+ bio_reader.lo bio_writer.lo crypter.lo hasher.lo pkcs9.lo \
+ proposal_keywords.lo prf.lo rng.lo prf_plus.lo signer.lo \
+ crypto_factory.lo crypto_tester.lo diffie_hellman.lo aead.lo \
+ transform.lo credential_factory.lo builder.lo cred_encoding.lo \
private_key.lo public_key.lo shared_key.lo certificate.lo \
crl.lo ocsp_response.lo ietf_attributes.lo \
credential_manager.lo auth_cfg_wrapper.lo \
ocsp_response_wrapper.lo cert_cache.lo mem_cred.lo \
- callback_cred.lo auth_cfg.lo database_factory.lo fetcher.lo \
- fetcher_manager.lo eap.lo plugin_loader.lo callback_job.lo \
- processor.lo scheduler.lo traffic_selector.lo thread.lo \
- thread_value.lo mutex.lo rwlock.lo utils.lo host.lo \
- identification.lo lexparser.lo linked_list.lo hashtable.lo \
- enumerator.lo optionsfrom.lo backtrace.lo $(am__objects_1) \
- $(am__objects_2)
+ callback_cred.lo auth_cfg.lo database.lo database_factory.lo \
+ fetcher.lo fetcher_manager.lo eap.lo pen.lo plugin_loader.lo \
+ plugin_feature.lo job.lo callback_job.lo processor.lo \
+ scheduler.lo traffic_selector.lo thread.lo thread_value.lo \
+ mutex.lo rwlock.lo utils.lo host.lo identification.lo \
+ lexparser.lo linked_list.lo hashtable.lo enumerator.lo \
+ optionsfrom.lo backtrace.lo $(am__objects_1) $(am__objects_2)
libstrongswan_la_OBJECTS = $(am_libstrongswan_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -287,13 +297,13 @@ CTAGS = ctags
DIST_SUBDIRS = . plugins/af_alg plugins/aes plugins/des \
plugins/blowfish plugins/md4 plugins/md5 plugins/sha1 \
plugins/sha2 plugins/gmp plugins/random plugins/hmac \
- plugins/xcbc plugins/x509 plugins/revocation \
- plugins/constraints plugins/pubkey plugins/pkcs1 plugins/pgp \
- plugins/dnskey plugins/pem plugins/curl plugins/soup \
- plugins/ldap plugins/mysql plugins/sqlite plugins/padlock \
- plugins/openssl plugins/gcrypt plugins/fips_prf plugins/agent \
- plugins/pkcs11 plugins/ctr plugins/ccm plugins/gcm \
- plugins/test_vectors
+ plugins/cmac plugins/xcbc plugins/x509 plugins/revocation \
+ plugins/constraints plugins/pubkey plugins/pkcs1 plugins/pkcs8 \
+ plugins/pgp plugins/dnskey plugins/pem plugins/curl \
+ plugins/soup plugins/ldap plugins/mysql plugins/sqlite \
+ plugins/padlock plugins/openssl plugins/gcrypt \
+ plugins/fips_prf plugins/agent plugins/pkcs11 plugins/ctr \
+ plugins/ccm plugins/gcm plugins/test_vectors
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
@@ -411,6 +421,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -419,6 +432,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -435,11 +449,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -483,6 +499,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -493,11 +510,12 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-lib_LTLIBRARIES = libstrongswan.la
+ipseclib_LTLIBRARIES = libstrongswan.la
libstrongswan_la_SOURCES = library.c library.h chunk.c chunk.h debug.c \
debug.h enum.c enum.h settings.h settings.c printf_hook.c \
printf_hook.h asn1/asn1.c asn1/asn1.h asn1/asn1_parser.c \
- asn1/asn1_parser.h asn1/oid.c asn1/oid.h \
+ asn1/asn1_parser.h asn1/oid.c asn1/oid.h bio/bio_reader.h \
+ bio/bio_reader.c bio/bio_writer.h bio/bio_writer.c \
crypto/crypters/crypter.c crypto/crypters/crypter.h \
crypto/hashers/hasher.h crypto/hashers/hasher.c crypto/pkcs9.c \
crypto/pkcs9.h crypto/proposal/proposal_keywords.c \
@@ -539,25 +557,28 @@ libstrongswan_la_SOURCES = library.c library.h chunk.c chunk.h debug.c \
credentials/sets/callback_cred.h credentials/auth_cfg.c \
credentials/auth_cfg.h credentials/credential_set.h \
credentials/cert_validator.h database/database.h \
- database/database_factory.h database/database_factory.c \
- fetcher/fetcher.h fetcher/fetcher.c fetcher/fetcher_manager.h \
- fetcher/fetcher_manager.c eap/eap.h eap/eap.c \
- plugins/plugin_loader.c plugins/plugin_loader.h \
- plugins/plugin.h processing/jobs/job.h \
- processing/jobs/callback_job.c processing/jobs/callback_job.h \
- processing/processor.c processing/processor.h \
- processing/scheduler.c processing/scheduler.h \
- selectors/traffic_selector.c selectors/traffic_selector.h \
- threading/thread.h threading/thread.c threading/thread_value.h \
+ database/database.c database/database_factory.h \
+ database/database_factory.c fetcher/fetcher.h \
+ fetcher/fetcher.c fetcher/fetcher_manager.h \
+ fetcher/fetcher_manager.c eap/eap.h eap/eap.c pen/pen.h \
+ pen/pen.c plugins/plugin_loader.c plugins/plugin_loader.h \
+ plugins/plugin.h plugins/plugin_feature.c \
+ plugins/plugin_feature.h processing/jobs/job.h \
+ processing/jobs/job.c processing/jobs/callback_job.c \
+ processing/jobs/callback_job.h processing/processor.c \
+ processing/processor.h processing/scheduler.c \
+ processing/scheduler.h selectors/traffic_selector.c \
+ selectors/traffic_selector.h threading/thread.h \
+ threading/thread.c threading/thread_value.h \
threading/thread_value.c threading/mutex.h threading/mutex.c \
threading/condvar.h threading/rwlock.h threading/rwlock.c \
threading/lock_profiler.h utils.h utils.c utils/host.c \
utils/host.h utils/identification.c utils/identification.h \
- utils/iterator.h utils/lexparser.c utils/lexparser.h \
- utils/linked_list.c utils/linked_list.h utils/hashtable.c \
- utils/hashtable.h utils/enumerator.c utils/enumerator.h \
- utils/optionsfrom.c utils/optionsfrom.h utils/backtrace.c \
- utils/backtrace.h $(am__append_2) $(am__append_5)
+ utils/lexparser.c utils/lexparser.h utils/linked_list.c \
+ utils/linked_list.h utils/hashtable.c utils/hashtable.h \
+ utils/enumerator.c utils/enumerator.h utils/optionsfrom.c \
+ utils/optionsfrom.h utils/backtrace.c utils/backtrace.h \
+ $(am__append_2) $(am__append_5)
libstrongswan_la_LIBADD = $(PTHREADLIB) $(DLLIB) $(BTLIB) $(SOCKLIB) \
$(RTLIB) $(am__append_6) $(am__append_8) $(am__append_10) \
$(am__append_12) $(am__append_14) $(am__append_16) \
@@ -570,9 +591,12 @@ libstrongswan_la_LIBADD = $(PTHREADLIB) $(DLLIB) $(BTLIB) $(SOCKLIB) \
$(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_72) $(am__append_74) $(am__append_76) \
+ $(am__append_78) $(am__append_80)
INCLUDES = -I$(top_srcdir)/src/libstrongswan
-AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" -DPLUGINDIR=\"${plugindir}\" \
+AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \
+ -DIPSEC_LIB_DIR=\"${ipseclibdir}\" \
+ -DPLUGINDIR=\"${plugindir}\" \
-DSTRONGSWAN_CONF=\"${strongswan_conf}\" $(am__append_1) \
$(am__append_3) $(am__append_4)
EXTRA_DIST = \
@@ -605,7 +629,8 @@ $(srcdir)/crypto/proposal/proposal_keywords.c
@MONOLITHIC_FALSE@ $(am__append_63) $(am__append_65) \
@MONOLITHIC_FALSE@ $(am__append_67) $(am__append_69) \
@MONOLITHIC_FALSE@ $(am__append_71) $(am__append_73) \
-@MONOLITHIC_FALSE@ $(am__append_75)
+@MONOLITHIC_FALSE@ $(am__append_75) $(am__append_77) \
+@MONOLITHIC_FALSE@ $(am__append_79)
# build plugins with their own Makefile
#######################################
@@ -626,7 +651,8 @@ $(srcdir)/crypto/proposal/proposal_keywords.c
@MONOLITHIC_TRUE@ $(am__append_63) $(am__append_65) \
@MONOLITHIC_TRUE@ $(am__append_67) $(am__append_69) \
@MONOLITHIC_TRUE@ $(am__append_71) $(am__append_73) \
-@MONOLITHIC_TRUE@ $(am__append_75)
+@MONOLITHIC_TRUE@ $(am__append_75) $(am__append_77) \
+@MONOLITHIC_TRUE@ $(am__append_79)
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -662,39 +688,39 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(libdir)'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
}
-uninstall-libLTLIBRARIES:
+uninstall-ipseclibLTLIBRARIES:
@$(NORMAL_UNINSTALL)
- @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
- echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
- $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
done
-clean-libLTLIBRARIES:
- -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
- @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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.la: $(libstrongswan_la_OBJECTS) $(libstrongswan_la_DEPENDENCIES)
- $(LINK) -rpath $(libdir) $(libstrongswan_la_OBJECTS) $(libstrongswan_la_LIBADD) $(LIBS)
+ $(LINK) -rpath $(ipseclibdir) $(libstrongswan_la_OBJECTS) $(libstrongswan_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -708,6 +734,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_cfg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_cfg_wrapper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backtrace.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bio_reader.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bio_writer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/builder.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback_cred.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback_job.Plo@am__quote@
@@ -721,6 +749,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_factory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto_tester.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/database.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/database_factory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diffie_hellman.Plo@am__quote@
@@ -735,6 +764,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/identification.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ietf_attributes.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/integrity_checker.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/job.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/leak_detective.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lexparser.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/library.Plo@am__quote@
@@ -745,7 +775,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp_response_wrapper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oid.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optionsfrom.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pen.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs9.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_feature.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_loader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prf_plus.Plo@am__quote@
@@ -808,6 +840,20 @@ oid.lo: asn1/oid.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 oid.lo `test -f 'asn1/oid.c' || echo '$(srcdir)/'`asn1/oid.c
+bio_reader.lo: bio/bio_reader.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bio_reader.lo -MD -MP -MF $(DEPDIR)/bio_reader.Tpo -c -o bio_reader.lo `test -f 'bio/bio_reader.c' || echo '$(srcdir)/'`bio/bio_reader.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/bio_reader.Tpo $(DEPDIR)/bio_reader.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bio/bio_reader.c' object='bio_reader.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 bio_reader.lo `test -f 'bio/bio_reader.c' || echo '$(srcdir)/'`bio/bio_reader.c
+
+bio_writer.lo: bio/bio_writer.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT bio_writer.lo -MD -MP -MF $(DEPDIR)/bio_writer.Tpo -c -o bio_writer.lo `test -f 'bio/bio_writer.c' || echo '$(srcdir)/'`bio/bio_writer.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/bio_writer.Tpo $(DEPDIR)/bio_writer.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='bio/bio_writer.c' object='bio_writer.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 bio_writer.lo `test -f 'bio/bio_writer.c' || echo '$(srcdir)/'`bio/bio_writer.c
+
crypter.lo: crypto/crypters/crypter.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT crypter.lo -MD -MP -MF $(DEPDIR)/crypter.Tpo -c -o crypter.lo `test -f 'crypto/crypters/crypter.c' || echo '$(srcdir)/'`crypto/crypters/crypter.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/crypter.Tpo $(DEPDIR)/crypter.Plo
@@ -1018,6 +1064,13 @@ auth_cfg.lo: credentials/auth_cfg.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 auth_cfg.lo `test -f 'credentials/auth_cfg.c' || echo '$(srcdir)/'`credentials/auth_cfg.c
+database.lo: database/database.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT database.lo -MD -MP -MF $(DEPDIR)/database.Tpo -c -o database.lo `test -f 'database/database.c' || echo '$(srcdir)/'`database/database.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/database.Tpo $(DEPDIR)/database.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='database/database.c' object='database.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 database.lo `test -f 'database/database.c' || echo '$(srcdir)/'`database/database.c
+
database_factory.lo: database/database_factory.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT database_factory.lo -MD -MP -MF $(DEPDIR)/database_factory.Tpo -c -o database_factory.lo `test -f 'database/database_factory.c' || echo '$(srcdir)/'`database/database_factory.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/database_factory.Tpo $(DEPDIR)/database_factory.Plo
@@ -1046,6 +1099,13 @@ eap.lo: eap/eap.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 eap.lo `test -f 'eap/eap.c' || echo '$(srcdir)/'`eap/eap.c
+pen.lo: pen/pen.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pen.lo -MD -MP -MF $(DEPDIR)/pen.Tpo -c -o pen.lo `test -f 'pen/pen.c' || echo '$(srcdir)/'`pen/pen.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pen.Tpo $(DEPDIR)/pen.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pen/pen.c' object='pen.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 pen.lo `test -f 'pen/pen.c' || echo '$(srcdir)/'`pen/pen.c
+
plugin_loader.lo: plugins/plugin_loader.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plugin_loader.lo -MD -MP -MF $(DEPDIR)/plugin_loader.Tpo -c -o plugin_loader.lo `test -f 'plugins/plugin_loader.c' || echo '$(srcdir)/'`plugins/plugin_loader.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/plugin_loader.Tpo $(DEPDIR)/plugin_loader.Plo
@@ -1053,6 +1113,20 @@ plugin_loader.lo: plugins/plugin_loader.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 plugin_loader.lo `test -f 'plugins/plugin_loader.c' || echo '$(srcdir)/'`plugins/plugin_loader.c
+plugin_feature.lo: plugins/plugin_feature.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plugin_feature.lo -MD -MP -MF $(DEPDIR)/plugin_feature.Tpo -c -o plugin_feature.lo `test -f 'plugins/plugin_feature.c' || echo '$(srcdir)/'`plugins/plugin_feature.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/plugin_feature.Tpo $(DEPDIR)/plugin_feature.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='plugins/plugin_feature.c' object='plugin_feature.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 plugin_feature.lo `test -f 'plugins/plugin_feature.c' || echo '$(srcdir)/'`plugins/plugin_feature.c
+
+job.lo: processing/jobs/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 job.lo -MD -MP -MF $(DEPDIR)/job.Tpo -c -o job.lo `test -f 'processing/jobs/job.c' || echo '$(srcdir)/'`processing/jobs/job.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/job.Tpo $(DEPDIR)/job.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='processing/jobs/job.c' object='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 job.lo `test -f 'processing/jobs/job.c' || echo '$(srcdir)/'`processing/jobs/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
@@ -1377,7 +1451,7 @@ check: $(BUILT_SOURCES)
all-am: Makefile $(LTLIBRARIES)
installdirs: installdirs-recursive
installdirs-am:
- for dir in "$(DESTDIR)$(libdir)"; do \
+ for dir in "$(DESTDIR)$(ipseclibdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
@@ -1410,7 +1484,7 @@ maintainer-clean-generic:
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-recursive
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-recursive
@@ -1431,13 +1505,13 @@ info: info-recursive
info-am:
-install-data-am:
+install-data-am: install-ipseclibLTLIBRARIES
install-dvi: install-dvi-recursive
install-dvi-am:
-install-exec-am: install-libLTLIBRARIES
+install-exec-am:
install-html: install-html-recursive
@@ -1477,7 +1551,7 @@ ps: ps-recursive
ps-am:
-uninstall-am: uninstall-libLTLIBRARIES
+uninstall-am: uninstall-ipseclibLTLIBRARIES
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \
ctags-recursive install install-am install-strip \
@@ -1485,19 +1559,19 @@ uninstall-am: uninstall-libLTLIBRARIES
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am check check-am clean clean-generic \
- clean-libLTLIBRARIES clean-libtool ctags ctags-recursive \
+ clean-ipseclibLTLIBRARIES clean-libtool ctags ctags-recursive \
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-libLTLIBRARIES install-man install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs installdirs-am \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
- uninstall-libLTLIBRARIES
+ install-info-am install-ipseclibLTLIBRARIES install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-ipseclibLTLIBRARIES
library.lo : $(top_builddir)/config.status
diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c
index 4466b37a4..4cb38d126 100644
--- a/src/libstrongswan/asn1/asn1.c
+++ b/src/libstrongswan/asn1/asn1.c
@@ -222,7 +222,7 @@ size_t asn1_length(chunk_t *blob)
if (blob->len < 2)
{
- DBG2(DBG_LIB, "insufficient number of octets to parse ASN.1 length");
+ DBG2(DBG_ASN, "insufficient number of octets to parse ASN.1 length");
return ASN1_INVALID_LENGTH;
}
@@ -234,7 +234,7 @@ size_t asn1_length(chunk_t *blob)
{ /* single length octet */
if (n > blob->len)
{
- DBG2(DBG_LIB, "length is larger than remaining blob size");
+ DBG2(DBG_ASN, "length is larger than remaining blob size");
return ASN1_INVALID_LENGTH;
}
return n;
@@ -245,13 +245,13 @@ size_t asn1_length(chunk_t *blob)
if (n == 0 || n > blob->len)
{
- DBG2(DBG_LIB, "number of length octets invalid");
+ DBG2(DBG_ASN, "number of length octets invalid");
return ASN1_INVALID_LENGTH;
}
if (n > sizeof(len))
{
- DBG2(DBG_LIB, "number of length octets is larger than limit of"
+ DBG2(DBG_ASN, "number of length octets is larger than limit of"
" %d octets", (int)sizeof(len));
return ASN1_INVALID_LENGTH;
}
@@ -265,7 +265,7 @@ size_t asn1_length(chunk_t *blob)
}
if (len > blob->len)
{
- DBG2(DBG_LIB, "length is larger than remaining blob size");
+ DBG2(DBG_ASN, "length is larger than remaining blob size");
return ASN1_INVALID_LENGTH;
}
return len;
@@ -326,10 +326,10 @@ static const int tm_leap_1970 = 477;
*/
time_t asn1_to_time(const chunk_t *utctime, asn1_t type)
{
- int tm_year, tm_mon, tm_day, tm_days, tm_hour, tm_min, tm_sec;
+ int tm_year, tm_mon, tm_day, tm_hour, tm_min, tm_sec;
int tm_leap_4, tm_leap_100, tm_leap_400, tm_leap;
int tz_hour, tz_min, tz_offset;
- time_t tm_secs;
+ time_t tm_days, tm_secs;
u_char *eot = NULL;
if ((eot = memchr(utctime->ptr, 'Z', utctime->len)) != NULL)
@@ -435,6 +435,11 @@ chunk_t asn1_from_time(const time_t *time, asn1_t type)
struct tm t;
gmtime_r(time, &t);
+ /* RFC 5280 says that dates through the year 2049 MUST be encoded as UTCTIME
+ * and dates in 2050 or later MUST be encoded as GENERALIZEDTIME. We only
+ * enforce the latter to avoid overflows but allow callers to force the
+ * encoding to GENERALIZEDTIME */
+ type = (t.tm_year >= 150) ? ASN1_GENERALIZEDTIME : type;
if (type == ASN1_GENERALIZEDTIME)
{
format = "%04d%02d%02d%02d%02d%02dZ";
@@ -443,7 +448,7 @@ chunk_t asn1_from_time(const time_t *time, asn1_t type)
else /* ASN1_UTCTIME */
{
format = "%02d%02d%02d%02d%02d%02dZ";
- offset = (t.tm_year < 100)? 0 : -100;
+ offset = (t.tm_year < 100) ? 0 : -100;
}
snprintf(buf, BUF_LEN, format, t.tm_year + offset,
t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
@@ -471,12 +476,12 @@ void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private)
{
break;
}
- DBG2(DBG_LIB, " %s", oid_str);
+ DBG2(DBG_ASN, " %s", oid_str);
free(oid_str);
}
else
{
- DBG2(DBG_LIB, " '%s'", oid_names[oid].name);
+ DBG2(DBG_ASN, " '%s'", oid_names[oid].name);
}
return;
case ASN1_UTF8STRING:
@@ -484,14 +489,14 @@ void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private)
case ASN1_PRINTABLESTRING:
case ASN1_T61STRING:
case ASN1_VISIBLESTRING:
- DBG2(DBG_LIB, " '%.*s'", (int)object.len, object.ptr);
+ DBG2(DBG_ASN, " '%.*s'", (int)object.len, object.ptr);
return;
case ASN1_UTCTIME:
case ASN1_GENERALIZEDTIME:
{
time_t time = asn1_to_time(&object, type);
- DBG2(DBG_LIB, " '%T'", &time, TRUE);
+ DBG2(DBG_ASN, " '%T'", &time, TRUE);
}
return;
default:
@@ -499,11 +504,11 @@ void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private)
}
if (private)
{
- DBG4(DBG_LIB, "%B", &object);
+ DBG4(DBG_ASN, "%B", &object);
}
else
{
- DBG3(DBG_LIB, "%B", &object);
+ DBG3(DBG_ASN, "%B", &object);
}
}
@@ -517,14 +522,14 @@ bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level, const c
/* an ASN.1 object must possess at least a tag and length field */
if (object->len < 2)
{
- DBG2(DBG_LIB, "L%d - %s: ASN.1 object smaller than 2 octets", level,
+ DBG2(DBG_ASN, "L%d - %s: ASN.1 object smaller than 2 octets", level,
name);
return FALSE;
}
if (*object->ptr != type)
{
- DBG2(DBG_LIB, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
+ DBG2(DBG_ASN, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
level, name, type, *object->ptr);
return FALSE;
}
@@ -533,12 +538,12 @@ bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level, const c
if (len == ASN1_INVALID_LENGTH || object->len < len)
{
- DBG2(DBG_LIB, "L%d - %s: length of ASN.1 object invalid or too large",
+ DBG2(DBG_ASN, "L%d - %s: length of ASN.1 object invalid or too large",
level, name);
return FALSE;
}
- DBG2(DBG_LIB, "L%d - %s:", level, name);
+ DBG2(DBG_ASN, "L%d - %s:", level, name);
asn1_debug_simple_object(*object, type, FALSE);
return TRUE;
}
@@ -547,14 +552,20 @@ bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level, const c
* ASN.1 definition of an algorithmIdentifier
*/
static const asn1Object_t algorithmIdentifierObjects[] = {
- { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */
- { 1, "parameters", ASN1_EOC, ASN1_RAW|ASN1_OPT }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
- { 0, "exit", ASN1_EOC, ASN1_EXIT }
+ { 0, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "algorithm", ASN1_OID, ASN1_BODY }, /* 1 */
+ { 1, "parameters", ASN1_OID, ASN1_RAW|ASN1_OPT }, /* 2 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 1, "parameters", ASN1_SEQUENCE, ASN1_RAW|ASN1_OPT }, /* 4 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 5 */
+ { 1, "parameters", ASN1_OCTET_STRING, ASN1_RAW|ASN1_OPT }, /* 6 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-#define ALGORITHM_ID_ALG 1
-#define ALGORITHM_ID_PARAMETERS 2
+#define ALGORITHM_ID_ALG 1
+#define ALGORITHM_ID_PARAMETERS_OID 2
+#define ALGORITHM_ID_PARAMETERS_SEQ 4
+#define ALGORITHM_ID_PARAMETERS_OCT 6
/*
* Defined in header
@@ -576,7 +587,9 @@ int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *parameters
case ALGORITHM_ID_ALG:
alg = asn1_known_oid(object);
break;
- case ALGORITHM_ID_PARAMETERS:
+ case ALGORITHM_ID_PARAMETERS_OID:
+ case ALGORITHM_ID_PARAMETERS_SEQ:
+ case ALGORITHM_ID_PARAMETERS_OCT:
if (parameters != NULL)
{
*parameters = object;
@@ -606,7 +619,7 @@ bool is_asn1(chunk_t blob)
tag = *blob.ptr;
if (tag != ASN1_SEQUENCE && tag != ASN1_SET && tag != ASN1_OCTET_STRING)
{
- DBG2(DBG_LIB, " file content is not binary ASN.1");
+ DBG2(DBG_ASN, " file content is not binary ASN.1");
return FALSE;
}
@@ -624,7 +637,7 @@ bool is_asn1(chunk_t blob)
return TRUE;
}
- DBG2(DBG_LIB, " file size does not match ASN.1 coded length");
+ DBG2(DBG_ASN, " file size does not match ASN.1 coded length");
return FALSE;
}
diff --git a/src/libstrongswan/asn1/asn1.h b/src/libstrongswan/asn1/asn1.h
index 05a060827..15ffff62e 100644
--- a/src/libstrongswan/asn1/asn1.h
+++ b/src/libstrongswan/asn1/asn1.h
@@ -35,8 +35,8 @@ typedef enum {
ASN1_BOOLEAN = 0x01,
ASN1_INTEGER = 0x02,
ASN1_BIT_STRING = 0x03,
- ASN1_OCTET_STRING = 0x04,
- ASN1_NULL = 0x05,
+ ASN1_OCTET_STRING = 0x04,
+ ASN1_NULL = 0x05,
ASN1_OID = 0x06,
ASN1_ENUMERATED = 0x0A,
ASN1_UTF8STRING = 0x0C,
@@ -48,7 +48,7 @@ typedef enum {
ASN1_UTCTIME = 0x17,
ASN1_GENERALIZEDTIME = 0x18,
ASN1_GRAPHICSTRING = 0x19,
- ASN1_VISIBLESTRING = 0x1A,
+ ASN1_VISIBLESTRING = 0x1A,
ASN1_GENERALSTRING = 0x1B,
ASN1_UNIVERSALSTRING = 0x1C,
ASN1_BMPSTRING = 0x1E,
@@ -75,7 +75,7 @@ typedef enum {
ASN1_CONTEXT_C_4 = 0xA4,
ASN1_CONTEXT_C_5 = 0xA5,
- ASN1_INVALID = 0x100,
+ ASN1_INVALID = 0x100,
} asn1_t;
#define ASN1_INVALID_LENGTH 0xffffffff
@@ -191,6 +191,8 @@ time_t asn1_to_time(const chunk_t *utctime, asn1_t type);
/**
* Converts time_t to an ASN.1 UTCTIME or GENERALIZEDTIME string
*
+ * @note The type is automatically changed to GENERALIZEDTIME if needed
+ *
* @param time time_t in UTC
* @param type ASN1_UTCTIME or ASN1_GENERALIZEDTIME
* @return body of an ASN.1 code time object
diff --git a/src/libstrongswan/asn1/asn1_parser.c b/src/libstrongswan/asn1/asn1_parser.c
index 2a7a38a52..40e11b321 100644
--- a/src/libstrongswan/asn1/asn1_parser.c
+++ b/src/libstrongswan/asn1/asn1_parser.c
@@ -120,7 +120,7 @@ METHOD(asn1_parser_t, iterate, bool,
if ((obj.flags & ASN1_DEF) && (blob->len == 0 || *start_ptr != obj.type) )
{
/* field is missing */
- DBG2(DBG_LIB, "L%d - %s:", level, obj.name);
+ DBG2(DBG_ASN, "L%d - %s:", level, obj.name);
if (obj.type & ASN1_CONSTRUCTED)
{
this->line++ ; /* skip context-specific tag */
@@ -147,7 +147,7 @@ METHOD(asn1_parser_t, iterate, bool,
if (blob->len < 2)
{
- DBG1(DBG_LIB, "L%d - %s: ASN.1 object smaller than 2 octets",
+ DBG1(DBG_ASN, "L%d - %s: ASN.1 object smaller than 2 octets",
level, obj.name);
this->success = FALSE;
goto end;
@@ -157,7 +157,7 @@ METHOD(asn1_parser_t, iterate, bool,
if (blob1->len == ASN1_INVALID_LENGTH)
{
- DBG1(DBG_LIB, "L%d - %s: length of ASN.1 object invalid or too large",
+ DBG1(DBG_ASN, "L%d - %s: length of ASN.1 object invalid or too large",
level, obj.name);
this->success = FALSE;
}
@@ -170,7 +170,7 @@ METHOD(asn1_parser_t, iterate, bool,
if (obj.flags & ASN1_RAW)
{
- DBG2(DBG_LIB, "L%d - %s:", level, obj.name);
+ DBG2(DBG_ASN, "L%d - %s:", level, obj.name);
object->ptr = start_ptr;
object->len = (size_t)(blob->ptr - start_ptr);
goto end;
@@ -178,14 +178,14 @@ METHOD(asn1_parser_t, iterate, bool,
if (*start_ptr != obj.type && !(this->implicit && this->line == 0))
{
- DBG1(DBG_LIB, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
+ DBG2(DBG_ASN, "L%d - %s: ASN1 tag 0x%02x expected, but is 0x%02x",
level, obj.name, obj.type, *start_ptr);
- DBG3(DBG_LIB, "%b", start_ptr, (u_int)(blob->ptr - start_ptr));
+ DBG3(DBG_ASN, "%b", start_ptr, (u_int)(blob->ptr - start_ptr));
this->success = FALSE;
goto end;
}
- DBG2(DBG_LIB, "L%d - %s:", level, obj.name);
+ DBG2(DBG_ASN, "L%d - %s:", level, obj.name);
/* In case of "SEQUENCE OF" or "SET OF" start a loop */
if (obj.flags & ASN1_LOOP)
@@ -214,11 +214,11 @@ METHOD(asn1_parser_t, iterate, bool,
object->len = (size_t)(blob->ptr - start_ptr);
if (this->private)
{
- DBG4(DBG_LIB, "%B", object);
+ DBG4(DBG_ASN, "%B", object);
}
else
{
- DBG3(DBG_LIB, "%B", object);
+ DBG3(DBG_ASN, "%B", object);
}
}
else if (obj.flags & ASN1_BODY)
diff --git a/src/libstrongswan/asn1/oid.c b/src/libstrongswan/asn1/oid.c
index 6af088fd2..bfc985c25 100644
--- a/src/libstrongswan/asn1/oid.c
+++ b/src/libstrongswan/asn1/oid.c
@@ -28,8 +28,8 @@ const oid_t oid_names[] = {
{ 0x01, 0, 1, 8, "pilotAttributeType" }, /* 15 */
{ 0x01, 17, 0, 9, "UID" }, /* 16 */
{ 0x19, 0, 0, 9, "DC" }, /* 17 */
- {0x55, 64, 1, 0, "X.500" }, /* 18 */
- { 0x04, 36, 1, 1, "X.509" }, /* 19 */
+ {0x55, 65, 1, 0, "X.500" }, /* 18 */
+ { 0x04, 37, 1, 1, "X.509" }, /* 19 */
{ 0x03, 21, 0, 2, "CN" }, /* 20 */
{ 0x04, 22, 0, 2, "S" }, /* 21 */
{ 0x05, 23, 0, 2, "SN" }, /* 22 */
@@ -45,337 +45,343 @@ const oid_t oid_names[] = {
{ 0x2A, 33, 0, 2, "G" }, /* 32 */
{ 0x2B, 34, 0, 2, "I" }, /* 33 */
{ 0x2D, 35, 0, 2, "ID" }, /* 34 */
- { 0x48, 0, 0, 2, "role" }, /* 35 */
- { 0x1D, 0, 1, 1, "id-ce" }, /* 36 */
- { 0x09, 38, 0, 2, "subjectDirectoryAttrs" }, /* 37 */
- { 0x0E, 39, 0, 2, "subjectKeyIdentifier" }, /* 38 */
- { 0x0F, 40, 0, 2, "keyUsage" }, /* 39 */
- { 0x10, 41, 0, 2, "privateKeyUsagePeriod" }, /* 40 */
- { 0x11, 42, 0, 2, "subjectAltName" }, /* 41 */
- { 0x12, 43, 0, 2, "issuerAltName" }, /* 42 */
- { 0x13, 44, 0, 2, "basicConstraints" }, /* 43 */
- { 0x14, 45, 0, 2, "crlNumber" }, /* 44 */
- { 0x15, 46, 0, 2, "reasonCode" }, /* 45 */
- { 0x17, 47, 0, 2, "holdInstructionCode" }, /* 46 */
- { 0x18, 48, 0, 2, "invalidityDate" }, /* 47 */
- { 0x1B, 49, 0, 2, "deltaCrlIndicator" }, /* 48 */
- { 0x1C, 50, 0, 2, "issuingDistributionPoint" }, /* 49 */
- { 0x1D, 51, 0, 2, "certificateIssuer" }, /* 50 */
- { 0x1E, 52, 0, 2, "nameConstraints" }, /* 51 */
- { 0x1F, 53, 0, 2, "crlDistributionPoints" }, /* 52 */
- { 0x20, 55, 1, 2, "certificatePolicies" }, /* 53 */
- { 0x00, 0, 0, 3, "anyPolicy" }, /* 54 */
- { 0x21, 56, 0, 2, "policyMappings" }, /* 55 */
- { 0x23, 57, 0, 2, "authorityKeyIdentifier" }, /* 56 */
- { 0x24, 58, 0, 2, "policyConstraints" }, /* 57 */
- { 0x25, 60, 1, 2, "extendedKeyUsage" }, /* 58 */
- { 0x00, 0, 0, 3, "anyExtendedKeyUsage" }, /* 59 */
- { 0x2E, 61, 0, 2, "freshestCRL" }, /* 60 */
- { 0x36, 62, 0, 2, "inhibitAnyPolicy" }, /* 61 */
- { 0x37, 63, 0, 2, "targetInformation" }, /* 62 */
- { 0x38, 0, 0, 2, "noRevAvail" }, /* 63 */
- {0x2A, 163, 1, 0, "" }, /* 64 */
- { 0x83, 77, 1, 1, "" }, /* 65 */
- { 0x08, 0, 1, 2, "jp" }, /* 66 */
- { 0x8C, 0, 1, 3, "" }, /* 67 */
- { 0x9A, 0, 1, 4, "" }, /* 68 */
- { 0x4B, 0, 1, 5, "" }, /* 69 */
- { 0x3D, 0, 1, 6, "" }, /* 70 */
- { 0x01, 0, 1, 7, "security" }, /* 71 */
- { 0x01, 0, 1, 8, "algorithm" }, /* 72 */
- { 0x01, 0, 1, 9, "symm-encryption-alg" }, /* 73 */
- { 0x02, 75, 0, 10, "camellia128-cbc" }, /* 74 */
- { 0x03, 76, 0, 10, "camellia192-cbc" }, /* 75 */
- { 0x04, 0, 0, 10, "camellia256-cbc" }, /* 76 */
- { 0x86, 0, 1, 1, "" }, /* 77 */
- { 0x48, 0, 1, 2, "us" }, /* 78 */
- { 0x86, 122, 1, 3, "" }, /* 79 */
- { 0xF6, 85, 1, 4, "" }, /* 80 */
- { 0x7D, 0, 1, 5, "NortelNetworks" }, /* 81 */
- { 0x07, 0, 1, 6, "Entrust" }, /* 82 */
- { 0x41, 0, 1, 7, "nsn-ce" }, /* 83 */
- { 0x00, 0, 0, 8, "entrustVersInfo" }, /* 84 */
- { 0xF7, 0, 1, 4, "" }, /* 85 */
- { 0x0D, 0, 1, 5, "RSADSI" }, /* 86 */
- { 0x01, 117, 1, 6, "PKCS" }, /* 87 */
- { 0x01, 99, 1, 7, "PKCS-1" }, /* 88 */
- { 0x01, 90, 0, 8, "rsaEncryption" }, /* 89 */
- { 0x02, 91, 0, 8, "md2WithRSAEncryption" }, /* 90 */
- { 0x04, 92, 0, 8, "md5WithRSAEncryption" }, /* 91 */
- { 0x05, 93, 0, 8, "sha-1WithRSAEncryption" }, /* 92 */
- { 0x07, 94, 0, 8, "id-RSAES-OAEP" }, /* 93 */
- { 0x09, 95, 0, 8, "id-pSpecified" }, /* 94 */
- { 0x0B, 96, 0, 8, "sha256WithRSAEncryption" }, /* 95 */
- { 0x0C, 97, 0, 8, "sha384WithRSAEncryption" }, /* 96 */
- { 0x0D, 98, 0, 8, "sha512WithRSAEncryption" }, /* 97 */
- { 0x0E, 0, 0, 8, "sha224WithRSAEncryption" }, /* 98 */
- { 0x07, 106, 1, 7, "PKCS-7" }, /* 99 */
- { 0x01, 101, 0, 8, "data" }, /* 100 */
- { 0x02, 102, 0, 8, "signedData" }, /* 101 */
- { 0x03, 103, 0, 8, "envelopedData" }, /* 102 */
- { 0x04, 104, 0, 8, "signedAndEnvelopedData" }, /* 103 */
- { 0x05, 105, 0, 8, "digestedData" }, /* 104 */
- { 0x06, 0, 0, 8, "encryptedData" }, /* 105 */
- { 0x09, 0, 1, 7, "PKCS-9" }, /* 106 */
- { 0x01, 108, 0, 8, "E" }, /* 107 */
- { 0x02, 109, 0, 8, "unstructuredName" }, /* 108 */
- { 0x03, 110, 0, 8, "contentType" }, /* 109 */
- { 0x04, 111, 0, 8, "messageDigest" }, /* 110 */
- { 0x05, 112, 0, 8, "signingTime" }, /* 111 */
- { 0x06, 113, 0, 8, "counterSignature" }, /* 112 */
- { 0x07, 114, 0, 8, "challengePassword" }, /* 113 */
- { 0x08, 115, 0, 8, "unstructuredAddress" }, /* 114 */
- { 0x0E, 116, 0, 8, "extensionRequest" }, /* 115 */
- { 0x0F, 0, 0, 8, "S/MIME Capabilities" }, /* 116 */
- { 0x02, 120, 1, 6, "digestAlgorithm" }, /* 117 */
- { 0x02, 119, 0, 7, "md2" }, /* 118 */
- { 0x05, 0, 0, 7, "md5" }, /* 119 */
- { 0x03, 0, 1, 6, "encryptionAlgorithm" }, /* 120 */
- { 0x07, 0, 0, 7, "3des-ede-cbc" }, /* 121 */
- { 0xCE, 0, 1, 3, "" }, /* 122 */
- { 0x3D, 0, 1, 4, "ansi-X9-62" }, /* 123 */
- { 0x02, 126, 1, 5, "id-publicKeyType" }, /* 124 */
- { 0x01, 0, 0, 6, "id-ecPublicKey" }, /* 125 */
- { 0x03, 156, 1, 5, "ellipticCurve" }, /* 126 */
- { 0x00, 148, 1, 6, "c-TwoCurve" }, /* 127 */
- { 0x01, 129, 0, 7, "c2pnb163v1" }, /* 128 */
- { 0x02, 130, 0, 7, "c2pnb163v2" }, /* 129 */
- { 0x03, 131, 0, 7, "c2pnb163v3" }, /* 130 */
- { 0x04, 132, 0, 7, "c2pnb176w1" }, /* 131 */
- { 0x05, 133, 0, 7, "c2tnb191v1" }, /* 132 */
- { 0x06, 134, 0, 7, "c2tnb191v2" }, /* 133 */
- { 0x07, 135, 0, 7, "c2tnb191v3" }, /* 134 */
- { 0x08, 136, 0, 7, "c2onb191v4" }, /* 135 */
- { 0x09, 137, 0, 7, "c2onb191v5" }, /* 136 */
- { 0x0A, 138, 0, 7, "c2pnb208w1" }, /* 137 */
- { 0x0B, 139, 0, 7, "c2tnb239v1" }, /* 138 */
- { 0x0C, 140, 0, 7, "c2tnb239v2" }, /* 139 */
- { 0x0D, 141, 0, 7, "c2tnb239v3" }, /* 140 */
- { 0x0E, 142, 0, 7, "c2onb239v4" }, /* 141 */
- { 0x0F, 143, 0, 7, "c2onb239v5" }, /* 142 */
- { 0x10, 144, 0, 7, "c2pnb272w1" }, /* 143 */
- { 0x11, 145, 0, 7, "c2pnb304w1" }, /* 144 */
- { 0x12, 146, 0, 7, "c2tnb359v1" }, /* 145 */
- { 0x13, 147, 0, 7, "c2pnb368w1" }, /* 146 */
- { 0x14, 0, 0, 7, "c2tnb431r1" }, /* 147 */
- { 0x01, 0, 1, 6, "primeCurve" }, /* 148 */
- { 0x01, 150, 0, 7, "prime192v1" }, /* 149 */
- { 0x02, 151, 0, 7, "prime192v2" }, /* 150 */
- { 0x03, 152, 0, 7, "prime192v3" }, /* 151 */
- { 0x04, 153, 0, 7, "prime239v1" }, /* 152 */
- { 0x05, 154, 0, 7, "prime239v2" }, /* 153 */
- { 0x06, 155, 0, 7, "prime239v3" }, /* 154 */
- { 0x07, 0, 0, 7, "prime256v1" }, /* 155 */
- { 0x04, 0, 1, 5, "id-ecSigType" }, /* 156 */
- { 0x01, 158, 0, 6, "ecdsa-with-SHA1" }, /* 157 */
- { 0x03, 0, 1, 6, "ecdsa-with-Specified" }, /* 158 */
- { 0x01, 160, 0, 7, "ecdsa-with-SHA224" }, /* 159 */
- { 0x02, 161, 0, 7, "ecdsa-with-SHA256" }, /* 160 */
- { 0x03, 162, 0, 7, "ecdsa-with-SHA384" }, /* 161 */
- { 0x04, 0, 0, 7, "ecdsa-with-SHA512" }, /* 162 */
- {0x2B, 314, 1, 0, "" }, /* 163 */
- { 0x06, 228, 1, 1, "dod" }, /* 164 */
- { 0x01, 0, 1, 2, "internet" }, /* 165 */
- { 0x04, 188, 1, 3, "private" }, /* 166 */
- { 0x01, 0, 1, 4, "enterprise" }, /* 167 */
- { 0x82, 181, 1, 5, "" }, /* 168 */
- { 0x37, 178, 1, 6, "Microsoft" }, /* 169 */
- { 0x0A, 174, 1, 7, "" }, /* 170 */
- { 0x03, 0, 1, 8, "" }, /* 171 */
- { 0x03, 173, 0, 9, "msSGC" }, /* 172 */
- { 0x04, 0, 0, 9, "msEncryptingFileSystem" }, /* 173 */
- { 0x14, 0, 1, 7, "msEnrollmentInfrastructure"}, /* 174 */
- { 0x02, 0, 1, 8, "msCertificateTypeExtension"}, /* 175 */
- { 0x02, 177, 0, 9, "msSmartcardLogon" }, /* 176 */
- { 0x03, 0, 0, 9, "msUPN" }, /* 177 */
- { 0xA0, 0, 1, 6, "" }, /* 178 */
- { 0x2A, 0, 1, 7, "ITA" }, /* 179 */
- { 0x01, 0, 0, 8, "strongSwan" }, /* 180 */
- { 0x89, 0, 1, 5, "" }, /* 181 */
- { 0x31, 0, 1, 6, "" }, /* 182 */
- { 0x01, 0, 1, 7, "" }, /* 183 */
- { 0x01, 0, 1, 8, "" }, /* 184 */
- { 0x02, 0, 1, 9, "" }, /* 185 */
- { 0x02, 0, 1, 10, "" }, /* 186 */
- { 0x4B, 0, 0, 11, "TCGID" }, /* 187 */
- { 0x05, 0, 1, 3, "security" }, /* 188 */
- { 0x05, 0, 1, 4, "mechanisms" }, /* 189 */
- { 0x07, 0, 1, 5, "id-pkix" }, /* 190 */
- { 0x01, 195, 1, 6, "id-pe" }, /* 191 */
- { 0x01, 193, 0, 7, "authorityInfoAccess" }, /* 192 */
- { 0x03, 194, 0, 7, "qcStatements" }, /* 193 */
- { 0x07, 0, 0, 7, "ipAddrBlocks" }, /* 194 */
- { 0x02, 198, 1, 6, "id-qt" }, /* 195 */
- { 0x01, 197, 0, 7, "cps" }, /* 196 */
- { 0x02, 0, 0, 7, "unotice" }, /* 197 */
- { 0x03, 208, 1, 6, "id-kp" }, /* 198 */
- { 0x01, 200, 0, 7, "serverAuth" }, /* 199 */
- { 0x02, 201, 0, 7, "clientAuth" }, /* 200 */
- { 0x03, 202, 0, 7, "codeSigning" }, /* 201 */
- { 0x04, 203, 0, 7, "emailProtection" }, /* 202 */
- { 0x05, 204, 0, 7, "ipsecEndSystem" }, /* 203 */
- { 0x06, 205, 0, 7, "ipsecTunnel" }, /* 204 */
- { 0x07, 206, 0, 7, "ipsecUser" }, /* 205 */
- { 0x08, 207, 0, 7, "timeStamping" }, /* 206 */
- { 0x09, 0, 0, 7, "ocspSigning" }, /* 207 */
- { 0x08, 210, 1, 6, "id-otherNames" }, /* 208 */
- { 0x05, 0, 0, 7, "xmppAddr" }, /* 209 */
- { 0x0A, 215, 1, 6, "id-aca" }, /* 210 */
- { 0x01, 212, 0, 7, "authenticationInfo" }, /* 211 */
- { 0x02, 213, 0, 7, "accessIdentity" }, /* 212 */
- { 0x03, 214, 0, 7, "chargingIdentity" }, /* 213 */
- { 0x04, 0, 0, 7, "group" }, /* 214 */
- { 0x0B, 216, 0, 6, "subjectInfoAccess" }, /* 215 */
- { 0x30, 0, 1, 6, "id-ad" }, /* 216 */
- { 0x01, 225, 1, 7, "ocsp" }, /* 217 */
- { 0x01, 219, 0, 8, "basic" }, /* 218 */
- { 0x02, 220, 0, 8, "nonce" }, /* 219 */
- { 0x03, 221, 0, 8, "crl" }, /* 220 */
- { 0x04, 222, 0, 8, "response" }, /* 221 */
- { 0x05, 223, 0, 8, "noCheck" }, /* 222 */
- { 0x06, 224, 0, 8, "archiveCutoff" }, /* 223 */
- { 0x07, 0, 0, 8, "serviceLocator" }, /* 224 */
- { 0x02, 226, 0, 7, "caIssuers" }, /* 225 */
- { 0x03, 227, 0, 7, "timeStamping" }, /* 226 */
- { 0x05, 0, 0, 7, "caRepository" }, /* 227 */
- { 0x0E, 234, 1, 1, "oiw" }, /* 228 */
- { 0x03, 0, 1, 2, "secsig" }, /* 229 */
- { 0x02, 0, 1, 3, "algorithms" }, /* 230 */
- { 0x07, 232, 0, 4, "des-cbc" }, /* 231 */
- { 0x1A, 233, 0, 4, "sha-1" }, /* 232 */
- { 0x1D, 0, 0, 4, "sha-1WithRSASignature" }, /* 233 */
- { 0x24, 280, 1, 1, "TeleTrusT" }, /* 234 */
- { 0x03, 0, 1, 2, "algorithm" }, /* 235 */
- { 0x03, 0, 1, 3, "signatureAlgorithm" }, /* 236 */
- { 0x01, 241, 1, 4, "rsaSignature" }, /* 237 */
- { 0x02, 239, 0, 5, "rsaSigWithripemd160" }, /* 238 */
- { 0x03, 240, 0, 5, "rsaSigWithripemd128" }, /* 239 */
- { 0x04, 0, 0, 5, "rsaSigWithripemd256" }, /* 240 */
- { 0x02, 0, 1, 4, "ecSign" }, /* 241 */
- { 0x01, 243, 0, 5, "ecSignWithsha1" }, /* 242 */
- { 0x02, 244, 0, 5, "ecSignWithripemd160" }, /* 243 */
- { 0x03, 245, 0, 5, "ecSignWithmd2" }, /* 244 */
- { 0x04, 246, 0, 5, "ecSignWithmd5" }, /* 245 */
- { 0x05, 263, 1, 5, "ttt-ecg" }, /* 246 */
- { 0x01, 251, 1, 6, "fieldType" }, /* 247 */
- { 0x01, 0, 1, 7, "characteristictwoField" }, /* 248 */
- { 0x01, 0, 1, 8, "basisType" }, /* 249 */
- { 0x01, 0, 0, 9, "ipBasis" }, /* 250 */
- { 0x02, 253, 1, 6, "keyType" }, /* 251 */
- { 0x01, 0, 0, 7, "ecgPublicKey" }, /* 252 */
- { 0x03, 254, 0, 6, "curve" }, /* 253 */
- { 0x04, 261, 1, 6, "signatures" }, /* 254 */
- { 0x01, 256, 0, 7, "ecgdsa-with-RIPEMD160" }, /* 255 */
- { 0x02, 257, 0, 7, "ecgdsa-with-SHA1" }, /* 256 */
- { 0x03, 258, 0, 7, "ecgdsa-with-SHA224" }, /* 257 */
- { 0x04, 259, 0, 7, "ecgdsa-with-SHA256" }, /* 258 */
- { 0x05, 260, 0, 7, "ecgdsa-with-SHA384" }, /* 259 */
- { 0x06, 0, 0, 7, "ecgdsa-with-SHA512" }, /* 260 */
- { 0x05, 0, 1, 6, "module" }, /* 261 */
- { 0x01, 0, 0, 7, "1" }, /* 262 */
- { 0x08, 0, 1, 5, "ecStdCurvesAndGeneration" }, /* 263 */
- { 0x01, 0, 1, 6, "ellipticCurve" }, /* 264 */
- { 0x01, 0, 1, 7, "versionOne" }, /* 265 */
- { 0x01, 267, 0, 8, "brainpoolP160r1" }, /* 266 */
- { 0x02, 268, 0, 8, "brainpoolP160t1" }, /* 267 */
- { 0x03, 269, 0, 8, "brainpoolP192r1" }, /* 268 */
- { 0x04, 270, 0, 8, "brainpoolP192t1" }, /* 269 */
- { 0x05, 271, 0, 8, "brainpoolP224r1" }, /* 270 */
- { 0x06, 272, 0, 8, "brainpoolP224t1" }, /* 271 */
- { 0x07, 273, 0, 8, "brainpoolP256r1" }, /* 272 */
- { 0x08, 274, 0, 8, "brainpoolP256t1" }, /* 273 */
- { 0x09, 275, 0, 8, "brainpoolP320r1" }, /* 274 */
- { 0x0A, 276, 0, 8, "brainpoolP320t1" }, /* 275 */
- { 0x0B, 277, 0, 8, "brainpoolP384r1" }, /* 276 */
- { 0x0C, 278, 0, 8, "brainpoolP384t1" }, /* 277 */
- { 0x0D, 279, 0, 8, "brainpoolP512r1" }, /* 278 */
- { 0x0E, 0, 0, 8, "brainpoolP512t1" }, /* 279 */
- { 0x81, 0, 1, 1, "" }, /* 280 */
- { 0x04, 0, 1, 2, "Certicom" }, /* 281 */
- { 0x00, 0, 1, 3, "curve" }, /* 282 */
- { 0x01, 284, 0, 4, "sect163k1" }, /* 283 */
- { 0x02, 285, 0, 4, "sect163r1" }, /* 284 */
- { 0x03, 286, 0, 4, "sect239k1" }, /* 285 */
- { 0x04, 287, 0, 4, "sect113r1" }, /* 286 */
- { 0x05, 288, 0, 4, "sect113r2" }, /* 287 */
- { 0x06, 289, 0, 4, "secp112r1" }, /* 288 */
- { 0x07, 290, 0, 4, "secp112r2" }, /* 289 */
- { 0x08, 291, 0, 4, "secp160r1" }, /* 290 */
- { 0x09, 292, 0, 4, "secp160k1" }, /* 291 */
- { 0x0A, 293, 0, 4, "secp256k1" }, /* 292 */
- { 0x0F, 294, 0, 4, "sect163r2" }, /* 293 */
- { 0x10, 295, 0, 4, "sect283k1" }, /* 294 */
- { 0x11, 296, 0, 4, "sect283r1" }, /* 295 */
- { 0x16, 297, 0, 4, "sect131r1" }, /* 296 */
- { 0x17, 298, 0, 4, "sect131r2" }, /* 297 */
- { 0x18, 299, 0, 4, "sect193r1" }, /* 298 */
- { 0x19, 300, 0, 4, "sect193r2" }, /* 299 */
- { 0x1A, 301, 0, 4, "sect233k1" }, /* 300 */
- { 0x1B, 302, 0, 4, "sect233r1" }, /* 301 */
- { 0x1C, 303, 0, 4, "secp128r1" }, /* 302 */
- { 0x1D, 304, 0, 4, "secp128r2" }, /* 303 */
- { 0x1E, 305, 0, 4, "secp160r2" }, /* 304 */
- { 0x1F, 306, 0, 4, "secp192k1" }, /* 305 */
- { 0x20, 307, 0, 4, "secp224k1" }, /* 306 */
- { 0x21, 308, 0, 4, "secp224r1" }, /* 307 */
- { 0x22, 309, 0, 4, "secp384r1" }, /* 308 */
- { 0x23, 310, 0, 4, "secp521r1" }, /* 309 */
- { 0x24, 311, 0, 4, "sect409k1" }, /* 310 */
- { 0x25, 312, 0, 4, "sect409r1" }, /* 311 */
- { 0x26, 313, 0, 4, "sect571k1" }, /* 312 */
- { 0x27, 0, 0, 4, "sect571r1" }, /* 313 */
- {0x60, 360, 1, 0, "" }, /* 314 */
- { 0x86, 0, 1, 1, "" }, /* 315 */
- { 0x48, 0, 1, 2, "" }, /* 316 */
- { 0x01, 0, 1, 3, "organization" }, /* 317 */
- { 0x65, 336, 1, 4, "gov" }, /* 318 */
- { 0x03, 0, 1, 5, "csor" }, /* 319 */
- { 0x04, 0, 1, 6, "nistalgorithm" }, /* 320 */
- { 0x01, 331, 1, 7, "aes" }, /* 321 */
- { 0x02, 323, 0, 8, "id-aes128-CBC" }, /* 322 */
- { 0x06, 324, 0, 8, "id-aes128-GCM" }, /* 323 */
- { 0x07, 325, 0, 8, "id-aes128-CCM" }, /* 324 */
- { 0x16, 326, 0, 8, "id-aes192-CBC" }, /* 325 */
- { 0x1A, 327, 0, 8, "id-aes192-GCM" }, /* 326 */
- { 0x1B, 328, 0, 8, "id-aes192-CCM" }, /* 327 */
- { 0x2A, 329, 0, 8, "id-aes256-CBC" }, /* 328 */
- { 0x2E, 330, 0, 8, "id-aes256-GCM" }, /* 329 */
- { 0x2F, 0, 0, 8, "id-aes256-CCM" }, /* 330 */
- { 0x02, 0, 1, 7, "hashalgs" }, /* 331 */
- { 0x01, 333, 0, 8, "id-SHA-256" }, /* 332 */
- { 0x02, 334, 0, 8, "id-SHA-384" }, /* 333 */
- { 0x03, 335, 0, 8, "id-SHA-512" }, /* 334 */
- { 0x04, 0, 0, 8, "id-SHA-224" }, /* 335 */
- { 0x86, 0, 1, 4, "" }, /* 336 */
- { 0xf8, 0, 1, 5, "" }, /* 337 */
- { 0x42, 350, 1, 6, "netscape" }, /* 338 */
- { 0x01, 345, 1, 7, "" }, /* 339 */
- { 0x01, 341, 0, 8, "nsCertType" }, /* 340 */
- { 0x03, 342, 0, 8, "nsRevocationUrl" }, /* 341 */
- { 0x04, 343, 0, 8, "nsCaRevocationUrl" }, /* 342 */
- { 0x08, 344, 0, 8, "nsCaPolicyUrl" }, /* 343 */
- { 0x0d, 0, 0, 8, "nsComment" }, /* 344 */
- { 0x03, 348, 1, 7, "directory" }, /* 345 */
- { 0x01, 0, 1, 8, "" }, /* 346 */
- { 0x03, 0, 0, 9, "employeeNumber" }, /* 347 */
- { 0x04, 0, 1, 7, "policy" }, /* 348 */
- { 0x01, 0, 0, 8, "nsSGC" }, /* 349 */
- { 0x45, 0, 1, 6, "verisign" }, /* 350 */
- { 0x01, 0, 1, 7, "pki" }, /* 351 */
- { 0x09, 0, 1, 8, "attributes" }, /* 352 */
- { 0x02, 354, 0, 9, "messageType" }, /* 353 */
- { 0x03, 355, 0, 9, "pkiStatus" }, /* 354 */
- { 0x04, 356, 0, 9, "failInfo" }, /* 355 */
- { 0x05, 357, 0, 9, "senderNonce" }, /* 356 */
- { 0x06, 358, 0, 9, "recipientNonce" }, /* 357 */
- { 0x07, 359, 0, 9, "transID" }, /* 358 */
- { 0x08, 0, 0, 9, "extensionReq" }, /* 359 */
- {0x67, 0, 1, 0, "" }, /* 360 */
- { 0x81, 0, 1, 1, "" }, /* 361 */
- { 0x05, 0, 1, 2, "" }, /* 362 */
- { 0x02, 0, 1, 3, "tcg-attribute" }, /* 363 */
- { 0x01, 365, 0, 4, "tcg-at-tpmManufacturer" }, /* 364 */
- { 0x02, 366, 0, 4, "tcg-at-tpmModel" }, /* 365 */
- { 0x03, 367, 0, 4, "tcg-at-tpmVersion" }, /* 366 */
- { 0x0F, 0, 0, 4, "tcg-at-tpmIdLabel" } /* 367 */
+ { 0x2E, 36, 0, 2, "dnQualifier" }, /* 35 */
+ { 0x48, 0, 0, 2, "role" }, /* 36 */
+ { 0x1D, 0, 1, 1, "id-ce" }, /* 37 */
+ { 0x09, 39, 0, 2, "subjectDirectoryAttrs" }, /* 38 */
+ { 0x0E, 40, 0, 2, "subjectKeyIdentifier" }, /* 39 */
+ { 0x0F, 41, 0, 2, "keyUsage" }, /* 40 */
+ { 0x10, 42, 0, 2, "privateKeyUsagePeriod" }, /* 41 */
+ { 0x11, 43, 0, 2, "subjectAltName" }, /* 42 */
+ { 0x12, 44, 0, 2, "issuerAltName" }, /* 43 */
+ { 0x13, 45, 0, 2, "basicConstraints" }, /* 44 */
+ { 0x14, 46, 0, 2, "crlNumber" }, /* 45 */
+ { 0x15, 47, 0, 2, "reasonCode" }, /* 46 */
+ { 0x17, 48, 0, 2, "holdInstructionCode" }, /* 47 */
+ { 0x18, 49, 0, 2, "invalidityDate" }, /* 48 */
+ { 0x1B, 50, 0, 2, "deltaCrlIndicator" }, /* 49 */
+ { 0x1C, 51, 0, 2, "issuingDistributionPoint" }, /* 50 */
+ { 0x1D, 52, 0, 2, "certificateIssuer" }, /* 51 */
+ { 0x1E, 53, 0, 2, "nameConstraints" }, /* 52 */
+ { 0x1F, 54, 0, 2, "crlDistributionPoints" }, /* 53 */
+ { 0x20, 56, 1, 2, "certificatePolicies" }, /* 54 */
+ { 0x00, 0, 0, 3, "anyPolicy" }, /* 55 */
+ { 0x21, 57, 0, 2, "policyMappings" }, /* 56 */
+ { 0x23, 58, 0, 2, "authorityKeyIdentifier" }, /* 57 */
+ { 0x24, 59, 0, 2, "policyConstraints" }, /* 58 */
+ { 0x25, 61, 1, 2, "extendedKeyUsage" }, /* 59 */
+ { 0x00, 0, 0, 3, "anyExtendedKeyUsage" }, /* 60 */
+ { 0x2E, 62, 0, 2, "freshestCRL" }, /* 61 */
+ { 0x36, 63, 0, 2, "inhibitAnyPolicy" }, /* 62 */
+ { 0x37, 64, 0, 2, "targetInformation" }, /* 63 */
+ { 0x38, 0, 0, 2, "noRevAvail" }, /* 64 */
+ {0x2A, 169, 1, 0, "" }, /* 65 */
+ { 0x83, 78, 1, 1, "" }, /* 66 */
+ { 0x08, 0, 1, 2, "jp" }, /* 67 */
+ { 0x8C, 0, 1, 3, "" }, /* 68 */
+ { 0x9A, 0, 1, 4, "" }, /* 69 */
+ { 0x4B, 0, 1, 5, "" }, /* 70 */
+ { 0x3D, 0, 1, 6, "" }, /* 71 */
+ { 0x01, 0, 1, 7, "security" }, /* 72 */
+ { 0x01, 0, 1, 8, "algorithm" }, /* 73 */
+ { 0x01, 0, 1, 9, "symm-encryption-alg" }, /* 74 */
+ { 0x02, 76, 0, 10, "camellia128-cbc" }, /* 75 */
+ { 0x03, 77, 0, 10, "camellia192-cbc" }, /* 76 */
+ { 0x04, 0, 0, 10, "camellia256-cbc" }, /* 77 */
+ { 0x86, 0, 1, 1, "" }, /* 78 */
+ { 0x48, 0, 1, 2, "us" }, /* 79 */
+ { 0x86, 128, 1, 3, "" }, /* 80 */
+ { 0xF6, 86, 1, 4, "" }, /* 81 */
+ { 0x7D, 0, 1, 5, "NortelNetworks" }, /* 82 */
+ { 0x07, 0, 1, 6, "Entrust" }, /* 83 */
+ { 0x41, 0, 1, 7, "nsn-ce" }, /* 84 */
+ { 0x00, 0, 0, 8, "entrustVersInfo" }, /* 85 */
+ { 0xF7, 0, 1, 4, "" }, /* 86 */
+ { 0x0D, 0, 1, 5, "RSADSI" }, /* 87 */
+ { 0x01, 123, 1, 6, "PKCS" }, /* 88 */
+ { 0x01, 100, 1, 7, "PKCS-1" }, /* 89 */
+ { 0x01, 91, 0, 8, "rsaEncryption" }, /* 90 */
+ { 0x02, 92, 0, 8, "md2WithRSAEncryption" }, /* 91 */
+ { 0x04, 93, 0, 8, "md5WithRSAEncryption" }, /* 92 */
+ { 0x05, 94, 0, 8, "sha-1WithRSAEncryption" }, /* 93 */
+ { 0x07, 95, 0, 8, "id-RSAES-OAEP" }, /* 94 */
+ { 0x09, 96, 0, 8, "id-pSpecified" }, /* 95 */
+ { 0x0B, 97, 0, 8, "sha256WithRSAEncryption" }, /* 96 */
+ { 0x0C, 98, 0, 8, "sha384WithRSAEncryption" }, /* 97 */
+ { 0x0D, 99, 0, 8, "sha512WithRSAEncryption" }, /* 98 */
+ { 0x0E, 0, 0, 8, "sha224WithRSAEncryption" }, /* 99 */
+ { 0x05, 105, 1, 7, "PKCS-5" }, /* 100 */
+ { 0x03, 102, 0, 8, "pbeWithMD5AndDES-CBC" }, /* 101 */
+ { 0x0A, 103, 0, 8, "pbeWithSHA1AndDES-CBC" }, /* 102 */
+ { 0x0C, 104, 0, 8, "id-PBKDF2" }, /* 103 */
+ { 0x0D, 0, 0, 8, "id-PBES2" }, /* 104 */
+ { 0x07, 112, 1, 7, "PKCS-7" }, /* 105 */
+ { 0x01, 107, 0, 8, "data" }, /* 106 */
+ { 0x02, 108, 0, 8, "signedData" }, /* 107 */
+ { 0x03, 109, 0, 8, "envelopedData" }, /* 108 */
+ { 0x04, 110, 0, 8, "signedAndEnvelopedData" }, /* 109 */
+ { 0x05, 111, 0, 8, "digestedData" }, /* 110 */
+ { 0x06, 0, 0, 8, "encryptedData" }, /* 111 */
+ { 0x09, 0, 1, 7, "PKCS-9" }, /* 112 */
+ { 0x01, 114, 0, 8, "E" }, /* 113 */
+ { 0x02, 115, 0, 8, "unstructuredName" }, /* 114 */
+ { 0x03, 116, 0, 8, "contentType" }, /* 115 */
+ { 0x04, 117, 0, 8, "messageDigest" }, /* 116 */
+ { 0x05, 118, 0, 8, "signingTime" }, /* 117 */
+ { 0x06, 119, 0, 8, "counterSignature" }, /* 118 */
+ { 0x07, 120, 0, 8, "challengePassword" }, /* 119 */
+ { 0x08, 121, 0, 8, "unstructuredAddress" }, /* 120 */
+ { 0x0E, 122, 0, 8, "extensionRequest" }, /* 121 */
+ { 0x0F, 0, 0, 8, "S/MIME Capabilities" }, /* 122 */
+ { 0x02, 126, 1, 6, "digestAlgorithm" }, /* 123 */
+ { 0x02, 125, 0, 7, "md2" }, /* 124 */
+ { 0x05, 0, 0, 7, "md5" }, /* 125 */
+ { 0x03, 0, 1, 6, "encryptionAlgorithm" }, /* 126 */
+ { 0x07, 0, 0, 7, "3des-ede-cbc" }, /* 127 */
+ { 0xCE, 0, 1, 3, "" }, /* 128 */
+ { 0x3D, 0, 1, 4, "ansi-X9-62" }, /* 129 */
+ { 0x02, 132, 1, 5, "id-publicKeyType" }, /* 130 */
+ { 0x01, 0, 0, 6, "id-ecPublicKey" }, /* 131 */
+ { 0x03, 162, 1, 5, "ellipticCurve" }, /* 132 */
+ { 0x00, 154, 1, 6, "c-TwoCurve" }, /* 133 */
+ { 0x01, 135, 0, 7, "c2pnb163v1" }, /* 134 */
+ { 0x02, 136, 0, 7, "c2pnb163v2" }, /* 135 */
+ { 0x03, 137, 0, 7, "c2pnb163v3" }, /* 136 */
+ { 0x04, 138, 0, 7, "c2pnb176w1" }, /* 137 */
+ { 0x05, 139, 0, 7, "c2tnb191v1" }, /* 138 */
+ { 0x06, 140, 0, 7, "c2tnb191v2" }, /* 139 */
+ { 0x07, 141, 0, 7, "c2tnb191v3" }, /* 140 */
+ { 0x08, 142, 0, 7, "c2onb191v4" }, /* 141 */
+ { 0x09, 143, 0, 7, "c2onb191v5" }, /* 142 */
+ { 0x0A, 144, 0, 7, "c2pnb208w1" }, /* 143 */
+ { 0x0B, 145, 0, 7, "c2tnb239v1" }, /* 144 */
+ { 0x0C, 146, 0, 7, "c2tnb239v2" }, /* 145 */
+ { 0x0D, 147, 0, 7, "c2tnb239v3" }, /* 146 */
+ { 0x0E, 148, 0, 7, "c2onb239v4" }, /* 147 */
+ { 0x0F, 149, 0, 7, "c2onb239v5" }, /* 148 */
+ { 0x10, 150, 0, 7, "c2pnb272w1" }, /* 149 */
+ { 0x11, 151, 0, 7, "c2pnb304w1" }, /* 150 */
+ { 0x12, 152, 0, 7, "c2tnb359v1" }, /* 151 */
+ { 0x13, 153, 0, 7, "c2pnb368w1" }, /* 152 */
+ { 0x14, 0, 0, 7, "c2tnb431r1" }, /* 153 */
+ { 0x01, 0, 1, 6, "primeCurve" }, /* 154 */
+ { 0x01, 156, 0, 7, "prime192v1" }, /* 155 */
+ { 0x02, 157, 0, 7, "prime192v2" }, /* 156 */
+ { 0x03, 158, 0, 7, "prime192v3" }, /* 157 */
+ { 0x04, 159, 0, 7, "prime239v1" }, /* 158 */
+ { 0x05, 160, 0, 7, "prime239v2" }, /* 159 */
+ { 0x06, 161, 0, 7, "prime239v3" }, /* 160 */
+ { 0x07, 0, 0, 7, "prime256v1" }, /* 161 */
+ { 0x04, 0, 1, 5, "id-ecSigType" }, /* 162 */
+ { 0x01, 164, 0, 6, "ecdsa-with-SHA1" }, /* 163 */
+ { 0x03, 0, 1, 6, "ecdsa-with-Specified" }, /* 164 */
+ { 0x01, 166, 0, 7, "ecdsa-with-SHA224" }, /* 165 */
+ { 0x02, 167, 0, 7, "ecdsa-with-SHA256" }, /* 166 */
+ { 0x03, 168, 0, 7, "ecdsa-with-SHA384" }, /* 167 */
+ { 0x04, 0, 0, 7, "ecdsa-with-SHA512" }, /* 168 */
+ {0x2B, 320, 1, 0, "" }, /* 169 */
+ { 0x06, 234, 1, 1, "dod" }, /* 170 */
+ { 0x01, 0, 1, 2, "internet" }, /* 171 */
+ { 0x04, 194, 1, 3, "private" }, /* 172 */
+ { 0x01, 0, 1, 4, "enterprise" }, /* 173 */
+ { 0x82, 187, 1, 5, "" }, /* 174 */
+ { 0x37, 184, 1, 6, "Microsoft" }, /* 175 */
+ { 0x0A, 180, 1, 7, "" }, /* 176 */
+ { 0x03, 0, 1, 8, "" }, /* 177 */
+ { 0x03, 179, 0, 9, "msSGC" }, /* 178 */
+ { 0x04, 0, 0, 9, "msEncryptingFileSystem" }, /* 179 */
+ { 0x14, 0, 1, 7, "msEnrollmentInfrastructure"}, /* 180 */
+ { 0x02, 0, 1, 8, "msCertificateTypeExtension"}, /* 181 */
+ { 0x02, 183, 0, 9, "msSmartcardLogon" }, /* 182 */
+ { 0x03, 0, 0, 9, "msUPN" }, /* 183 */
+ { 0xA0, 0, 1, 6, "" }, /* 184 */
+ { 0x2A, 0, 1, 7, "ITA" }, /* 185 */
+ { 0x01, 0, 0, 8, "strongSwan" }, /* 186 */
+ { 0x89, 0, 1, 5, "" }, /* 187 */
+ { 0x31, 0, 1, 6, "" }, /* 188 */
+ { 0x01, 0, 1, 7, "" }, /* 189 */
+ { 0x01, 0, 1, 8, "" }, /* 190 */
+ { 0x02, 0, 1, 9, "" }, /* 191 */
+ { 0x02, 0, 1, 10, "" }, /* 192 */
+ { 0x4B, 0, 0, 11, "TCGID" }, /* 193 */
+ { 0x05, 0, 1, 3, "security" }, /* 194 */
+ { 0x05, 0, 1, 4, "mechanisms" }, /* 195 */
+ { 0x07, 0, 1, 5, "id-pkix" }, /* 196 */
+ { 0x01, 201, 1, 6, "id-pe" }, /* 197 */
+ { 0x01, 199, 0, 7, "authorityInfoAccess" }, /* 198 */
+ { 0x03, 200, 0, 7, "qcStatements" }, /* 199 */
+ { 0x07, 0, 0, 7, "ipAddrBlocks" }, /* 200 */
+ { 0x02, 204, 1, 6, "id-qt" }, /* 201 */
+ { 0x01, 203, 0, 7, "cps" }, /* 202 */
+ { 0x02, 0, 0, 7, "unotice" }, /* 203 */
+ { 0x03, 214, 1, 6, "id-kp" }, /* 204 */
+ { 0x01, 206, 0, 7, "serverAuth" }, /* 205 */
+ { 0x02, 207, 0, 7, "clientAuth" }, /* 206 */
+ { 0x03, 208, 0, 7, "codeSigning" }, /* 207 */
+ { 0x04, 209, 0, 7, "emailProtection" }, /* 208 */
+ { 0x05, 210, 0, 7, "ipsecEndSystem" }, /* 209 */
+ { 0x06, 211, 0, 7, "ipsecTunnel" }, /* 210 */
+ { 0x07, 212, 0, 7, "ipsecUser" }, /* 211 */
+ { 0x08, 213, 0, 7, "timeStamping" }, /* 212 */
+ { 0x09, 0, 0, 7, "ocspSigning" }, /* 213 */
+ { 0x08, 216, 1, 6, "id-otherNames" }, /* 214 */
+ { 0x05, 0, 0, 7, "xmppAddr" }, /* 215 */
+ { 0x0A, 221, 1, 6, "id-aca" }, /* 216 */
+ { 0x01, 218, 0, 7, "authenticationInfo" }, /* 217 */
+ { 0x02, 219, 0, 7, "accessIdentity" }, /* 218 */
+ { 0x03, 220, 0, 7, "chargingIdentity" }, /* 219 */
+ { 0x04, 0, 0, 7, "group" }, /* 220 */
+ { 0x0B, 222, 0, 6, "subjectInfoAccess" }, /* 221 */
+ { 0x30, 0, 1, 6, "id-ad" }, /* 222 */
+ { 0x01, 231, 1, 7, "ocsp" }, /* 223 */
+ { 0x01, 225, 0, 8, "basic" }, /* 224 */
+ { 0x02, 226, 0, 8, "nonce" }, /* 225 */
+ { 0x03, 227, 0, 8, "crl" }, /* 226 */
+ { 0x04, 228, 0, 8, "response" }, /* 227 */
+ { 0x05, 229, 0, 8, "noCheck" }, /* 228 */
+ { 0x06, 230, 0, 8, "archiveCutoff" }, /* 229 */
+ { 0x07, 0, 0, 8, "serviceLocator" }, /* 230 */
+ { 0x02, 232, 0, 7, "caIssuers" }, /* 231 */
+ { 0x03, 233, 0, 7, "timeStamping" }, /* 232 */
+ { 0x05, 0, 0, 7, "caRepository" }, /* 233 */
+ { 0x0E, 240, 1, 1, "oiw" }, /* 234 */
+ { 0x03, 0, 1, 2, "secsig" }, /* 235 */
+ { 0x02, 0, 1, 3, "algorithms" }, /* 236 */
+ { 0x07, 238, 0, 4, "des-cbc" }, /* 237 */
+ { 0x1A, 239, 0, 4, "sha-1" }, /* 238 */
+ { 0x1D, 0, 0, 4, "sha-1WithRSASignature" }, /* 239 */
+ { 0x24, 286, 1, 1, "TeleTrusT" }, /* 240 */
+ { 0x03, 0, 1, 2, "algorithm" }, /* 241 */
+ { 0x03, 0, 1, 3, "signatureAlgorithm" }, /* 242 */
+ { 0x01, 247, 1, 4, "rsaSignature" }, /* 243 */
+ { 0x02, 245, 0, 5, "rsaSigWithripemd160" }, /* 244 */
+ { 0x03, 246, 0, 5, "rsaSigWithripemd128" }, /* 245 */
+ { 0x04, 0, 0, 5, "rsaSigWithripemd256" }, /* 246 */
+ { 0x02, 0, 1, 4, "ecSign" }, /* 247 */
+ { 0x01, 249, 0, 5, "ecSignWithsha1" }, /* 248 */
+ { 0x02, 250, 0, 5, "ecSignWithripemd160" }, /* 249 */
+ { 0x03, 251, 0, 5, "ecSignWithmd2" }, /* 250 */
+ { 0x04, 252, 0, 5, "ecSignWithmd5" }, /* 251 */
+ { 0x05, 269, 1, 5, "ttt-ecg" }, /* 252 */
+ { 0x01, 257, 1, 6, "fieldType" }, /* 253 */
+ { 0x01, 0, 1, 7, "characteristictwoField" }, /* 254 */
+ { 0x01, 0, 1, 8, "basisType" }, /* 255 */
+ { 0x01, 0, 0, 9, "ipBasis" }, /* 256 */
+ { 0x02, 259, 1, 6, "keyType" }, /* 257 */
+ { 0x01, 0, 0, 7, "ecgPublicKey" }, /* 258 */
+ { 0x03, 260, 0, 6, "curve" }, /* 259 */
+ { 0x04, 267, 1, 6, "signatures" }, /* 260 */
+ { 0x01, 262, 0, 7, "ecgdsa-with-RIPEMD160" }, /* 261 */
+ { 0x02, 263, 0, 7, "ecgdsa-with-SHA1" }, /* 262 */
+ { 0x03, 264, 0, 7, "ecgdsa-with-SHA224" }, /* 263 */
+ { 0x04, 265, 0, 7, "ecgdsa-with-SHA256" }, /* 264 */
+ { 0x05, 266, 0, 7, "ecgdsa-with-SHA384" }, /* 265 */
+ { 0x06, 0, 0, 7, "ecgdsa-with-SHA512" }, /* 266 */
+ { 0x05, 0, 1, 6, "module" }, /* 267 */
+ { 0x01, 0, 0, 7, "1" }, /* 268 */
+ { 0x08, 0, 1, 5, "ecStdCurvesAndGeneration" }, /* 269 */
+ { 0x01, 0, 1, 6, "ellipticCurve" }, /* 270 */
+ { 0x01, 0, 1, 7, "versionOne" }, /* 271 */
+ { 0x01, 273, 0, 8, "brainpoolP160r1" }, /* 272 */
+ { 0x02, 274, 0, 8, "brainpoolP160t1" }, /* 273 */
+ { 0x03, 275, 0, 8, "brainpoolP192r1" }, /* 274 */
+ { 0x04, 276, 0, 8, "brainpoolP192t1" }, /* 275 */
+ { 0x05, 277, 0, 8, "brainpoolP224r1" }, /* 276 */
+ { 0x06, 278, 0, 8, "brainpoolP224t1" }, /* 277 */
+ { 0x07, 279, 0, 8, "brainpoolP256r1" }, /* 278 */
+ { 0x08, 280, 0, 8, "brainpoolP256t1" }, /* 279 */
+ { 0x09, 281, 0, 8, "brainpoolP320r1" }, /* 280 */
+ { 0x0A, 282, 0, 8, "brainpoolP320t1" }, /* 281 */
+ { 0x0B, 283, 0, 8, "brainpoolP384r1" }, /* 282 */
+ { 0x0C, 284, 0, 8, "brainpoolP384t1" }, /* 283 */
+ { 0x0D, 285, 0, 8, "brainpoolP512r1" }, /* 284 */
+ { 0x0E, 0, 0, 8, "brainpoolP512t1" }, /* 285 */
+ { 0x81, 0, 1, 1, "" }, /* 286 */
+ { 0x04, 0, 1, 2, "Certicom" }, /* 287 */
+ { 0x00, 0, 1, 3, "curve" }, /* 288 */
+ { 0x01, 290, 0, 4, "sect163k1" }, /* 289 */
+ { 0x02, 291, 0, 4, "sect163r1" }, /* 290 */
+ { 0x03, 292, 0, 4, "sect239k1" }, /* 291 */
+ { 0x04, 293, 0, 4, "sect113r1" }, /* 292 */
+ { 0x05, 294, 0, 4, "sect113r2" }, /* 293 */
+ { 0x06, 295, 0, 4, "secp112r1" }, /* 294 */
+ { 0x07, 296, 0, 4, "secp112r2" }, /* 295 */
+ { 0x08, 297, 0, 4, "secp160r1" }, /* 296 */
+ { 0x09, 298, 0, 4, "secp160k1" }, /* 297 */
+ { 0x0A, 299, 0, 4, "secp256k1" }, /* 298 */
+ { 0x0F, 300, 0, 4, "sect163r2" }, /* 299 */
+ { 0x10, 301, 0, 4, "sect283k1" }, /* 300 */
+ { 0x11, 302, 0, 4, "sect283r1" }, /* 301 */
+ { 0x16, 303, 0, 4, "sect131r1" }, /* 302 */
+ { 0x17, 304, 0, 4, "sect131r2" }, /* 303 */
+ { 0x18, 305, 0, 4, "sect193r1" }, /* 304 */
+ { 0x19, 306, 0, 4, "sect193r2" }, /* 305 */
+ { 0x1A, 307, 0, 4, "sect233k1" }, /* 306 */
+ { 0x1B, 308, 0, 4, "sect233r1" }, /* 307 */
+ { 0x1C, 309, 0, 4, "secp128r1" }, /* 308 */
+ { 0x1D, 310, 0, 4, "secp128r2" }, /* 309 */
+ { 0x1E, 311, 0, 4, "secp160r2" }, /* 310 */
+ { 0x1F, 312, 0, 4, "secp192k1" }, /* 311 */
+ { 0x20, 313, 0, 4, "secp224k1" }, /* 312 */
+ { 0x21, 314, 0, 4, "secp224r1" }, /* 313 */
+ { 0x22, 315, 0, 4, "secp384r1" }, /* 314 */
+ { 0x23, 316, 0, 4, "secp521r1" }, /* 315 */
+ { 0x24, 317, 0, 4, "sect409k1" }, /* 316 */
+ { 0x25, 318, 0, 4, "sect409r1" }, /* 317 */
+ { 0x26, 319, 0, 4, "sect571k1" }, /* 318 */
+ { 0x27, 0, 0, 4, "sect571r1" }, /* 319 */
+ {0x60, 366, 1, 0, "" }, /* 320 */
+ { 0x86, 0, 1, 1, "" }, /* 321 */
+ { 0x48, 0, 1, 2, "" }, /* 322 */
+ { 0x01, 0, 1, 3, "organization" }, /* 323 */
+ { 0x65, 342, 1, 4, "gov" }, /* 324 */
+ { 0x03, 0, 1, 5, "csor" }, /* 325 */
+ { 0x04, 0, 1, 6, "nistalgorithm" }, /* 326 */
+ { 0x01, 337, 1, 7, "aes" }, /* 327 */
+ { 0x02, 329, 0, 8, "id-aes128-CBC" }, /* 328 */
+ { 0x06, 330, 0, 8, "id-aes128-GCM" }, /* 329 */
+ { 0x07, 331, 0, 8, "id-aes128-CCM" }, /* 330 */
+ { 0x16, 332, 0, 8, "id-aes192-CBC" }, /* 331 */
+ { 0x1A, 333, 0, 8, "id-aes192-GCM" }, /* 332 */
+ { 0x1B, 334, 0, 8, "id-aes192-CCM" }, /* 333 */
+ { 0x2A, 335, 0, 8, "id-aes256-CBC" }, /* 334 */
+ { 0x2E, 336, 0, 8, "id-aes256-GCM" }, /* 335 */
+ { 0x2F, 0, 0, 8, "id-aes256-CCM" }, /* 336 */
+ { 0x02, 0, 1, 7, "hashalgs" }, /* 337 */
+ { 0x01, 339, 0, 8, "id-SHA-256" }, /* 338 */
+ { 0x02, 340, 0, 8, "id-SHA-384" }, /* 339 */
+ { 0x03, 341, 0, 8, "id-SHA-512" }, /* 340 */
+ { 0x04, 0, 0, 8, "id-SHA-224" }, /* 341 */
+ { 0x86, 0, 1, 4, "" }, /* 342 */
+ { 0xf8, 0, 1, 5, "" }, /* 343 */
+ { 0x42, 356, 1, 6, "netscape" }, /* 344 */
+ { 0x01, 351, 1, 7, "" }, /* 345 */
+ { 0x01, 347, 0, 8, "nsCertType" }, /* 346 */
+ { 0x03, 348, 0, 8, "nsRevocationUrl" }, /* 347 */
+ { 0x04, 349, 0, 8, "nsCaRevocationUrl" }, /* 348 */
+ { 0x08, 350, 0, 8, "nsCaPolicyUrl" }, /* 349 */
+ { 0x0d, 0, 0, 8, "nsComment" }, /* 350 */
+ { 0x03, 354, 1, 7, "directory" }, /* 351 */
+ { 0x01, 0, 1, 8, "" }, /* 352 */
+ { 0x03, 0, 0, 9, "employeeNumber" }, /* 353 */
+ { 0x04, 0, 1, 7, "policy" }, /* 354 */
+ { 0x01, 0, 0, 8, "nsSGC" }, /* 355 */
+ { 0x45, 0, 1, 6, "verisign" }, /* 356 */
+ { 0x01, 0, 1, 7, "pki" }, /* 357 */
+ { 0x09, 0, 1, 8, "attributes" }, /* 358 */
+ { 0x02, 360, 0, 9, "messageType" }, /* 359 */
+ { 0x03, 361, 0, 9, "pkiStatus" }, /* 360 */
+ { 0x04, 362, 0, 9, "failInfo" }, /* 361 */
+ { 0x05, 363, 0, 9, "senderNonce" }, /* 362 */
+ { 0x06, 364, 0, 9, "recipientNonce" }, /* 363 */
+ { 0x07, 365, 0, 9, "transID" }, /* 364 */
+ { 0x08, 0, 0, 9, "extensionReq" }, /* 365 */
+ {0x67, 0, 1, 0, "" }, /* 366 */
+ { 0x81, 0, 1, 1, "" }, /* 367 */
+ { 0x05, 0, 1, 2, "" }, /* 368 */
+ { 0x02, 0, 1, 3, "tcg-attribute" }, /* 369 */
+ { 0x01, 371, 0, 4, "tcg-at-tpmManufacturer" }, /* 370 */
+ { 0x02, 372, 0, 4, "tcg-at-tpmModel" }, /* 371 */
+ { 0x03, 373, 0, 4, "tcg-at-tpmVersion" }, /* 372 */
+ { 0x0F, 0, 0, 4, "tcg-at-tpmIdLabel" } /* 373 */
};
diff --git a/src/libstrongswan/asn1/oid.h b/src/libstrongswan/asn1/oid.h
index 61db061f7..a01c434a9 100644
--- a/src/libstrongswan/asn1/oid.h
+++ b/src/libstrongswan/asn1/oid.h
@@ -39,182 +39,187 @@ extern const oid_t oid_names[];
#define OID_GIVEN_NAME 32
#define OID_INITIALS 33
#define OID_UNIQUE_IDENTIFIER 34
-#define OID_ROLE 35
-#define OID_SUBJECT_KEY_ID 38
-#define OID_KEY_USAGE 39
-#define OID_SUBJECT_ALT_NAME 41
-#define OID_BASIC_CONSTRAINTS 43
-#define OID_CRL_NUMBER 44
-#define OID_CRL_REASON_CODE 45
-#define OID_DELTA_CRL_INDICATOR 48
-#define OID_NAME_CONSTRAINTS 51
-#define OID_CRL_DISTRIBUTION_POINTS 52
-#define OID_CERTIFICATE_POLICIES 53
-#define OID_ANY_POLICY 54
-#define OID_POLICY_MAPPINGS 55
-#define OID_AUTHORITY_KEY_ID 56
-#define OID_POLICY_CONSTRAINTS 57
-#define OID_EXTENDED_KEY_USAGE 58
-#define OID_FRESHEST_CRL 60
-#define OID_INHIBIT_ANY_POLICY 61
-#define OID_TARGET_INFORMATION 62
-#define OID_NO_REV_AVAIL 63
-#define OID_CAMELLIA128_CBC 74
-#define OID_CAMELLIA192_CBC 75
-#define OID_CAMELLIA256_CBC 76
-#define OID_RSA_ENCRYPTION 89
-#define OID_MD2_WITH_RSA 90
-#define OID_MD5_WITH_RSA 91
-#define OID_SHA1_WITH_RSA 92
-#define OID_RSAES_OAEP 93
-#define OID_SHA256_WITH_RSA 95
-#define OID_SHA384_WITH_RSA 96
-#define OID_SHA512_WITH_RSA 97
-#define OID_SHA224_WITH_RSA 98
-#define OID_PKCS7_DATA 100
-#define OID_PKCS7_SIGNED_DATA 101
-#define OID_PKCS7_ENVELOPED_DATA 102
-#define OID_PKCS7_SIGNED_ENVELOPED_DATA 103
-#define OID_PKCS7_DIGESTED_DATA 104
-#define OID_PKCS7_ENCRYPTED_DATA 105
-#define OID_EMAIL_ADDRESS 107
-#define OID_UNSTRUCTURED_NAME 108
-#define OID_PKCS9_CONTENT_TYPE 109
-#define OID_PKCS9_MESSAGE_DIGEST 110
-#define OID_PKCS9_SIGNING_TIME 111
-#define OID_CHALLENGE_PASSWORD 113
-#define OID_UNSTRUCTURED_ADDRESS 114
-#define OID_EXTENSION_REQUEST 115
-#define OID_MD2 118
-#define OID_MD5 119
-#define OID_3DES_EDE_CBC 121
-#define OID_EC_PUBLICKEY 125
-#define OID_C2PNB163V1 128
-#define OID_C2PNB163V2 129
-#define OID_C2PNB163V3 130
-#define OID_C2PNB176W1 131
-#define OID_C2PNB191V1 132
-#define OID_C2PNB191V2 133
-#define OID_C2PNB191V3 134
-#define OID_C2PNB191V4 135
-#define OID_C2PNB191V5 136
-#define OID_C2PNB208W1 137
-#define OID_C2PNB239V1 138
-#define OID_C2PNB239V2 139
-#define OID_C2PNB239V3 140
-#define OID_C2PNB239V4 141
-#define OID_C2PNB239V5 142
-#define OID_C2PNB272W1 143
-#define OID_C2PNB304W1 144
-#define OID_C2PNB359V1 145
-#define OID_C2PNB368W1 146
-#define OID_C2PNB431R1 147
-#define OID_PRIME192V1 149
-#define OID_PRIME192V2 150
-#define OID_PRIME192V3 151
-#define OID_PRIME239V1 152
-#define OID_PRIME239V2 153
-#define OID_PRIME239V3 154
-#define OID_PRIME256V1 155
-#define OID_ECDSA_WITH_SHA1 157
-#define OID_ECDSA_WITH_SHA224 159
-#define OID_ECDSA_WITH_SHA256 160
-#define OID_ECDSA_WITH_SHA384 161
-#define OID_ECDSA_WITH_SHA512 162
-#define OID_USER_PRINCIPAL_NAME 177
-#define OID_STRONGSWAN 180
-#define OID_TCGID 187
-#define OID_AUTHORITY_INFO_ACCESS 192
-#define OID_IP_ADDR_BLOCKS 194
-#define OID_POLICY_QUALIFIER_CPS 196
-#define OID_POLICY_QUALIFIER_UNOTICE 197
-#define OID_SERVER_AUTH 199
-#define OID_CLIENT_AUTH 200
-#define OID_OCSP_SIGNING 207
-#define OID_XMPP_ADDR 209
-#define OID_AUTHENTICATION_INFO 211
-#define OID_ACCESS_IDENTITY 212
-#define OID_CHARGING_IDENTITY 213
-#define OID_GROUP 214
-#define OID_OCSP 217
-#define OID_BASIC 218
-#define OID_NONCE 219
-#define OID_CRL 220
-#define OID_RESPONSE 221
-#define OID_NO_CHECK 222
-#define OID_ARCHIVE_CUTOFF 223
-#define OID_SERVICE_LOCATOR 224
-#define OID_CA_ISSUERS 225
-#define OID_DES_CBC 231
-#define OID_SHA1 232
-#define OID_SHA1_WITH_RSA_OIW 233
-#define OID_ECGDSA_PUBKEY 252
-#define OID_ECGDSA_SIG_WITH_RIPEMD160 255
-#define OID_ECGDSA_SIG_WITH_SHA1 256
-#define OID_ECGDSA_SIG_WITH_SHA224 257
-#define OID_ECGDSA_SIG_WITH_SHA256 258
-#define OID_ECGDSA_SIG_WITH_SHA384 259
-#define OID_ECGDSA_SIG_WITH_SHA512 260
-#define OID_SECT163K1 283
-#define OID_SECT163R1 284
-#define OID_SECT239K1 285
-#define OID_SECT113R1 286
-#define OID_SECT113R2 287
-#define OID_SECT112R1 288
-#define OID_SECT112R2 289
-#define OID_SECT160R1 290
-#define OID_SECT160K1 291
-#define OID_SECT256K1 292
-#define OID_SECT163R2 293
-#define OID_SECT283K1 294
-#define OID_SECT283R1 295
-#define OID_SECT131R1 296
-#define OID_SECT131R2 297
-#define OID_SECT193R1 298
-#define OID_SECT193R2 299
-#define OID_SECT233K1 300
-#define OID_SECT233R1 301
-#define OID_SECT128R1 302
-#define OID_SECT128R2 303
-#define OID_SECT160R2 304
-#define OID_SECT192K1 305
-#define OID_SECT224K1 306
-#define OID_SECT224R1 307
-#define OID_SECT384R1 308
-#define OID_SECT521R1 309
-#define OID_SECT409K1 310
-#define OID_SECT409R1 311
-#define OID_SECT571K1 312
-#define OID_SECT571R1 313
-#define OID_AES128_CBC 322
-#define OID_AES128_GCM 323
-#define OID_AES128_CCM 324
-#define OID_AES192_CBC 325
-#define OID_AES192_GCM 326
-#define OID_AES192_CCM 327
-#define OID_AES256_CBC 328
-#define OID_AES256_GCM 329
-#define OID_AES256_CCM 330
-#define OID_SHA256 332
-#define OID_SHA384 333
-#define OID_SHA512 334
-#define OID_SHA224 335
-#define OID_NS_REVOCATION_URL 341
-#define OID_NS_CA_REVOCATION_URL 342
-#define OID_NS_CA_POLICY_URL 343
-#define OID_NS_COMMENT 344
-#define OID_EMPLOYEE_NUMBER 347
-#define OID_PKI_MESSAGE_TYPE 353
-#define OID_PKI_STATUS 354
-#define OID_PKI_FAIL_INFO 355
-#define OID_PKI_SENDER_NONCE 356
-#define OID_PKI_RECIPIENT_NONCE 357
-#define OID_PKI_TRANS_ID 358
-#define OID_TPM_MANUFACTURER 364
-#define OID_TPM_MODEL 365
-#define OID_TPM_VERSION 366
-#define OID_TPM_ID_LABEL 367
+#define OID_DN_QUALIFIER 35
+#define OID_ROLE 36
+#define OID_SUBJECT_KEY_ID 39
+#define OID_KEY_USAGE 40
+#define OID_SUBJECT_ALT_NAME 42
+#define OID_BASIC_CONSTRAINTS 44
+#define OID_CRL_NUMBER 45
+#define OID_CRL_REASON_CODE 46
+#define OID_DELTA_CRL_INDICATOR 49
+#define OID_NAME_CONSTRAINTS 52
+#define OID_CRL_DISTRIBUTION_POINTS 53
+#define OID_CERTIFICATE_POLICIES 54
+#define OID_ANY_POLICY 55
+#define OID_POLICY_MAPPINGS 56
+#define OID_AUTHORITY_KEY_ID 57
+#define OID_POLICY_CONSTRAINTS 58
+#define OID_EXTENDED_KEY_USAGE 59
+#define OID_FRESHEST_CRL 61
+#define OID_INHIBIT_ANY_POLICY 62
+#define OID_TARGET_INFORMATION 63
+#define OID_NO_REV_AVAIL 64
+#define OID_CAMELLIA128_CBC 75
+#define OID_CAMELLIA192_CBC 76
+#define OID_CAMELLIA256_CBC 77
+#define OID_RSA_ENCRYPTION 90
+#define OID_MD2_WITH_RSA 91
+#define OID_MD5_WITH_RSA 92
+#define OID_SHA1_WITH_RSA 93
+#define OID_RSAES_OAEP 94
+#define OID_SHA256_WITH_RSA 96
+#define OID_SHA384_WITH_RSA 97
+#define OID_SHA512_WITH_RSA 98
+#define OID_SHA224_WITH_RSA 99
+#define OID_PBE_MD5_DES_CBC 101
+#define OID_PBE_SHA1_DES_CBC 102
+#define OID_PBKDF2 103
+#define OID_PBES2 104
+#define OID_PKCS7_DATA 106
+#define OID_PKCS7_SIGNED_DATA 107
+#define OID_PKCS7_ENVELOPED_DATA 108
+#define OID_PKCS7_SIGNED_ENVELOPED_DATA 109
+#define OID_PKCS7_DIGESTED_DATA 110
+#define OID_PKCS7_ENCRYPTED_DATA 111
+#define OID_EMAIL_ADDRESS 113
+#define OID_UNSTRUCTURED_NAME 114
+#define OID_PKCS9_CONTENT_TYPE 115
+#define OID_PKCS9_MESSAGE_DIGEST 116
+#define OID_PKCS9_SIGNING_TIME 117
+#define OID_CHALLENGE_PASSWORD 119
+#define OID_UNSTRUCTURED_ADDRESS 120
+#define OID_EXTENSION_REQUEST 121
+#define OID_MD2 124
+#define OID_MD5 125
+#define OID_3DES_EDE_CBC 127
+#define OID_EC_PUBLICKEY 131
+#define OID_C2PNB163V1 134
+#define OID_C2PNB163V2 135
+#define OID_C2PNB163V3 136
+#define OID_C2PNB176W1 137
+#define OID_C2PNB191V1 138
+#define OID_C2PNB191V2 139
+#define OID_C2PNB191V3 140
+#define OID_C2PNB191V4 141
+#define OID_C2PNB191V5 142
+#define OID_C2PNB208W1 143
+#define OID_C2PNB239V1 144
+#define OID_C2PNB239V2 145
+#define OID_C2PNB239V3 146
+#define OID_C2PNB239V4 147
+#define OID_C2PNB239V5 148
+#define OID_C2PNB272W1 149
+#define OID_C2PNB304W1 150
+#define OID_C2PNB359V1 151
+#define OID_C2PNB368W1 152
+#define OID_C2PNB431R1 153
+#define OID_PRIME192V1 155
+#define OID_PRIME192V2 156
+#define OID_PRIME192V3 157
+#define OID_PRIME239V1 158
+#define OID_PRIME239V2 159
+#define OID_PRIME239V3 160
+#define OID_PRIME256V1 161
+#define OID_ECDSA_WITH_SHA1 163
+#define OID_ECDSA_WITH_SHA224 165
+#define OID_ECDSA_WITH_SHA256 166
+#define OID_ECDSA_WITH_SHA384 167
+#define OID_ECDSA_WITH_SHA512 168
+#define OID_USER_PRINCIPAL_NAME 183
+#define OID_STRONGSWAN 186
+#define OID_TCGID 193
+#define OID_AUTHORITY_INFO_ACCESS 198
+#define OID_IP_ADDR_BLOCKS 200
+#define OID_POLICY_QUALIFIER_CPS 202
+#define OID_POLICY_QUALIFIER_UNOTICE 203
+#define OID_SERVER_AUTH 205
+#define OID_CLIENT_AUTH 206
+#define OID_OCSP_SIGNING 213
+#define OID_XMPP_ADDR 215
+#define OID_AUTHENTICATION_INFO 217
+#define OID_ACCESS_IDENTITY 218
+#define OID_CHARGING_IDENTITY 219
+#define OID_GROUP 220
+#define OID_OCSP 223
+#define OID_BASIC 224
+#define OID_NONCE 225
+#define OID_CRL 226
+#define OID_RESPONSE 227
+#define OID_NO_CHECK 228
+#define OID_ARCHIVE_CUTOFF 229
+#define OID_SERVICE_LOCATOR 230
+#define OID_CA_ISSUERS 231
+#define OID_DES_CBC 237
+#define OID_SHA1 238
+#define OID_SHA1_WITH_RSA_OIW 239
+#define OID_ECGDSA_PUBKEY 258
+#define OID_ECGDSA_SIG_WITH_RIPEMD160 261
+#define OID_ECGDSA_SIG_WITH_SHA1 262
+#define OID_ECGDSA_SIG_WITH_SHA224 263
+#define OID_ECGDSA_SIG_WITH_SHA256 264
+#define OID_ECGDSA_SIG_WITH_SHA384 265
+#define OID_ECGDSA_SIG_WITH_SHA512 266
+#define OID_SECT163K1 289
+#define OID_SECT163R1 290
+#define OID_SECT239K1 291
+#define OID_SECT113R1 292
+#define OID_SECT113R2 293
+#define OID_SECT112R1 294
+#define OID_SECT112R2 295
+#define OID_SECT160R1 296
+#define OID_SECT160K1 297
+#define OID_SECT256K1 298
+#define OID_SECT163R2 299
+#define OID_SECT283K1 300
+#define OID_SECT283R1 301
+#define OID_SECT131R1 302
+#define OID_SECT131R2 303
+#define OID_SECT193R1 304
+#define OID_SECT193R2 305
+#define OID_SECT233K1 306
+#define OID_SECT233R1 307
+#define OID_SECT128R1 308
+#define OID_SECT128R2 309
+#define OID_SECT160R2 310
+#define OID_SECT192K1 311
+#define OID_SECT224K1 312
+#define OID_SECT224R1 313
+#define OID_SECT384R1 314
+#define OID_SECT521R1 315
+#define OID_SECT409K1 316
+#define OID_SECT409R1 317
+#define OID_SECT571K1 318
+#define OID_SECT571R1 319
+#define OID_AES128_CBC 328
+#define OID_AES128_GCM 329
+#define OID_AES128_CCM 330
+#define OID_AES192_CBC 331
+#define OID_AES192_GCM 332
+#define OID_AES192_CCM 333
+#define OID_AES256_CBC 334
+#define OID_AES256_GCM 335
+#define OID_AES256_CCM 336
+#define OID_SHA256 338
+#define OID_SHA384 339
+#define OID_SHA512 340
+#define OID_SHA224 341
+#define OID_NS_REVOCATION_URL 347
+#define OID_NS_CA_REVOCATION_URL 348
+#define OID_NS_CA_POLICY_URL 349
+#define OID_NS_COMMENT 350
+#define OID_EMPLOYEE_NUMBER 353
+#define OID_PKI_MESSAGE_TYPE 359
+#define OID_PKI_STATUS 360
+#define OID_PKI_FAIL_INFO 361
+#define OID_PKI_SENDER_NONCE 362
+#define OID_PKI_RECIPIENT_NONCE 363
+#define OID_PKI_TRANS_ID 364
+#define OID_TPM_MANUFACTURER 370
+#define OID_TPM_MODEL 371
+#define OID_TPM_VERSION 372
+#define OID_TPM_ID_LABEL 373
-#define OID_MAX 368
+#define OID_MAX 374
#endif /* OID_H_ */
diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt
index f16287cb2..c3ff1a9e7 100644
--- a/src/libstrongswan/asn1/oid.txt
+++ b/src/libstrongswan/asn1/oid.txt
@@ -33,6 +33,7 @@
0x2A "G" OID_GIVEN_NAME
0x2B "I" OID_INITIALS
0x2D "ID" OID_UNIQUE_IDENTIFIER
+ 0x2E "dnQualifier" OID_DN_QUALIFIER
0x48 "role" OID_ROLE
0x1D "id-ce"
0x09 "subjectDirectoryAttrs"
@@ -97,6 +98,11 @@
0x0C "sha384WithRSAEncryption" OID_SHA384_WITH_RSA
0x0D "sha512WithRSAEncryption" OID_SHA512_WITH_RSA
0x0E "sha224WithRSAEncryption" OID_SHA224_WITH_RSA
+ 0x05 "PKCS-5"
+ 0x03 "pbeWithMD5AndDES-CBC" OID_PBE_MD5_DES_CBC
+ 0x0A "pbeWithSHA1AndDES-CBC" OID_PBE_SHA1_DES_CBC
+ 0x0C "id-PBKDF2" OID_PBKDF2
+ 0x0D "id-PBES2" OID_PBES2
0x07 "PKCS-7"
0x01 "data" OID_PKCS7_DATA
0x02 "signedData" OID_PKCS7_SIGNED_DATA
diff --git a/src/libtls/tls_reader.c b/src/libstrongswan/bio/bio_reader.c
index 2b3cd8cac..fce0d1aef 100644
--- a/src/libtls/tls_reader.c
+++ b/src/libstrongswan/bio/bio_reader.c
@@ -13,21 +13,21 @@
* for more details.
*/
-#include "tls_reader.h"
+#include "bio_reader.h"
#include <debug.h>
-typedef struct private_tls_reader_t private_tls_reader_t;
+typedef struct private_bio_reader_t private_bio_reader_t;
/**
- * Private data of an tls_reader_t object.
+ * Private data of an bio_reader_t object.
*/
-struct private_tls_reader_t {
+struct private_bio_reader_t {
/**
- * Public tls_reader_t interface.
+ * Public bio_reader_t interface.
*/
- tls_reader_t public;
+ bio_reader_t public;
/**
* Remaining data to process
@@ -35,24 +35,24 @@ struct private_tls_reader_t {
chunk_t buf;
};
-METHOD(tls_reader_t, remaining, u_int32_t,
- private_tls_reader_t *this)
+METHOD(bio_reader_t, remaining, u_int32_t,
+ private_bio_reader_t *this)
{
return this->buf.len;
}
-METHOD(tls_reader_t, peek, chunk_t,
- private_tls_reader_t *this)
+METHOD(bio_reader_t, peek, chunk_t,
+ private_bio_reader_t *this)
{
return this->buf;
}
-METHOD(tls_reader_t, read_uint8, bool,
- private_tls_reader_t *this, u_int8_t *res)
+METHOD(bio_reader_t, read_uint8, bool,
+ private_bio_reader_t *this, u_int8_t *res)
{
if (this->buf.len < 1)
{
- DBG1(DBG_TLS, "%d bytes insufficient to parse u_int8 data",
+ DBG1(DBG_LIB, "%d bytes insufficient to parse u_int8 data",
this->buf.len);
return FALSE;
}
@@ -61,12 +61,12 @@ METHOD(tls_reader_t, read_uint8, bool,
return TRUE;
}
-METHOD(tls_reader_t, read_uint16, bool,
- private_tls_reader_t *this, u_int16_t *res)
+METHOD(bio_reader_t, read_uint16, bool,
+ private_bio_reader_t *this, u_int16_t *res)
{
if (this->buf.len < 2)
{
- DBG1(DBG_TLS, "%d bytes insufficient to parse u_int16 data",
+ DBG1(DBG_LIB, "%d bytes insufficient to parse u_int16 data",
this->buf.len);
return FALSE;
}
@@ -75,12 +75,12 @@ METHOD(tls_reader_t, read_uint16, bool,
return TRUE;
}
-METHOD(tls_reader_t, read_uint24, bool,
- private_tls_reader_t *this, u_int32_t *res)
+METHOD(bio_reader_t, read_uint24, bool,
+ private_bio_reader_t *this, u_int32_t *res)
{
if (this->buf.len < 3)
{
- DBG1(DBG_TLS, "%d bytes insufficient to parse u_int24 data",
+ DBG1(DBG_LIB, "%d bytes insufficient to parse u_int24 data",
this->buf.len);
return FALSE;
}
@@ -89,12 +89,12 @@ METHOD(tls_reader_t, read_uint24, bool,
return TRUE;
}
-METHOD(tls_reader_t, read_uint32, bool,
- private_tls_reader_t *this, u_int32_t *res)
+METHOD(bio_reader_t, read_uint32, bool,
+ private_bio_reader_t *this, u_int32_t *res)
{
if (this->buf.len < 4)
{
- DBG1(DBG_TLS, "%d bytes insufficient to parse u_int32 data",
+ DBG1(DBG_LIB, "%d bytes insufficient to parse u_int32 data",
this->buf.len);
return FALSE;
}
@@ -103,12 +103,26 @@ METHOD(tls_reader_t, read_uint32, bool,
return TRUE;
}
-METHOD(tls_reader_t, read_data, bool,
- private_tls_reader_t *this, u_int32_t len, chunk_t *res)
+METHOD(bio_reader_t, read_uint64, bool,
+ private_bio_reader_t *this, u_int64_t *res)
+{
+ if (this->buf.len < 8)
+ {
+ DBG1(DBG_LIB, "%d bytes insufficient to parse u_int64 data",
+ this->buf.len);
+ return FALSE;
+ }
+ *res = untoh64(this->buf.ptr);
+ this->buf = chunk_skip(this->buf, 8);
+ return TRUE;
+}
+
+METHOD(bio_reader_t, read_data, bool,
+ private_bio_reader_t *this, u_int32_t len, chunk_t *res)
{
if (this->buf.len < len)
{
- DBG1(DBG_TLS, "%d bytes insufficient to parse %d bytes of data",
+ DBG1(DBG_LIB, "%d bytes insufficient to parse %d bytes of data",
this->buf.len, len);
return FALSE;
}
@@ -117,8 +131,8 @@ METHOD(tls_reader_t, read_data, bool,
return TRUE;
}
-METHOD(tls_reader_t, read_data8, bool,
- private_tls_reader_t *this, chunk_t *res)
+METHOD(bio_reader_t, read_data8, bool,
+ private_bio_reader_t *this, chunk_t *res)
{
u_int8_t len;
@@ -129,8 +143,8 @@ METHOD(tls_reader_t, read_data8, bool,
return read_data(this, len, res);
}
-METHOD(tls_reader_t, read_data16, bool,
- private_tls_reader_t *this, chunk_t *res)
+METHOD(bio_reader_t, read_data16, bool,
+ private_bio_reader_t *this, chunk_t *res)
{
u_int16_t len;
@@ -141,8 +155,8 @@ METHOD(tls_reader_t, read_data16, bool,
return read_data(this, len, res);
}
-METHOD(tls_reader_t, read_data24, bool,
- private_tls_reader_t *this, chunk_t *res)
+METHOD(bio_reader_t, read_data24, bool,
+ private_bio_reader_t *this, chunk_t *res)
{
u_int32_t len;
@@ -153,8 +167,8 @@ METHOD(tls_reader_t, read_data24, bool,
return read_data(this, len, res);
}
-METHOD(tls_reader_t, read_data32, bool,
- private_tls_reader_t *this, chunk_t *res)
+METHOD(bio_reader_t, read_data32, bool,
+ private_bio_reader_t *this, chunk_t *res)
{
u_int32_t len;
@@ -165,8 +179,8 @@ METHOD(tls_reader_t, read_data32, bool,
return read_data(this, len, res);
}
-METHOD(tls_reader_t, destroy, void,
- private_tls_reader_t *this)
+METHOD(bio_reader_t, destroy, void,
+ private_bio_reader_t *this)
{
free(this);
}
@@ -174,9 +188,9 @@ METHOD(tls_reader_t, destroy, void,
/**
* See header
*/
-tls_reader_t *tls_reader_create(chunk_t data)
+bio_reader_t *bio_reader_create(chunk_t data)
{
- private_tls_reader_t *this;
+ private_bio_reader_t *this;
INIT(this,
.public = {
@@ -186,6 +200,7 @@ tls_reader_t *tls_reader_create(chunk_t data)
.read_uint16 = _read_uint16,
.read_uint24 = _read_uint24,
.read_uint32 = _read_uint32,
+ .read_uint64 = _read_uint64,
.read_data = _read_data,
.read_data8 = _read_data8,
.read_data16 = _read_data16,
diff --git a/src/libtls/tls_reader.h b/src/libstrongswan/bio/bio_reader.h
index a8978b486..85434a784 100644
--- a/src/libtls/tls_reader.h
+++ b/src/libstrongswan/bio/bio_reader.h
@@ -14,35 +14,35 @@
*/
/**
- * @defgroup tls_reader tls_reader
- * @{ @ingroup libtls
+ * @defgroup bio_reader bio_reader
+ * @{ @ingroup bio
*/
-#ifndef TLS_READER_H_
-#define TLS_READER_H_
+#ifndef BIO_READER_H_
+#define BIO_READER_H_
-typedef struct tls_reader_t tls_reader_t;
+typedef struct bio_reader_t bio_reader_t;
#include <library.h>
/**
- * TLS record parser.
+ * Buffered input parser.
*/
-struct tls_reader_t {
+struct bio_reader_t {
/**
* Get the number of remaining bytes.
*
* @return number of remaining bytes in buffer
*/
- u_int32_t (*remaining)(tls_reader_t *this);
+ u_int32_t (*remaining)(bio_reader_t *this);
/**
* Peek the remaining data, not consuming any bytes.
*
* @return remaining data
*/
- chunk_t (*peek)(tls_reader_t *this);
+ chunk_t (*peek)(bio_reader_t *this);
/**
* Read a 8-bit integer from the buffer, advance.
@@ -50,7 +50,7 @@ struct tls_reader_t {
* @param res pointer to result
* @return TRUE if integer read successfully
*/
- bool (*read_uint8)(tls_reader_t *this, u_int8_t *res);
+ bool (*read_uint8)(bio_reader_t *this, u_int8_t *res);
/**
* Read a 16-bit integer from the buffer, advance.
@@ -58,7 +58,7 @@ struct tls_reader_t {
* @param res pointer to result
* @return TRUE if integer read successfully
*/
- bool (*read_uint16)(tls_reader_t *this, u_int16_t *res);
+ bool (*read_uint16)(bio_reader_t *this, u_int16_t *res);
/**
* Read a 24-bit integer from the buffer, advance.
@@ -66,7 +66,7 @@ struct tls_reader_t {
* @param res pointer to result
* @return TRUE if integer read successfully
*/
- bool (*read_uint24)(tls_reader_t *this, u_int32_t *res);
+ bool (*read_uint24)(bio_reader_t *this, u_int32_t *res);
/**
* Read a 32-bit integer from the buffer, advance.
@@ -74,7 +74,15 @@ struct tls_reader_t {
* @param res pointer to result
* @return TRUE if integer read successfully
*/
- bool (*read_uint32)(tls_reader_t *this, u_int32_t *res);
+ bool (*read_uint32)(bio_reader_t *this, u_int32_t *res);
+
+ /**
+ * Read a 64-bit integer from the buffer, advance.
+ *
+ * @param res pointer to result
+ * @return TRUE if integer read successfully
+ */
+ bool (*read_uint64)(bio_reader_t *this, u_int64_t *res);
/**
* Read a chunk of len bytes, advance.
@@ -83,7 +91,7 @@ struct tls_reader_t {
* @param res pointer to result, not cloned
* @return TRUE if data read successfully
*/
- bool (*read_data)(tls_reader_t *this, u_int32_t len, chunk_t *res);
+ bool (*read_data)(bio_reader_t *this, u_int32_t len, chunk_t *res);
/**
* Read a chunk of bytes with a 8-bit length header, advance.
@@ -91,7 +99,7 @@ struct tls_reader_t {
* @param res pointer to result, not cloned
* @return TRUE if data read successfully
*/
- bool (*read_data8)(tls_reader_t *this, chunk_t *res);
+ bool (*read_data8)(bio_reader_t *this, chunk_t *res);
/**
* Read a chunk of bytes with a 16-bit length header, advance.
@@ -99,7 +107,7 @@ struct tls_reader_t {
* @param res pointer to result, not cloned
* @return TRUE if data read successfully
*/
- bool (*read_data16)(tls_reader_t *this, chunk_t *res);
+ bool (*read_data16)(bio_reader_t *this, chunk_t *res);
/**
* Read a chunk of bytes with a 24-bit length header, advance.
@@ -107,7 +115,7 @@ struct tls_reader_t {
* @param res pointer to result, not cloned
* @return TRUE if data read successfully
*/
- bool (*read_data24)(tls_reader_t *this, chunk_t *res);
+ bool (*read_data24)(bio_reader_t *this, chunk_t *res);
/**
* Read a chunk of bytes with a 32-bit length header, advance.
@@ -115,17 +123,17 @@ struct tls_reader_t {
* @param res pointer to result, not cloned
* @return TRUE if data read successfully
*/
- bool (*read_data32)(tls_reader_t *this, chunk_t *res);
+ bool (*read_data32)(bio_reader_t *this, chunk_t *res);
/**
- * Destroy a tls_reader_t.
+ * Destroy a bio_reader_t.
*/
- void (*destroy)(tls_reader_t *this);
+ void (*destroy)(bio_reader_t *this);
};
/**
- * Create a tls_reader instance.
+ * Create a bio_reader instance.
*/
-tls_reader_t *tls_reader_create(chunk_t data);
+bio_reader_t *bio_reader_create(chunk_t data);
-#endif /** tls_reader_H_ @}*/
+#endif /** bio_reader_H_ @}*/
diff --git a/src/libtls/tls_writer.c b/src/libstrongswan/bio/bio_writer.c
index 57c60fdaf..bf373d6ac 100644
--- a/src/libtls/tls_writer.c
+++ b/src/libstrongswan/bio/bio_writer.c
@@ -13,19 +13,19 @@
* for more details.
*/
-#include "tls_writer.h"
+#include "bio_writer.h"
-typedef struct private_tls_writer_t private_tls_writer_t;
+typedef struct private_bio_writer_t private_bio_writer_t;
/**
- * Private data of an tls_writer_t object.
+ * Private data of an bio_writer_t object.
*/
-struct private_tls_writer_t {
+struct private_bio_writer_t {
/**
- * Public tls_writer_t interface.
+ * Public bio_writer_t interface.
*/
- tls_writer_t public;
+ bio_writer_t public;
/**
* Allocated buffer
@@ -46,14 +46,14 @@ struct private_tls_writer_t {
/**
* Increase buffer size
*/
-static void increase(private_tls_writer_t *this)
+static void increase(private_bio_writer_t *this)
{
this->buf.len += this->increase;
this->buf.ptr = realloc(this->buf.ptr, this->buf.len);
}
-METHOD(tls_writer_t, write_uint8, void,
- private_tls_writer_t *this, u_int8_t value)
+METHOD(bio_writer_t, write_uint8, void,
+ private_bio_writer_t *this, u_int8_t value)
{
if (this->used + 1 > this->buf.len)
{
@@ -63,8 +63,8 @@ METHOD(tls_writer_t, write_uint8, void,
this->used += 1;
}
-METHOD(tls_writer_t, write_uint16, void,
- private_tls_writer_t *this, u_int16_t value)
+METHOD(bio_writer_t, write_uint16, void,
+ private_bio_writer_t *this, u_int16_t value)
{
if (this->used + 2 > this->buf.len)
{
@@ -74,8 +74,8 @@ METHOD(tls_writer_t, write_uint16, void,
this->used += 2;
}
-METHOD(tls_writer_t, write_uint24, void,
- private_tls_writer_t *this, u_int32_t value)
+METHOD(bio_writer_t, write_uint24, void,
+ private_bio_writer_t *this, u_int32_t value)
{
if (this->used + 3 > this->buf.len)
{
@@ -86,8 +86,8 @@ METHOD(tls_writer_t, write_uint24, void,
this->used += 3;
}
-METHOD(tls_writer_t, write_uint32, void,
- private_tls_writer_t *this, u_int32_t value)
+METHOD(bio_writer_t, write_uint32, void,
+ private_bio_writer_t *this, u_int32_t value)
{
if (this->used + 4 > this->buf.len)
{
@@ -97,8 +97,19 @@ METHOD(tls_writer_t, write_uint32, void,
this->used += 4;
}
-METHOD(tls_writer_t, write_data, void,
- private_tls_writer_t *this, chunk_t value)
+METHOD(bio_writer_t, write_uint64, void,
+ private_bio_writer_t *this, u_int64_t value)
+{
+ if (this->used + 8 > this->buf.len)
+ {
+ increase(this);
+ }
+ htoun64(this->buf.ptr + this->used, value);
+ this->used += 8;
+}
+
+METHOD(bio_writer_t, write_data, void,
+ private_bio_writer_t *this, chunk_t value)
{
while (this->used + value.len > this->buf.len)
{
@@ -108,36 +119,36 @@ METHOD(tls_writer_t, write_data, void,
this->used += value.len;
}
-METHOD(tls_writer_t, write_data8, void,
- private_tls_writer_t *this, chunk_t value)
+METHOD(bio_writer_t, write_data8, void,
+ private_bio_writer_t *this, chunk_t value)
{
write_uint8(this, value.len);
write_data(this, value);
}
-METHOD(tls_writer_t, write_data16, void,
- private_tls_writer_t *this, chunk_t value)
+METHOD(bio_writer_t, write_data16, void,
+ private_bio_writer_t *this, chunk_t value)
{
write_uint16(this, value.len);
write_data(this, value);
}
-METHOD(tls_writer_t, write_data24, void,
- private_tls_writer_t *this, chunk_t value)
+METHOD(bio_writer_t, write_data24, void,
+ private_bio_writer_t *this, chunk_t value)
{
write_uint24(this, value.len);
write_data(this, value);
}
-METHOD(tls_writer_t, write_data32, void,
- private_tls_writer_t *this, chunk_t value)
+METHOD(bio_writer_t, write_data32, void,
+ private_bio_writer_t *this, chunk_t value)
{
write_uint32(this, value.len);
write_data(this, value);
}
-METHOD(tls_writer_t, wrap8, void,
- private_tls_writer_t *this)
+METHOD(bio_writer_t, wrap8, void,
+ private_bio_writer_t *this)
{
if (this->used + 1 > this->buf.len)
{
@@ -148,8 +159,8 @@ METHOD(tls_writer_t, wrap8, void,
this->used += 1;
}
-METHOD(tls_writer_t, wrap16, void,
- private_tls_writer_t *this)
+METHOD(bio_writer_t, wrap16, void,
+ private_bio_writer_t *this)
{
if (this->used + 2 > this->buf.len)
{
@@ -160,8 +171,8 @@ METHOD(tls_writer_t, wrap16, void,
this->used += 2;
}
-METHOD(tls_writer_t, wrap24, void,
- private_tls_writer_t *this)
+METHOD(bio_writer_t, wrap24, void,
+ private_bio_writer_t *this)
{
u_int32_t len;
@@ -176,8 +187,8 @@ METHOD(tls_writer_t, wrap24, void,
this->used += 3;
}
-METHOD(tls_writer_t, wrap32, void,
- private_tls_writer_t *this)
+METHOD(bio_writer_t, wrap32, void,
+ private_bio_writer_t *this)
{
if (this->used + 4 > this->buf.len)
{
@@ -188,14 +199,14 @@ METHOD(tls_writer_t, wrap32, void,
this->used += 4;
}
-METHOD(tls_writer_t, get_buf, chunk_t,
- private_tls_writer_t *this)
+METHOD(bio_writer_t, get_buf, chunk_t,
+ private_bio_writer_t *this)
{
return chunk_create(this->buf.ptr, this->used);
}
-METHOD(tls_writer_t, destroy, void,
- private_tls_writer_t *this)
+METHOD(bio_writer_t, destroy, void,
+ private_bio_writer_t *this)
{
free(this->buf.ptr);
free(this);
@@ -204,9 +215,9 @@ METHOD(tls_writer_t, destroy, void,
/**
* See header
*/
-tls_writer_t *tls_writer_create(u_int32_t bufsize)
+bio_writer_t *bio_writer_create(u_int32_t bufsize)
{
- private_tls_writer_t *this;
+ private_bio_writer_t *this;
INIT(this,
.public = {
@@ -214,6 +225,7 @@ tls_writer_t *tls_writer_create(u_int32_t bufsize)
.write_uint16 = _write_uint16,
.write_uint24 = _write_uint24,
.write_uint32 = _write_uint32,
+ .write_uint64 = _write_uint64,
.write_data = _write_data,
.write_data8 = _write_data8,
.write_data16 = _write_data16,
diff --git a/src/libtls/tls_writer.h b/src/libstrongswan/bio/bio_writer.h
index d3f09d5da..0b50f7882 100644
--- a/src/libtls/tls_writer.h
+++ b/src/libstrongswan/bio/bio_writer.h
@@ -14,123 +14,130 @@
*/
/**
- * @defgroup tls_writer tls_writer
- * @{ @ingroup libtls
+ * @defgroup bio_writer bio_writer
+ * @{ @ingroup bio
*/
-#ifndef TLS_WRITER_H_
-#define TLS_WRITER_H_
+#ifndef BIO_WRITER_H_
+#define BIO_WRITER_H_
-typedef struct tls_writer_t tls_writer_t;
+typedef struct bio_writer_t bio_writer_t;
#include <library.h>
/**
- * TLS record generator.
+ * Buffered output generator.
*/
-struct tls_writer_t {
+struct bio_writer_t {
/**
* Append a 8-bit integer to the buffer.
*
* @param value value to append
*/
- void (*write_uint8)(tls_writer_t *this, u_int8_t value);
+ void (*write_uint8)(bio_writer_t *this, u_int8_t value);
/**
* Append a 16-bit integer to the buffer.
*
* @param value value to append
*/
- void (*write_uint16)(tls_writer_t *this, u_int16_t value);
+ void (*write_uint16)(bio_writer_t *this, u_int16_t value);
/**
* Append a 24-bit integer to the buffer.
*
* @param value value to append
*/
- void (*write_uint24)(tls_writer_t *this, u_int32_t value);
+ void (*write_uint24)(bio_writer_t *this, u_int32_t value);
/**
* Append a 32-bit integer to the buffer.
*
* @param value value to append
*/
- void (*write_uint32)(tls_writer_t *this, u_int32_t value);
+ void (*write_uint32)(bio_writer_t *this, u_int32_t value);
+
+ /**
+ * Append a 64-bit integer to the buffer.
+ *
+ * @param value value to append
+ */
+ void (*write_uint64)(bio_writer_t *this, u_int64_t value);
/**
* Append a chunk of data without a length header.
*
* @param value value to append
*/
- void (*write_data)(tls_writer_t *this, chunk_t value);
+ void (*write_data)(bio_writer_t *this, chunk_t value);
/**
* Append a chunk of data with a 8-bit length header.
*
* @param value value to append
*/
- void (*write_data8)(tls_writer_t *this, chunk_t value);
+ void (*write_data8)(bio_writer_t *this, chunk_t value);
/**
* Append a chunk of data with a 16-bit length header.
*
* @param value value to append
*/
- void (*write_data16)(tls_writer_t *this, chunk_t value);
+ void (*write_data16)(bio_writer_t *this, chunk_t value);
/**
* Append a chunk of data with a 24-bit length header.
*
* @param value value to append
*/
- void (*write_data24)(tls_writer_t *this, chunk_t value);
+ void (*write_data24)(bio_writer_t *this, chunk_t value);
/**
* Append a chunk of data with a 32-bit length header.
*
* @param value value to append
*/
- void (*write_data32)(tls_writer_t *this, chunk_t value);
+ void (*write_data32)(bio_writer_t *this, chunk_t value);
/**
* Prepend a 8-bit length header to existing data.
*/
- void (*wrap8)(tls_writer_t *this);
+ void (*wrap8)(bio_writer_t *this);
/**
* Prepend a 16-bit length header to existing data.
*/
- void (*wrap16)(tls_writer_t *this);
+ void (*wrap16)(bio_writer_t *this);
/**
* Prepend a 24-bit length header to existing data.
*/
- void (*wrap24)(tls_writer_t *this);
+ void (*wrap24)(bio_writer_t *this);
/**
* Prepend a 32-bit length header to existing data.
*/
- void (*wrap32)(tls_writer_t *this);
+ void (*wrap32)(bio_writer_t *this);
/**
* Get the encoded data buffer.
*
* @return chunk to internal buffer
*/
- chunk_t (*get_buf)(tls_writer_t *this);
+ chunk_t (*get_buf)(bio_writer_t *this);
/**
- * Destroy a tls_writer_t.
+ * Destroy a bio_writer_t.
*/
- void (*destroy)(tls_writer_t *this);
+ void (*destroy)(bio_writer_t *this);
};
/**
- * Create a tls_writer instance.
+ * Create a bio_writer instance.
*
* @param bufsize initially allocated buffer size
*/
-tls_writer_t *tls_writer_create(u_int32_t bufsize);
+bio_writer_t *bio_writer_create(u_int32_t bufsize);
-#endif /** TLS_WRITER_H_ @}*/
+#endif /** BIO_WRITER_H_ @}*/
diff --git a/src/libstrongswan/chunk.c b/src/libstrongswan/chunk.c
index 9a4152145..9397c4e44 100644
--- a/src/libstrongswan/chunk.c
+++ b/src/libstrongswan/chunk.c
@@ -57,7 +57,7 @@ chunk_t chunk_create_clone(u_char *ptr, chunk_t chunk)
}
/**
- * Decribed in header.
+ * Described in header.
*/
size_t chunk_length(const char* mode, ...)
{
@@ -87,7 +87,7 @@ size_t chunk_length(const char* mode, ...)
}
/**
- * Decribed in header.
+ * Described in header.
*/
chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...)
{
@@ -133,7 +133,7 @@ chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...)
}
/**
- * Decribed in header.
+ * Described in header.
*/
void chunk_split(chunk_t chunk, const char *mode, ...)
{
@@ -313,7 +313,7 @@ chunk_t chunk_from_hex(chunk_t hex, char *buf)
/* subtract the number of optional ':' separation characters */
len = hex.len;
ptr = hex.ptr;
- for (i = 0; i < hex.len; i++)
+ for (i = 0; i < hex.len; i++)
{
if (*ptr++ == ':')
{
@@ -668,7 +668,8 @@ int chunk_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
if (!spec->hash)
{
- const void *new_args[] = {&chunk->ptr, &chunk->len};
+ u_int chunk_len = chunk->len;
+ const void *new_args[] = {&chunk->ptr, &chunk_len};
return mem_printf_hook(dst, len, spec, new_args);
}
diff --git a/src/libstrongswan/chunk.h b/src/libstrongswan/chunk.h
index 63644ac78..3de02eee7 100644
--- a/src/libstrongswan/chunk.h
+++ b/src/libstrongswan/chunk.h
@@ -235,6 +235,20 @@ static inline chunk_t chunk_skip(chunk_t chunk, size_t bytes)
}
/**
+ * Skip a leading zero-valued byte
+ */
+static inline chunk_t chunk_skip_zero(chunk_t chunk)
+{
+ if (chunk.len > 1 && *chunk.ptr == 0x00)
+ {
+ chunk.ptr++;
+ chunk.len--;
+ }
+ return chunk;
+}
+
+
+/**
* Compare two chunks, returns zero if a equals b
* or negative/positive if a is small/greater than b
*/
@@ -254,7 +268,7 @@ static inline bool chunk_equals(chunk_t a, chunk_t b)
* Increment a chunk, as it would reprensent a network order integer.
*
* @param chunk chunk to increment
- * @return TRUE if an overflow occured
+ * @return TRUE if an overflow occurred
*/
bool chunk_increment(chunk_t chunk);
diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c
index 23a3f62d9..12f75b240 100644
--- a/src/libstrongswan/credentials/auth_cfg.c
+++ b/src/libstrongswan/credentials/auth_cfg.c
@@ -1,6 +1,6 @@
/*
+ * Copyright (C) 2008-2012 Tobias Brunner
* Copyright (C) 2007-2009 Martin Willi
- * Copyright (C) 2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -30,6 +30,63 @@ ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_EAP,
"EAP",
);
+ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_REVOCATION_CERT,
+ "RULE_IDENTITY",
+ "RULE_AUTH_CLASS",
+ "RULE_AAA_IDENTITY",
+ "RULE_EAP_IDENTITY",
+ "RULE_EAP_TYPE",
+ "RULE_EAP_VENDOR",
+ "RULE_CA_CERT",
+ "RULE_IM_CERT",
+ "RULE_SUBJECT_CERT",
+ "RULE_CRL_VALIDATION",
+ "RULE_OCSP_VALIDATION",
+ "RULE_GROUP",
+ "RULE_RSA_STRENGTH",
+ "RULE_ECDSA_STRENGTH",
+ "RULE_CERT_POLICY",
+ "HELPER_IM_CERT",
+ "HELPER_SUBJECT_CERT",
+ "HELPER_IM_HASH_URL",
+ "HELPER_SUBJECT_HASH_URL",
+ "HELPER_REVOCATION_CERT",
+);
+
+/**
+ * Check if the given rule is a rule for which there may be multiple values.
+ */
+static inline bool is_multi_value_rule(auth_rule_t type)
+{
+ switch (type)
+ {
+ case AUTH_RULE_AUTH_CLASS:
+ case AUTH_RULE_EAP_TYPE:
+ case AUTH_RULE_EAP_VENDOR:
+ case AUTH_RULE_RSA_STRENGTH:
+ case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_IDENTITY:
+ case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AAA_IDENTITY:
+ case AUTH_RULE_SUBJECT_CERT:
+ case AUTH_HELPER_SUBJECT_CERT:
+ case AUTH_HELPER_SUBJECT_HASH_URL:
+ case AUTH_RULE_MAX:
+ return FALSE;
+ case AUTH_RULE_OCSP_VALIDATION:
+ case AUTH_RULE_CRL_VALIDATION:
+ case AUTH_RULE_GROUP:
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ case AUTH_RULE_CERT_POLICY:
+ case AUTH_HELPER_IM_CERT:
+ case AUTH_HELPER_IM_HASH_URL:
+ case AUTH_HELPER_REVOCATION_CERT:
+ return TRUE;
+ }
+ return FALSE;
+}
+
typedef struct private_auth_cfg_t private_auth_cfg_t;
/**
@@ -67,6 +124,8 @@ typedef struct {
enumerator_t *inner;
/** current entry */
entry_t *current;
+ /** types we have already enumerated */
+ bool enumerated[AUTH_RULE_MAX];
} entry_enumerator_t;
/**
@@ -76,11 +135,22 @@ static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
{
entry_t *entry;
- if (this->inner->enumerate(this->inner, &entry))
+ while (this->inner->enumerate(this->inner, &entry))
{
+ if (!is_multi_value_rule(entry->type) && this->enumerated[entry->type])
+ {
+ continue;
+ }
+ this->enumerated[entry->type] = TRUE;
this->current = entry;
- *type = entry->type;
- *value = entry->value;
+ if (type)
+ {
+ *type = entry->type;
+ }
+ if (value)
+ {
+ *value = entry->value;
+ }
return TRUE;
}
return FALSE;
@@ -95,22 +165,124 @@ static void entry_enumerator_destroy(entry_enumerator_t *this)
free(this);
}
-/**
- * Implementation of auth_cfg_t.create_enumerator.
- */
-static enumerator_t* create_enumerator(private_auth_cfg_t *this)
+METHOD(auth_cfg_t, create_enumerator, enumerator_t*,
+ private_auth_cfg_t *this)
{
entry_enumerator_t *enumerator;
- enumerator = malloc_thing(entry_enumerator_t);
- enumerator->inner = this->entries->create_enumerator(this->entries);
- enumerator->public.enumerate = (void*)enumerate;
- enumerator->public.destroy = (void*)entry_enumerator_destroy;
- enumerator->current = NULL;
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)enumerate,
+ .destroy = (void*)entry_enumerator_destroy,
+ },
+ .inner = this->entries->create_enumerator(this->entries),
+ );
return &enumerator->public;
}
/**
+ * Create an entry from the given arguments.
+ */
+static entry_t *entry_create(auth_rule_t type, va_list args)
+{
+ entry_t *this = malloc_thing(entry_t);
+
+ this->type = type;
+ switch (type)
+ {
+ case AUTH_RULE_AUTH_CLASS:
+ case AUTH_RULE_EAP_TYPE:
+ case AUTH_RULE_EAP_VENDOR:
+ case AUTH_RULE_CRL_VALIDATION:
+ case AUTH_RULE_OCSP_VALIDATION:
+ case AUTH_RULE_RSA_STRENGTH:
+ case AUTH_RULE_ECDSA_STRENGTH:
+ /* integer type */
+ this->value = (void*)(uintptr_t)va_arg(args, u_int);
+ break;
+ case AUTH_RULE_IDENTITY:
+ case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AAA_IDENTITY:
+ case AUTH_RULE_GROUP:
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ case AUTH_RULE_SUBJECT_CERT:
+ case AUTH_RULE_CERT_POLICY:
+ case AUTH_HELPER_IM_CERT:
+ case AUTH_HELPER_SUBJECT_CERT:
+ case AUTH_HELPER_IM_HASH_URL:
+ case AUTH_HELPER_SUBJECT_HASH_URL:
+ case AUTH_HELPER_REVOCATION_CERT:
+ /* pointer type */
+ this->value = va_arg(args, void*);
+ break;
+ case AUTH_RULE_MAX:
+ this->value = NULL;
+ break;
+ }
+ return this;
+}
+
+/**
+ * Compare two entries for equality.
+ */
+static bool entry_equals(entry_t *e1, entry_t *e2)
+{
+ if (e1->type != e2->type)
+ {
+ return FALSE;
+ }
+ switch (e1->type)
+ {
+ case AUTH_RULE_AUTH_CLASS:
+ case AUTH_RULE_EAP_TYPE:
+ case AUTH_RULE_EAP_VENDOR:
+ case AUTH_RULE_CRL_VALIDATION:
+ case AUTH_RULE_OCSP_VALIDATION:
+ case AUTH_RULE_RSA_STRENGTH:
+ case AUTH_RULE_ECDSA_STRENGTH:
+ {
+ return e1->value == e2->value;
+ }
+ case AUTH_RULE_CA_CERT:
+ case AUTH_RULE_IM_CERT:
+ case AUTH_RULE_SUBJECT_CERT:
+ case AUTH_HELPER_IM_CERT:
+ case AUTH_HELPER_SUBJECT_CERT:
+ case AUTH_HELPER_REVOCATION_CERT:
+ {
+ certificate_t *c1, *c2;
+
+ c1 = (certificate_t*)e1->value;
+ c2 = (certificate_t*)e2->value;
+
+ return c1->equals(c1, c2);
+ }
+ case AUTH_RULE_IDENTITY:
+ case AUTH_RULE_EAP_IDENTITY:
+ case AUTH_RULE_AAA_IDENTITY:
+ case AUTH_RULE_GROUP:
+ {
+ identification_t *id1, *id2;
+
+ id1 = (identification_t*)e1->value;
+ id2 = (identification_t*)e2->value;
+
+ return id1->equals(id1, id2);
+ }
+ case AUTH_RULE_CERT_POLICY:
+ case AUTH_HELPER_IM_HASH_URL:
+ case AUTH_HELPER_SUBJECT_HASH_URL:
+ {
+ return streq(e1->value, e2->value);
+ }
+ case AUTH_RULE_MAX:
+ break;
+ }
+ return FALSE;
+}
+
+/**
* Destroy the value associated with an entry
*/
static void destroy_entry_value(entry_t *entry)
@@ -151,6 +323,7 @@ static void destroy_entry_value(entry_t *entry)
case AUTH_RULE_OCSP_VALIDATION:
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
+ case AUTH_RULE_MAX:
break;
}
}
@@ -158,17 +331,18 @@ static void destroy_entry_value(entry_t *entry)
/**
* Implementation of auth_cfg_t.replace.
*/
-static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
+static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator,
auth_rule_t type, ...)
{
if (enumerator->current)
{
+ entry_t *entry;
va_list args;
va_start(args, type);
-
- destroy_entry_value(enumerator->current);
- enumerator->current->type = type;
+ entry = enumerator->current;
+ destroy_entry_value(entry);
+ entry->type = type;
switch (type)
{
case AUTH_RULE_AUTH_CLASS:
@@ -179,7 +353,7 @@ static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
case AUTH_RULE_RSA_STRENGTH:
case AUTH_RULE_ECDSA_STRENGTH:
/* integer type */
- enumerator->current->value = (void*)(uintptr_t)va_arg(args, u_int);
+ entry->value = (void*)(uintptr_t)va_arg(args, u_int);
break;
case AUTH_RULE_IDENTITY:
case AUTH_RULE_EAP_IDENTITY:
@@ -195,17 +369,18 @@ static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
case AUTH_HELPER_SUBJECT_HASH_URL:
case AUTH_HELPER_REVOCATION_CERT:
/* pointer type */
- enumerator->current->value = va_arg(args, void*);
+ entry->value = va_arg(args, void*);
+ break;
+ case AUTH_RULE_MAX:
+ entry->value = NULL;
break;
}
va_end(args);
}
}
-/**
- * Implementation of auth_cfg_t.get.
- */
-static void* get(private_auth_cfg_t *this, auth_rule_t type)
+METHOD(auth_cfg_t, get, void*,
+ private_auth_cfg_t *this, auth_rule_t type)
{
enumerator_t *enumerator;
void *current_value, *best_value = NULL;
@@ -264,9 +439,10 @@ static void* get(private_auth_cfg_t *this, auth_rule_t type)
case AUTH_HELPER_IM_HASH_URL:
case AUTH_HELPER_SUBJECT_HASH_URL:
case AUTH_HELPER_REVOCATION_CERT:
- default:
- return NULL;
+ case AUTH_RULE_MAX:
+ break;
}
+ return NULL;
}
/**
@@ -274,49 +450,26 @@ static void* get(private_auth_cfg_t *this, auth_rule_t type)
*/
static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
{
- entry_t *entry = malloc_thing(entry_t);
+ entry_t *entry;
va_list args;
va_start(args, type);
- entry->type = type;
- switch (type)
- {
- case AUTH_RULE_AUTH_CLASS:
- case AUTH_RULE_EAP_TYPE:
- case AUTH_RULE_EAP_VENDOR:
- case AUTH_RULE_CRL_VALIDATION:
- case AUTH_RULE_OCSP_VALIDATION:
- case AUTH_RULE_RSA_STRENGTH:
- case AUTH_RULE_ECDSA_STRENGTH:
- /* integer type */
- entry->value = (void*)(uintptr_t)va_arg(args, u_int);
- break;
- case AUTH_RULE_IDENTITY:
- case AUTH_RULE_EAP_IDENTITY:
- case AUTH_RULE_AAA_IDENTITY:
- case AUTH_RULE_GROUP:
- case AUTH_RULE_CA_CERT:
- case AUTH_RULE_IM_CERT:
- case AUTH_RULE_SUBJECT_CERT:
- case AUTH_RULE_CERT_POLICY:
- case AUTH_HELPER_IM_CERT:
- case AUTH_HELPER_SUBJECT_CERT:
- case AUTH_HELPER_IM_HASH_URL:
- case AUTH_HELPER_SUBJECT_HASH_URL:
- case AUTH_HELPER_REVOCATION_CERT:
- /* pointer type */
- entry->value = va_arg(args, void*);
- break;
- }
+ entry = entry_create(type, args);
va_end(args);
- this->entries->insert_last(this->entries, entry);
+
+ if (is_multi_value_rule(type))
+ { /* insert rules that may occur multiple times at the end */
+ this->entries->insert_last(this->entries, entry);
+ }
+ else
+ { /* insert rules we expect only once at the front (get() will return
+ * the latest value) */
+ this->entries->insert_first(this->entries, entry);
+ }
}
-/**
- * Implementation of auth_cfg_t.complies.
- */
-static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
- bool log_error)
+METHOD(auth_cfg_t, complies, bool,
+ private_auth_cfg_t *this, auth_cfg_t *constraints, bool log_error)
{
enumerator_t *e1, *e2;
bool success = TRUE, has_group = FALSE, group_match = FALSE;
@@ -566,6 +719,7 @@ static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
case AUTH_HELPER_IM_HASH_URL:
case AUTH_HELPER_SUBJECT_HASH_URL:
case AUTH_HELPER_REVOCATION_CERT:
+ case AUTH_RULE_MAX:
/* skip helpers */
continue;
}
@@ -602,6 +756,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
auth_rule_t type;
void *value;
+ /* this enumerator skips duplicates for rules we expect only once */
enumerator = create_enumerator(other);
while (enumerator->enumerate(enumerator, &type, &value))
{
@@ -647,6 +802,8 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy
add(this, type, strdup((char*)value));
break;
}
+ case AUTH_RULE_MAX:
+ break;
}
}
enumerator->destroy(enumerator);
@@ -672,85 +829,23 @@ static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
entry_t *i1, *i2;
bool equal = TRUE, found;
- if (this->entries->get_count(this->entries) !=
- other->entries->get_count(other->entries))
- {
- return FALSE;
- }
+ /* the rule count does not have to be equal for the two, as we only compare
+ * the first value found for some rules */
e1 = this->entries->create_enumerator(this->entries);
while (e1->enumerate(e1, &i1))
{
found = FALSE;
+
e2 = other->entries->create_enumerator(other->entries);
while (e2->enumerate(e2, &i2))
{
- if (i1->type == i2->type)
+ if (entry_equals(i1, i2))
{
- switch (i1->type)
- {
- case AUTH_RULE_AUTH_CLASS:
- case AUTH_RULE_EAP_TYPE:
- case AUTH_RULE_EAP_VENDOR:
- case AUTH_RULE_CRL_VALIDATION:
- case AUTH_RULE_OCSP_VALIDATION:
- case AUTH_RULE_RSA_STRENGTH:
- case AUTH_RULE_ECDSA_STRENGTH:
- {
- if (i1->value == i2->value)
- {
- found = TRUE;
- break;
- }
- continue;
- }
- case AUTH_RULE_CA_CERT:
- case AUTH_RULE_IM_CERT:
- case AUTH_RULE_SUBJECT_CERT:
- case AUTH_HELPER_IM_CERT:
- case AUTH_HELPER_SUBJECT_CERT:
- case AUTH_HELPER_REVOCATION_CERT:
- {
- certificate_t *c1, *c2;
-
- c1 = (certificate_t*)i1->value;
- c2 = (certificate_t*)i2->value;
-
- if (c1->equals(c1, c2))
- {
- found = TRUE;
- break;
- }
- continue;
- }
- case AUTH_RULE_IDENTITY:
- case AUTH_RULE_EAP_IDENTITY:
- case AUTH_RULE_AAA_IDENTITY:
- case AUTH_RULE_GROUP:
- {
- identification_t *id1, *id2;
-
- id1 = (identification_t*)i1->value;
- id2 = (identification_t*)i2->value;
-
- if (id1->equals(id1, id2))
- {
- found = TRUE;
- break;
- }
- continue;
- }
- case AUTH_RULE_CERT_POLICY:
- case AUTH_HELPER_IM_HASH_URL:
- case AUTH_HELPER_SUBJECT_HASH_URL:
- {
- if (streq(i1->value, i2->value))
- {
- found = TRUE;
- break;
- }
- continue;
- }
- }
+ found = TRUE;
+ break;
+ }
+ else if (i1->type == i2->type && !is_multi_value_rule(i1->type))
+ { /* we continue our search, only for multi valued rules */
break;
}
}
@@ -765,10 +860,8 @@ static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
return equal;
}
-/**
- * Implementation of auth_cfg_t.purge
- */
-static void purge(private_auth_cfg_t *this, bool keep_ca)
+METHOD(auth_cfg_t, purge, void,
+ private_auth_cfg_t *this, bool keep_ca)
{
entry_t *entry;
linked_list_t *cas;
@@ -793,16 +886,15 @@ static void purge(private_auth_cfg_t *this, bool keep_ca)
cas->destroy(cas);
}
-/**
- * Implementation of auth_cfg_t.clone
- */
-static auth_cfg_t* clone_(private_auth_cfg_t *this)
+METHOD(auth_cfg_t, clone_, auth_cfg_t*,
+ private_auth_cfg_t *this)
{
enumerator_t *enumerator;
auth_cfg_t *clone;
entry_t *entry;
clone = auth_cfg_create();
+ /* this enumerator skips duplicates for rules we expect only once */
enumerator = this->entries->create_enumerator(this->entries);
while (enumerator->enumerate(enumerator, &entry))
{
@@ -844,16 +936,16 @@ static auth_cfg_t* clone_(private_auth_cfg_t *this)
case AUTH_RULE_ECDSA_STRENGTH:
clone->add(clone, entry->type, (uintptr_t)entry->value);
break;
+ case AUTH_RULE_MAX:
+ break;
}
}
enumerator->destroy(enumerator);
return clone;
}
-/**
- * Implementation of auth_cfg_t.destroy
- */
-static void destroy(private_auth_cfg_t *this)
+METHOD(auth_cfg_t, destroy, void,
+ private_auth_cfg_t *this)
{
purge(this, FALSE);
this->entries->destroy(this->entries);
@@ -865,20 +957,23 @@ static void destroy(private_auth_cfg_t *this)
*/
auth_cfg_t *auth_cfg_create()
{
- private_auth_cfg_t *this = malloc_thing(private_auth_cfg_t);
-
- this->public.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add;
- this->public.get = (void*(*)(auth_cfg_t*, auth_rule_t type))get;
- this->public.create_enumerator = (enumerator_t*(*)(auth_cfg_t*))create_enumerator;
- this->public.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace;
- this->public.complies = (bool(*)(auth_cfg_t*, auth_cfg_t *,bool))complies;
- this->public.merge = (void(*)(auth_cfg_t*, auth_cfg_t *other,bool))merge;
- this->public.purge = (void(*)(auth_cfg_t*,bool))purge;
- this->public.equals = (bool(*)(auth_cfg_t*, auth_cfg_t *other))equals;
- this->public.clone = (auth_cfg_t*(*)(auth_cfg_t*))clone_;
- this->public.destroy = (void(*)(auth_cfg_t*))destroy;
-
- this->entries = linked_list_create();
+ private_auth_cfg_t *this;
+
+ INIT(this,
+ .public = {
+ .add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add,
+ .get = _get,
+ .create_enumerator = _create_enumerator,
+ .replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace,
+ .complies = _complies,
+ .merge = (void(*)(auth_cfg_t*,auth_cfg_t*,bool))merge,
+ .purge = _purge,
+ .equals = (bool(*)(auth_cfg_t*,auth_cfg_t*))equals,
+ .clone = _clone_,
+ .destroy = _destroy,
+ },
+ .entries = linked_list_create(),
+ );
return &this->public;
}
diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h
index 489ce1134..4d12a9c14 100644
--- a/src/libstrongswan/credentials/auth_cfg.h
+++ b/src/libstrongswan/credentials/auth_cfg.h
@@ -1,6 +1,6 @@
/*
+ * Copyright (C) 2008-2012 Tobias Brunner
* Copyright (C) 2007-2009 Martin Willi
- * Copyright (C) 2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@ typedef enum auth_class_t auth_class_t;
/**
* Class of authentication to use. This is different to auth_method_t in that
* it does not specify a method, but a class of acceptable methods. The found
- * certificate finally dictates wich method is used.
+ * certificate finally dictates which method is used.
*/
enum auth_class_t {
/** any class acceptable */
@@ -57,13 +57,12 @@ extern enum_name_t *auth_class_names;
* - For configs specifying local authentication behavior, the rules define
* which authentication method in which way.
* - For configs specifying remote peer authentication, the rules define
- * constraints the peer has to fullfill.
+ * constraints the peer has to fulfill.
*
* Additionally to the rules, there is a set of helper items. These are used
* to transport credentials during the authentication process.
*/
enum auth_rule_t {
-
/** identity to use for IKEv2 authentication exchange, identification_t* */
AUTH_RULE_IDENTITY,
/** authentication class, auth_class_t */
@@ -107,6 +106,9 @@ enum auth_rule_t {
AUTH_HELPER_SUBJECT_HASH_URL,
/** revocation certificate (CRL, OCSP), certificate_t* */
AUTH_HELPER_REVOCATION_CERT,
+
+ /** helper to determine the number of elements in this enum */
+ AUTH_RULE_MAX,
};
/**
@@ -119,8 +121,8 @@ extern enum_name_t *auth_rule_names;
*
* RFC4739 defines multiple authentication rounds. This class defines such
* a round from a configuration perspective, either for the local or the remote
- * peer. Local config are called "rulesets", as they define how we authenticate.
- * Remote peer configs are called "constraits", they define what is needed to
+ * peer. Local configs are called "rulesets". They define how we authenticate.
+ * Remote peer configs are called "constraits". They define what is needed to
* complete the authentication round successfully.
*
* @verbatim
@@ -144,13 +146,20 @@ extern enum_name_t *auth_rule_names;
@endverbatim
*
- * Values for each items are either pointers (casted to void*) or short
+ * Values for each item are either pointers (casted to void*) or short
* integers (use uintptr_t cast).
*/
struct auth_cfg_t {
/**
- * Add an rule to the set.
+ * Add a rule to the set.
+ *
+ * Rules we expect only once (e.g. identities) implicitly replace previous
+ * rules of the same type (but pointers to previous values will remain
+ * valid until the auth_cfg_t object is destroyed).
+ * Rules that may occur multiple times (e.g. CA certificates) are inserted
+ * so that they can be enumerated in the order in which they were added.
+ * For these get() will return the value added first.
*
* @param rule rule type
* @param ... associated value to rule
@@ -158,7 +167,9 @@ struct auth_cfg_t {
void (*add)(auth_cfg_t *this, auth_rule_t rule, ...);
/**
- * Get an rule value.
+ * Get a rule value.
+ *
+ * For rules we expect only once the latest value is returned.
*
* @param rule rule type
* @return bool if item has been found
@@ -168,14 +179,17 @@ struct auth_cfg_t {
/**
* Create an enumerator over added rules.
*
+ * Refer to add() regarding the order in which rules are enumerated.
+ * For rules we expect only once the latest value is enumerated only.
+ *
* @return enumerator over (auth_rule_t, union{void*,uintpr_t})
*/
enumerator_t* (*create_enumerator)(auth_cfg_t *this);
/**
- * Replace an rule at enumerator position.
+ * Replace a rule at enumerator position.
*
- * @param pos enumerator position position
+ * @param pos enumerator position
* @param rule rule type
* @param ... associated value to rule
*/
@@ -186,7 +200,7 @@ struct auth_cfg_t {
* Check if a used config fulfills a set of configured constraints.
*
* @param constraints required authorization rules
- * @param log_error wheter to log compliance errors
+ * @param log_error whether to log compliance errors
* @return TRUE if this complies with constraints
*/
bool (*complies)(auth_cfg_t *this, auth_cfg_t *constraints, bool log_error);
@@ -202,20 +216,22 @@ struct auth_cfg_t {
/**
* Purge all rules in a config.
*
- * @param keep_ca wheter to keep AUTH_RULE_CA_CERT entries
+ * @param keep_ca whether to keep AUTH_RULE_CA_CERT entries
*/
void (*purge)(auth_cfg_t *this, bool keep_ca);
/**
* Check two configs for equality.
*
- * @param other other config to compaire against this
+ * For rules we expect only once the latest value is compared only.
+ *
+ * @param other other config to compare against this
* @return TRUE if auth infos identical
*/
bool (*equals)(auth_cfg_t *this, auth_cfg_t *other);
/**
- * Clone a authentication config, including all rules.
+ * Clone an authentication config, including all rules.
*
* @return cloned configuration
*/
diff --git a/src/libstrongswan/credentials/builder.c b/src/libstrongswan/credentials/builder.c
index f9a277a2c..d3157c80e 100644
--- a/src/libstrongswan/credentials/builder.c
+++ b/src/libstrongswan/credentials/builder.c
@@ -23,8 +23,7 @@ ENUM(builder_part_names, BUILD_FROM_FILE, BUILD_END,
"BUILD_BLOB_PEM",
"BUILD_BLOB_PGP",
"BUILD_BLOB_DNSKEY",
- "BUILD_PASSPHRASE",
- "BUILD_PASSPHRASE_CALLBACK",
+ "BUILD_BLOB_ALGID_PARAMS",
"BUILD_KEY_SIZE",
"BUILD_SIGNING_KEY",
"BUILD_SIGNING_CERT",
diff --git a/src/libstrongswan/credentials/builder.h b/src/libstrongswan/credentials/builder.h
index 325b668cd..41250ccae 100644
--- a/src/libstrongswan/credentials/builder.h
+++ b/src/libstrongswan/credentials/builder.h
@@ -28,8 +28,8 @@ typedef enum builder_part_t builder_part_t;
/**
* Constructor function to build credentials.
*
- * Any added parts are cloned/refcounted by the builder implementation, a
- * caller may need to free the passed ressources themself.
+ * Any added parts are cloned/refcounted by the builder implementation.
+ * Callers may need to free the passed resources themselves.
*
* @param subtype constructor specific subtype, e.g. a certificate_type_t
* @param args list of builder part types, followed by parts, BUILD_END
@@ -53,10 +53,12 @@ enum builder_part_t {
BUILD_BLOB_ASN1_DER,
/** PEM encoded ASN.1/PGP blob, chunk_t */
BUILD_BLOB_PEM,
- /** OpenPGP key blob, chunk_t */
+ /** OpenPGP key blob, chunk_t */
BUILD_BLOB_PGP,
/** DNS public key blob (RFC 4034, RSA specifc RFC 3110), chunk_t */
BUILD_BLOB_DNSKEY,
+ /** parameters from algorithmIdentifier (ASN.1 blob), chunk_t */
+ BUILD_BLOB_ALGID_PARAMS,
/** key size in bits, as used for key generation, u_int */
BUILD_KEY_SIZE,
/** private key to use for signing, private_key_t* */
diff --git a/src/libstrongswan/credentials/cert_validator.h b/src/libstrongswan/credentials/cert_validator.h
index 733d9d612..00e30d7a0 100644
--- a/src/libstrongswan/credentials/cert_validator.h
+++ b/src/libstrongswan/credentials/cert_validator.h
@@ -39,7 +39,7 @@ struct cert_validator_t {
*
* @param subject subject certificate to check
* @param issuer issuer of subject
- * @param online wheter to do online revocation checking
+ * @param online whether to do online revocation checking
* @param pathlen the current length of the path bottom-up
* @param anchor is issuer trusted root anchor
* @param auth container for resulting authentication info
diff --git a/src/libstrongswan/credentials/certificates/ac.h b/src/libstrongswan/credentials/certificates/ac.h
index fef7f8c65..57b44adca 100644
--- a/src/libstrongswan/credentials/certificates/ac.h
+++ b/src/libstrongswan/credentials/certificates/ac.h
@@ -79,7 +79,6 @@ struct ac_t {
/**
* @brief Checks if two attribute certificates belong to the same holder
*
- * @param this calling attribute certificate
* @param that other attribute certificate
* @return TRUE if same holder
*/
diff --git a/src/libstrongswan/credentials/certificates/certificate.c b/src/libstrongswan/credentials/certificates/certificate.c
index 661b69e36..33ba4e907 100644
--- a/src/libstrongswan/credentials/certificates/certificate.c
+++ b/src/libstrongswan/credentials/certificates/certificate.c
@@ -38,6 +38,7 @@ ENUM(cert_validation_names, VALIDATION_GOOD, VALIDATION_REVOKED,
"SKIPPED",
"STALE",
"FAILED",
+ "ON_HOLD",
"REVOKED",
);
diff --git a/src/libstrongswan/credentials/certificates/certificate.h b/src/libstrongswan/credentials/certificates/certificate.h
index 43bfe3dc1..2f471da5b 100644
--- a/src/libstrongswan/credentials/certificates/certificate.h
+++ b/src/libstrongswan/credentials/certificates/certificate.h
@@ -77,6 +77,8 @@ enum cert_validation_t {
VALIDATION_STALE,
/** validation failed due to a processing error */
VALIDATION_FAILED,
+ /** certificate is on hold (i.e. temporary revokation) */
+ VALIDATION_ON_HOLD,
/** certificate has been revoked */
VALIDATION_REVOKED,
};
@@ -115,7 +117,7 @@ struct certificate_t {
* not returned by get_subject (e.g. subjectAltNames)
*
* @param subject subject identity
- * @return matching value of best match
+ * @return matching value of best match
*/
id_match_t (*has_subject)(certificate_t *this, identification_t *subject);
@@ -132,8 +134,8 @@ struct certificate_t {
* A certificate may contain additional issuer identifiers, which are
* not returned by get_issuer (e.g. issuerAltNames)
*
- * @param subject isser identity
- * @return matching value of best match
+ * @param subject issuer identity
+ * @return matching value of best match
*/
id_match_t (*has_issuer)(certificate_t *this, identification_t *issuer);
@@ -141,7 +143,7 @@ struct certificate_t {
* Check if this certificate is issued and signed by a specific issuer.
*
* @param issuer issuer's certificate
- * @return TRUE if certificate issued by issuer and trusted
+ * @return TRUE if certificate issued by issuer and trusted
*/
bool (*issued_by)(certificate_t *this, certificate_t *issuer);
@@ -176,7 +178,7 @@ struct certificate_t {
/**
* Check if two certificates are equal.
*
- * @param other certificate to compair against this
+ * @param other certificate to compare against this
* @return TRUE if certificates are equal
*/
bool (*equals)(certificate_t *this, certificate_t *other);
@@ -197,10 +199,10 @@ struct certificate_t {
/**
* Generic check if a given certificate is newer than another.
*
- * @param this first certificate to check
- * @param other second certificate
+ * @param cert certificate
+ * @param other certificate to compare to
* @return TRUE if this newer than other
*/
-bool certificate_is_newer(certificate_t *this, certificate_t *other);
+bool certificate_is_newer(certificate_t *cert, certificate_t *other);
#endif /** CERTIFICATE_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/crl.h b/src/libstrongswan/credentials/certificates/crl.h
index 2f3497474..4191c5935 100644
--- a/src/libstrongswan/credentials/certificates/crl.h
+++ b/src/libstrongswan/credentials/certificates/crl.h
@@ -100,10 +100,10 @@ struct crl_t {
/**
* Generic check if a given CRL is newer than another.
*
- * @param this first CRL to check
- * @param other second CRL
+ * @param crl CRL
+ * @param other CRL to compare to
* @return TRUE if this newer than other
*/
-bool crl_is_newer(crl_t *this, crl_t *other);
+bool crl_is_newer(crl_t *crl, crl_t *other);
#endif /** CRL_H_ @}*/
diff --git a/src/libstrongswan/credentials/certificates/x509.h b/src/libstrongswan/credentials/certificates/x509.h
index fec02dbad..5125aca26 100644
--- a/src/libstrongswan/credentials/certificates/x509.h
+++ b/src/libstrongswan/credentials/certificates/x509.h
@@ -41,13 +41,13 @@ enum x509_flag_t {
/** cert has no constraints */
X509_NONE = 0,
/** cert has CA constraint */
- X509_CA = (1<<0),
+ X509_CA = (1<<0),
/** cert has AA constraint */
- X509_AA = (1<<1),
+ X509_AA = (1<<1),
/** cert has OCSP signer constraint */
- X509_OCSP_SIGNER = (1<<2),
+ X509_OCSP_SIGNER = (1<<2),
/** cert has serverAuth key usage */
- X509_SERVER_AUTH = (1<<3),
+ X509_SERVER_AUTH = (1<<3),
/** cert has clientAuth key usage */
X509_CLIENT_AUTH = (1<<4),
/** cert is self-signed */
@@ -76,12 +76,12 @@ enum x509_constraint_t {
* X.509 certPolicy extension.
*/
struct x509_cert_policy_t {
- /** OID of certPolicy */
- chunk_t oid;
/** Certification Practice Statement URI qualifier */
char *cps_uri;
/** UserNotice Text qualifier */
char *unotice_text;
+ /** OID of certPolicy */
+ chunk_t oid;
};
/**
diff --git a/src/libstrongswan/credentials/cred_encoding.c b/src/libstrongswan/credentials/cred_encoding.c
index ac3266f4c..4865984dd 100644
--- a/src/libstrongswan/credentials/cred_encoding.c
+++ b/src/libstrongswan/credentials/cred_encoding.c
@@ -110,15 +110,13 @@ static bool equals(void *key1, void *key2)
return key1 == key2;
}
-/**
- * Implementation of cred_encoding_t.get_cache
- */
-static bool get_cache(private_cred_encoding_t *this, cred_encoding_type_t type,
- void *cache, chunk_t *encoding)
+METHOD(cred_encoding_t, get_cache, bool,
+ private_cred_encoding_t *this, cred_encoding_type_t type, void *cache,
+ chunk_t *encoding)
{
chunk_t *chunk;
- if (type >= CRED_ENCODING_MAX || type < 0)
+ if (type >= CRED_ENCODING_MAX || (int)type < 0)
{
return FALSE;
}
@@ -144,7 +142,7 @@ static bool encode(private_cred_encoding_t *this, cred_encoding_type_t type,
bool success = FALSE;
chunk_t *chunk;
- if (type >= CRED_ENCODING_MAX || type < 0)
+ if (type >= CRED_ENCODING_MAX || (int)type < 0)
{
return FALSE;
}
@@ -191,15 +189,13 @@ static bool encode(private_cred_encoding_t *this, cred_encoding_type_t type,
return success;
}
-/**
- * Implementation of cred_encoding_t.cache
- */
-static void cache(private_cred_encoding_t *this, cred_encoding_type_t type,
- void *cache, chunk_t encoding)
+METHOD(cred_encoding_t, cache, void,
+ private_cred_encoding_t *this, cred_encoding_type_t type, void *cache,
+ chunk_t encoding)
{
chunk_t *chunk;
- if (type >= CRED_ENCODING_MAX || type < 0)
+ if (type >= CRED_ENCODING_MAX || (int)type < 0)
{
return free(encoding.ptr);
}
@@ -216,10 +212,8 @@ static void cache(private_cred_encoding_t *this, cred_encoding_type_t type,
}
}
-/**
- * Implementation of cred_encoding_t.clear_cache
- */
-static void clear_cache(private_cred_encoding_t *this, void *cache)
+METHOD(cred_encoding_t, clear_cache, void,
+ private_cred_encoding_t *this, void *cache)
{
cred_encoding_type_t type;
chunk_t *chunk;
@@ -237,30 +231,24 @@ static void clear_cache(private_cred_encoding_t *this, void *cache)
this->lock->unlock(this->lock);
}
-/**
- * Implementation of cred_encoding_t.add_encoder
- */
-static void add_encoder(private_cred_encoding_t *this, cred_encoder_t encoder)
+METHOD(cred_encoding_t, add_encoder, void,
+ private_cred_encoding_t *this, cred_encoder_t encoder)
{
this->lock->write_lock(this->lock);
this->encoders->insert_last(this->encoders, encoder);
this->lock->unlock(this->lock);
}
-/**
- * Implementation of cred_encoding_t.remove_encoder
- */
-static void remove_encoder(private_cred_encoding_t *this, cred_encoder_t encoder)
+METHOD(cred_encoding_t, remove_encoder, void,
+ private_cred_encoding_t *this, cred_encoder_t encoder)
{
this->lock->write_lock(this->lock);
this->encoders->remove(this->encoders, encoder, NULL);
this->lock->unlock(this->lock);
}
-/**
- * Implementation of cred_encoder_t.destroy.
- */
-static void destroy(private_cred_encoding_t *this)
+METHOD(cred_encoding_t, destroy, void,
+ private_cred_encoding_t *this)
{
cred_encoding_type_t type;
@@ -282,23 +270,27 @@ static void destroy(private_cred_encoding_t *this)
*/
cred_encoding_t *cred_encoding_create()
{
- private_cred_encoding_t *this = malloc_thing(private_cred_encoding_t);
+ private_cred_encoding_t *this;
cred_encoding_type_t type;
- this->public.encode = (bool(*)(cred_encoding_t*, cred_encoding_type_t type, void *cache, chunk_t *encoding, ...))encode;
- this->public.get_cache = (bool(*)(cred_encoding_t*, cred_encoding_type_t type, void *cache, chunk_t *encoding))get_cache;
- this->public.cache = (void(*)(cred_encoding_t*, cred_encoding_type_t type, void *cache, chunk_t encoding))cache;
- this->public.clear_cache = (void(*)(cred_encoding_t*, void *cache))clear_cache;
- this->public.add_encoder = (void(*)(cred_encoding_t*, cred_encoder_t encoder))add_encoder;
- this->public.remove_encoder = (void(*)(cred_encoding_t*, cred_encoder_t encoder))remove_encoder;
- this->public.destroy = (void(*)(cred_encoding_t*))destroy;
+ INIT(this,
+ .public = {
+ .encode = (bool(*)(cred_encoding_t*, cred_encoding_type_t type, void *cache, chunk_t *encoding, ...))encode,
+ .get_cache = _get_cache,
+ .cache = _cache,
+ .clear_cache = _clear_cache,
+ .add_encoder = _add_encoder,
+ .remove_encoder = _remove_encoder,
+ .destroy = _destroy,
+ },
+ .encoders = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
for (type = 0; type < CRED_ENCODING_MAX; type++)
{
this->cache[type] = hashtable_create(hash, equals, 8);
}
- this->encoders = linked_list_create();
- this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
return &this->public;
}
diff --git a/src/libstrongswan/credentials/cred_encoding.h b/src/libstrongswan/credentials/cred_encoding.h
index e2d69691e..b029fe2ac 100644
--- a/src/libstrongswan/credentials/cred_encoding.h
+++ b/src/libstrongswan/credentials/cred_encoding.h
@@ -59,7 +59,7 @@ bool cred_encoding_args(va_list args, ...);
/**
* Encoding type of a fingerprint/credential.
*
- * Fingerprints have have the KEYID_*, public keys the PUBKEY_* and
+ * Fingerprints have the KEYID_*, public keys the PUBKEY_* and
* private keys the PRIVKEY_* prefix.
*/
enum cred_encoding_type_t {
diff --git a/src/libstrongswan/credentials/credential_factory.h b/src/libstrongswan/credentials/credential_factory.h
index 709dc916a..c31601245 100644
--- a/src/libstrongswan/credentials/credential_factory.h
+++ b/src/libstrongswan/credentials/credential_factory.h
@@ -54,7 +54,7 @@ struct credential_factory_t {
* The variable argument list takes builder_part_t types followed
* by the type specific value. The list must be terminated using BUILD_END.
* All passed parts get cloned/refcounted by the builder functions,
- * so free up allocated ressources after successful and unsuccessful
+ * so free up allocated resources after successful and unsuccessful
* invocations.
*
* @param type credential type to build
diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c
index 27b97eab3..b3461b810 100644
--- a/src/libstrongswan/credentials/credential_manager.c
+++ b/src/libstrongswan/credentials/credential_manager.c
@@ -866,7 +866,7 @@ METHOD(credential_manager_t, create_public_enumerator, enumerator_t*,
}
/**
- * Check if an helper contains a certificate as trust anchor
+ * Check if a helper contains a certificate as trust anchor
*/
static bool auth_contains_cacert(auth_cfg_t *auth, certificate_t *cert)
{
@@ -949,7 +949,7 @@ static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
}
/**
- * find a private key of a give certificate
+ * find a private key of a given certificate
*/
static private_key_t *get_private_by_cert(private_credential_manager_t *this,
certificate_t *cert, key_type_t type)
diff --git a/src/libstrongswan/credentials/credential_manager.h b/src/libstrongswan/credentials/credential_manager.h
index 04269cfbf..8e8f04b8c 100644
--- a/src/libstrongswan/credentials/credential_manager.h
+++ b/src/libstrongswan/credentials/credential_manager.h
@@ -36,11 +36,11 @@ typedef struct credential_manager_t credential_manager_t;
* Manages credentials using credential_sets.
*
* The credential manager is the entry point of the credential framework. It
- * uses so called "sets" to access credentials in a modular fashion, these
+ * uses so called "sets" to access credentials in a modular fashion. These
* are implemented through the credential_set_t interface.
* The manager additionally does trust chain verification and trust status
- * chaching. A set may call the managers methods if it needs credentials itself,
- * the manager uses recursive locking.
+ * caching. A set may call the managers methods if it needs credentials itself.
+ * The manager uses recursive locking.
*
* @verbatim
@@ -62,8 +62,8 @@ typedef struct credential_manager_t credential_manager_t;
@endverbatim
*
- * The credential manager uses rwlocks for performance reasons, credential
- * sets must be fully thread save.
+ * The credential manager uses rwlocks for performance reasons. Credential
+ * sets must be fully thread-safe.
*/
struct credential_manager_t {
@@ -84,7 +84,7 @@ struct credential_manager_t {
*
* The enumerator enumerates over:
* shared_key_t*, id_match_t me, id_match_t other
- * But must accepts values for the id_matches.
+ * But must accept values for the id_matches.
*
* @param type kind of requested shared key
* @param first first subject between key is shared
@@ -120,7 +120,7 @@ struct credential_manager_t {
*
* @param type kind of requested shared key
* @param me own identity
- * @param other peers identity
+ * @param other peer identity
* @return shared_key_t, NULL if none found
*/
shared_key_t *(*get_shared)(credential_manager_t *this, shared_key_type_t type,
@@ -130,7 +130,7 @@ struct credential_manager_t {
*
* The get_private() method gets a secret private key identified by either
* the keyid itself or an id the key belongs to.
- * The auth parameter contains additional information, such as receipients
+ * The auth parameter contains additional information, such as recipients
* trusted CA certs. Auth gets filled with subject and CA certificates
* needed to validate a created signature.
*
@@ -146,7 +146,7 @@ struct credential_manager_t {
* Create an enumerator over trusted certificates.
*
* This method creates an enumerator over trusted certificates. The auth
- * parameter (if given) recevies the trustchain used to validate
+ * parameter (if given) receives the trustchain used to validate
* the certificate. The resulting enumerator enumerates over
* certificate_t*, auth_cfg_t*.
* If online is set, revocations are checked online for the whole
@@ -163,7 +163,7 @@ struct credential_manager_t {
/**
* Create an enumerator over trusted public keys.
*
- * This method gets a an enumerator over trusted public keys to verify a
+ * This method creates an enumerator over trusted public keys to verify a
* signature created by id. The auth parameter contains additional
* authentication infos, e.g. peer and intermediate certificates.
* The resulting enumerator enumerates over public_key_t *, auth_cfg_t *,
@@ -180,7 +180,7 @@ struct credential_manager_t {
key_type_t type, identification_t *id, auth_cfg_t *auth);
/**
- * Cache a certificate by invoking cache_cert() on all registerd sets.
+ * Cache a certificate by invoking cache_cert() on all registered sets.
*
* @param cert certificate to cache
*/
@@ -199,8 +199,8 @@ struct credential_manager_t {
/**
* Check if a given subject certificate is issued by an issuer certificate.
*
- * This operation does signature verification, but uses the credential
- * managers cache for to speed up the operation.
+ * This operation does signature verification using the credential
+ * manager's cache to speed up the operation.
*
* @param subject subject certificate to check
* @param issuer issuer certificate that potentially has signed subject
@@ -228,7 +228,7 @@ struct credential_manager_t {
*
* To add a credential set for the current trustchain verification
* operation, sets may be added for the calling thread only. This
- * does not require a write lock and is therefore a much less expensive
+ * does not require a write lock and is therefore a much cheaper
* operation.
*
* @param set set to register
diff --git a/src/libstrongswan/credentials/credential_set.h b/src/libstrongswan/credentials/credential_set.h
index 0eee237cb..8673c484f 100644
--- a/src/libstrongswan/credentials/credential_set.h
+++ b/src/libstrongswan/credentials/credential_set.h
@@ -38,7 +38,7 @@ typedef struct credential_set_t credential_set_t;
* A credential set enumerator may not block the credential set, i.e. multiple
* threads must be able to hold multiple enumerators, as the credential manager
* is higly parallelized. The best way to achieve this is by using shared
- * read locks for the enumerators only. Otherwiese deadlocks will occur.
+ * read locks for the enumerators only. Otherwise deadlocks will occur.
* The writing cache_cert() routine is called by the manager only if no
* enumerator is alive, so it is save to use a write lock there.
*/
@@ -97,7 +97,7 @@ struct credential_set_t {
/**
* Cache a certificate in the credential set.
*
- * The caching policy is implementation dependent, the sets may cache the
+ * The caching policy is implementation dependent. The sets may cache the
* certificate in-memory, persistent on disk or not at all.
*
* @param cert certificate to cache
diff --git a/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c b/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c
index fecc9910e..fb18fb53d 100644
--- a/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c
+++ b/src/libstrongswan/credentials/ietf_attributes/ietf_attributes.c
@@ -102,15 +102,14 @@ static void ietf_attr_destroy(ietf_attr_t *this)
*/
static ietf_attr_t* ietf_attr_create(ietf_attribute_type_t type, chunk_t value)
{
- ietf_attr_t *this = malloc_thing(ietf_attr_t);
+ ietf_attr_t *this;
- /* initialize */
- this->type = type;
- this->value = chunk_clone(value);
-
- /* function */
- this->compare = ietf_attr_compare;
- this->destroy = ietf_attr_destroy;
+ INIT(this,
+ .compare = ietf_attr_compare,
+ .destroy = ietf_attr_destroy,
+ .type = type,
+ .value = chunk_clone(value),
+ );
return this;
}
@@ -142,10 +141,8 @@ struct private_ietf_attributes_t {
refcount_t ref;
};
-/**
- * Implementation of ietf_attributes_t.get_string.
- */
-static char* get_string(private_ietf_attributes_t *this)
+METHOD(ietf_attributes_t, get_string, char*,
+ private_ietf_attributes_t *this)
{
if (this->string == NULL)
{
@@ -217,10 +214,8 @@ static char* get_string(private_ietf_attributes_t *this)
return this->string;
}
-/**
- * Implementation of ietf_attributes_t.get_encoding.
- */
-static chunk_t get_encoding(private_ietf_attributes_t *this)
+METHOD(ietf_attributes_t, get_encoding, chunk_t,
+ private_ietf_attributes_t *this)
{
chunk_t values;
size_t size = 0;
@@ -270,7 +265,11 @@ static chunk_t get_encoding(private_ietf_attributes_t *this)
return asn1_wrap(ASN1_SEQUENCE, "m", values);
}
-static bool equals(private_ietf_attributes_t *this, private_ietf_attributes_t *other)
+/**
+ * Implementation of ietf_attributes_t.equals.
+ */
+static bool equals(private_ietf_attributes_t *this,
+ private_ietf_attributes_t *other)
{
bool result = TRUE;
@@ -304,7 +303,11 @@ static bool equals(private_ietf_attributes_t *this, private_ietf_attributes_t *o
return result;
}
-static bool matches(private_ietf_attributes_t *this, private_ietf_attributes_t *other)
+/**
+ * Implementation of ietf_attributes_t.matches.
+ */
+static bool matches(private_ietf_attributes_t *this,
+ private_ietf_attributes_t *other)
{
bool result = FALSE;
ietf_attr_t *attr_a, *attr_b;
@@ -364,19 +367,15 @@ static bool matches(private_ietf_attributes_t *this, private_ietf_attributes_t *
return result;
}
-/**
- * Implementation of ietf_attributes_t.get_ref
- */
-static private_ietf_attributes_t* get_ref(private_ietf_attributes_t *this)
+METHOD(ietf_attributes_t, get_ref, ietf_attributes_t*,
+ private_ietf_attributes_t *this)
{
ref_get(&this->ref);
- return this;
+ return &this->public;
}
-/**
- * Implementation of ietf_attributes_t.destroy.
- */
-static void destroy(private_ietf_attributes_t *this)
+METHOD(ietf_attributes_t, destroy, void,
+ private_ietf_attributes_t *this)
{
if (ref_put(&this->ref))
{
@@ -388,18 +387,21 @@ static void destroy(private_ietf_attributes_t *this)
static private_ietf_attributes_t* create_empty(void)
{
- private_ietf_attributes_t *this = malloc_thing(private_ietf_attributes_t);
-
- this->public.get_string = (char* (*)(ietf_attributes_t*))get_string;
- this->public.get_encoding = (chunk_t (*)(ietf_attributes_t*))get_encoding;
- this->public.equals = (bool (*)(ietf_attributes_t*,ietf_attributes_t*))equals;
- this->public.matches = (bool (*)(ietf_attributes_t*,ietf_attributes_t*))matches;
- this->public.get_ref = (ietf_attributes_t* (*)(ietf_attributes_t*))get_ref;
- this->public.destroy = (void (*)(ietf_attributes_t*))destroy;
-
- this->list = linked_list_create();
- this->string = NULL;
- this->ref = 1;
+ private_ietf_attributes_t *this;
+
+ INIT(this,
+ .public = {
+ .get_string = _get_string,
+ .get_encoding = _get_encoding,
+ .equals = (bool (*)(ietf_attributes_t*,ietf_attributes_t*))equals,
+ .matches = (bool (*)(ietf_attributes_t*,ietf_attributes_t*))matches,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .list = linked_list_create(),
+ .ref = 1,
+ );
+
return this;
}
@@ -410,34 +412,24 @@ static void ietf_attributes_add(private_ietf_attributes_t *this,
ietf_attr_t *attr)
{
ietf_attr_t *current_attr;
- bool found = FALSE;
- iterator_t *iterator;
+ enumerator_t *enumerator;
+ int cmp = -1;
- iterator = this->list->create_iterator(this->list, TRUE);
- while (iterator->iterate(iterator, (void **)&current_attr))
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, (void **)&current_attr) &&
+ (cmp = attr->compare(attr, current_attr)) > 0)
{
- int cmp = attr->compare(attr, current_attr);
-
- if (cmp > 0)
- {
- continue;
- }
- if (cmp == 0)
- {
- attr->destroy(attr);
- }
- else
- {
- iterator->insert_before(iterator, attr);
- }
- found = TRUE;
- break;
+ continue;
}
- iterator->destroy(iterator);
- if (!found)
+ if (cmp == 0)
{
- this->list->insert_last(this->list, attr);
+ attr->destroy(attr);
+ }
+ else
+ { /* the enumerator either points to the end or to the attribute > attr */
+ this->list->insert_before(this->list, enumerator, attr);
}
+ enumerator->destroy(enumerator);
}
/*
@@ -527,7 +519,7 @@ ietf_attributes_t *ietf_attributes_create_from_encoding(chunk_t encoded)
ietf_attr_t *attr;
type = (objectID - IETF_ATTR_OCTETS) / 2;
- attr = ietf_attr_create(type, object);
+ attr = ietf_attr_create(type, object);
ietf_attributes_add(this, attr);
}
break;
diff --git a/src/libstrongswan/credentials/keys/private_key.h b/src/libstrongswan/credentials/keys/private_key.h
index e57d3f5a5..b9f7dad55 100644
--- a/src/libstrongswan/credentials/keys/private_key.h
+++ b/src/libstrongswan/credentials/keys/private_key.h
@@ -133,11 +133,11 @@ struct private_key_t {
/**
* Generic private key equals() implementation, usable by implementors.
*
- * @param this first key to compare
- * @param other second key to compare
+ * @param private private key to check
+ * @param other key to compare
* @return TRUE if this is equal to other
*/
-bool private_key_equals(private_key_t *this, private_key_t *other);
+bool private_key_equals(private_key_t *private, private_key_t *other);
/**
* Generic private key belongs_to() implementation, usable by implementors.
@@ -151,10 +151,10 @@ bool private_key_belongs_to(private_key_t *private, public_key_t *public);
/**
* Generic private key has_fingerprint() implementation, usable by implementors.
*
- * @param this key to check fingerprint
+ * @param private private key to check
* @param fingerprint fingerprint to check
* @return TRUE if key has given fingerprint
*/
-bool private_key_has_fingerprint(private_key_t *this, chunk_t fingerprint);
+bool private_key_has_fingerprint(private_key_t *private, chunk_t fingerprint);
#endif /** PRIVATE_KEY_H_ @}*/
diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c
index 22df5dd1b..37bba77d1 100644
--- a/src/libstrongswan/credentials/keys/public_key.c
+++ b/src/libstrongswan/credentials/keys/public_key.c
@@ -17,7 +17,8 @@
#include "public_key.h"
-ENUM(key_type_names, KEY_RSA, KEY_DSA,
+ENUM(key_type_names, KEY_ANY, KEY_DSA,
+ "ANY",
"RSA",
"ECDSA",
"DSA"
diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h
index d20d2736b..fdbe17f2c 100644
--- a/src/libstrongswan/credentials/keys/public_key.h
+++ b/src/libstrongswan/credentials/keys/public_key.h
@@ -151,7 +151,7 @@ struct public_key_t {
* @param scheme encryption scheme to use
* @param plain chunk containing plaintext data
* @param crypto where to allocate encrypted data
- * @return TRUE if data successfully encrypted
+ * @return TRUE if data successfully encrypted
*/
bool (*encrypt)(public_key_t *this, encryption_scheme_t scheme,
chunk_t plain, chunk_t *crypto);
@@ -215,20 +215,20 @@ struct public_key_t {
/**
* Generic public key equals() implementation, usable by implementors.
*
- * @param this first key to compare
- * @param other second key to compare
+ * @param public public key to check
+ * @param other key to compare
* @return TRUE if this is equal to other
*/
-bool public_key_equals(public_key_t *this, public_key_t *other);
+bool public_key_equals(public_key_t *public, public_key_t *other);
/**
* Generic public key has_fingerprint() implementation, usable by implementors.
*
- * @param this key to check fingerprint
+ * @param public public key to check
* @param fingerprint fingerprint to check
* @return TRUE if key has given fingerprint
*/
-bool public_key_has_fingerprint(public_key_t *this, chunk_t fingerprint);
+bool public_key_has_fingerprint(public_key_t *public, chunk_t fingerprint);
/**
* Conversion of ASN.1 signature or hash OID to signature scheme.
diff --git a/src/libstrongswan/credentials/keys/shared_key.c b/src/libstrongswan/credentials/keys/shared_key.c
index f695c078d..1c2d31167 100644
--- a/src/libstrongswan/credentials/keys/shared_key.c
+++ b/src/libstrongswan/credentials/keys/shared_key.c
@@ -51,35 +51,27 @@ struct private_shared_key_t {
refcount_t ref;
};
-/**
- * Implements shared_key_t.get_type
- */
-static shared_key_type_t get_type(private_shared_key_t *this)
+METHOD(shared_key_t, get_type, shared_key_type_t,
+ private_shared_key_t *this)
{
return this->type;
}
-/**
- * Implements shared_key_t.get_key
- */
-static chunk_t get_key(private_shared_key_t *this)
+METHOD(shared_key_t, get_key, chunk_t,
+ private_shared_key_t *this)
{
return this->key;
}
-/**
- * Implements shared_key_t.get_ref
- */
-static shared_key_t* get_ref(private_shared_key_t *this)
+METHOD(shared_key_t, get_ref, shared_key_t*,
+ private_shared_key_t *this)
{
ref_get(&this->ref);
return &this->public;
}
-/**
- * Implementation of shared_key_t.destroy
- */
-static void destroy(private_shared_key_t *this)
+METHOD(shared_key_t, destroy, void,
+ private_shared_key_t *this)
{
if (ref_put(&this->ref))
{
@@ -93,16 +85,19 @@ static void destroy(private_shared_key_t *this)
*/
shared_key_t *shared_key_create(shared_key_type_t type, chunk_t key)
{
- private_shared_key_t *this = malloc_thing(private_shared_key_t);
-
- this->public.get_type = (shared_key_type_t (*)(shared_key_t *this))get_type;
- this->public.get_key = (chunk_t (*)(shared_key_t *this))get_key;
- this->public.get_ref = (shared_key_t* (*)(shared_key_t *this))get_ref;
- this->public.destroy = (void(*)(shared_key_t*))destroy;
-
- this->type = type;
- this->key = key;
- this->ref = 1;
+ private_shared_key_t *this;
+
+ INIT(this,
+ .public = {
+ .get_type = _get_type,
+ .get_key = _get_key,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .type = type,
+ .key = key,
+ .ref = 1,
+ );
return &this->public;
}
diff --git a/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c b/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c
index 225fabe31..2cef23328 100644
--- a/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c
+++ b/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c
@@ -172,12 +172,9 @@ static void wrapper_enumerator_destroy(wrapper_enumerator_t *this)
free(this);
}
-/**
- * implementation of auth_cfg_wrapper_t.set.create_cert_enumerator
- */
-static enumerator_t *create_enumerator(private_auth_cfg_wrapper_t *this,
- certificate_type_t cert, key_type_t key,
- identification_t *id, bool trusted)
+METHOD(credential_set_t, create_enumerator, enumerator_t*,
+ private_auth_cfg_wrapper_t *this, certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
{
wrapper_enumerator_t *enumerator;
@@ -196,10 +193,8 @@ static enumerator_t *create_enumerator(private_auth_cfg_wrapper_t *this,
return &enumerator->public;
}
-/**
- * Implementation of auth_cfg_wrapper_t.destroy
- */
-static void destroy(private_auth_cfg_wrapper_t *this)
+METHOD(auth_cfg_wrapper_t, destroy, void,
+ private_auth_cfg_wrapper_t *this)
{
free(this);
}
@@ -209,16 +204,20 @@ static void destroy(private_auth_cfg_wrapper_t *this)
*/
auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth)
{
- private_auth_cfg_wrapper_t *this = malloc_thing(private_auth_cfg_wrapper_t);
-
- this->public.set.create_private_enumerator = (void*)return_null;
- this->public.set.create_cert_enumerator = (void*)create_enumerator;
- this->public.set.create_shared_enumerator = (void*)return_null;
- this->public.set.create_cdp_enumerator = (void*)return_null;
- this->public.set.cache_cert = (void*)nop;
- this->public.destroy = (void(*)(auth_cfg_wrapper_t*))destroy;
-
- this->auth = auth;
+ private_auth_cfg_wrapper_t *this;
+
+ INIT(this,
+ .public = {
+ .set = {
+ .create_cert_enumerator = _create_enumerator,
+ .create_shared_enumerator = (void*)return_null,
+ .create_cdp_enumerator = (void*)return_null,
+ .cache_cert = (void*)nop,
+ },
+ .destroy = _destroy,
+ },
+ .auth = auth,
+ );
return &this->public;
}
diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c
index 7161ac9ac..968c3e31e 100644
--- a/src/libstrongswan/credentials/sets/cert_cache.c
+++ b/src/libstrongswan/credentials/sets/cert_cache.c
@@ -132,11 +132,8 @@ static void cache(private_cert_cache_t *this,
}
}
-/**
- * Implementation of cert_cache_t.issued_by.
- */
-static bool issued_by(private_cert_cache_t *this,
- certificate_t *subject, certificate_t *issuer)
+METHOD(cert_cache_t, issued_by, bool,
+ private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer)
{
relation_t *found = NULL, *current;
int i;
@@ -270,12 +267,9 @@ static void cert_enumerator_destroy(cert_enumerator_t *this)
free(this);
}
-/**
- * implementation of credential_set_t.create_cert_enumerator
- */
-static enumerator_t *create_enumerator(private_cert_cache_t *this,
- certificate_type_t cert, key_type_t key,
- identification_t *id, bool trusted)
+METHOD(credential_set_t, create_enumerator, enumerator_t*,
+ private_cert_cache_t *this, certificate_type_t cert, key_type_t key,
+ identification_t *id, bool trusted)
{
cert_enumerator_t *enumerator;
@@ -296,10 +290,8 @@ static enumerator_t *create_enumerator(private_cert_cache_t *this,
return &enumerator->public;
}
-/**
- * Implementation of cert_cache_t.flush.
- */
-static void flush(private_cert_cache_t *this, certificate_type_t type)
+METHOD(cert_cache_t, flush, void,
+ private_cert_cache_t *this, certificate_type_t type)
{
relation_t *rel;
int i;
@@ -339,10 +331,8 @@ static void flush(private_cert_cache_t *this, certificate_type_t type)
}
}
-/**
- * Implementation of cert_cache_t.destroy
- */
-static void destroy(private_cert_cache_t *this)
+METHOD(cert_cache_t, destroy, void,
+ private_cert_cache_t *this)
{
relation_t *rel;
int i;
@@ -368,15 +358,20 @@ cert_cache_t *cert_cache_create()
private_cert_cache_t *this;
int i;
- this = malloc_thing(private_cert_cache_t);
- this->public.set.create_private_enumerator = (void*)return_null;
- this->public.set.create_cert_enumerator = (void*)create_enumerator;
- this->public.set.create_shared_enumerator = (void*)return_null;
- this->public.set.create_cdp_enumerator = (void*)return_null;
- this->public.set.cache_cert = (void*)nop;
- this->public.issued_by = (bool(*)(cert_cache_t*, certificate_t *subject, certificate_t *issuer))issued_by;
- this->public.flush = (void(*)(cert_cache_t*, certificate_type_t type))flush;
- this->public.destroy = (void(*)(cert_cache_t*))destroy;
+ INIT(this,
+ .public = {
+ .set = {
+ .create_cert_enumerator = _create_enumerator,
+ .create_private_enumerator = (void*)return_null,
+ .create_shared_enumerator = (void*)return_null,
+ .create_cdp_enumerator = (void*)return_null,
+ .cache_cert = (void*)nop,
+ },
+ .issued_by = _issued_by,
+ .flush = _flush,
+ .destroy = _destroy,
+ },
+ );
for (i = 0; i < CACHE_SIZE; i++)
{
@@ -385,5 +380,6 @@ cert_cache_t *cert_cache_create()
this->relations[i].hits = 0;
this->relations[i].lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
}
+
return &this->public;
}
diff --git a/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c b/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c
index 4786495da..151d69216 100644
--- a/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c
+++ b/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c
@@ -94,12 +94,9 @@ static void enumerator_destroy(wrapper_enumerator_t *this)
free(this);
}
-/**
- * implementation of ocsp_response_wrapper_t.set.create_cert_enumerator
- */
-static enumerator_t *create_enumerator(private_ocsp_response_wrapper_t *this,
- certificate_type_t cert, key_type_t key,
- identification_t *id, bool trusted)
+METHOD(credential_set_t, create_enumerator, enumerator_t*,
+ private_ocsp_response_wrapper_t *this,certificate_type_t cert,
+ key_type_t key, identification_t *id, bool trusted)
{
wrapper_enumerator_t *enumerator;
@@ -118,10 +115,8 @@ static enumerator_t *create_enumerator(private_ocsp_response_wrapper_t *this,
return &enumerator->public;
}
-/**
- * Implementation of ocsp_response_wrapper_t.destroy
- */
-static void destroy(private_ocsp_response_wrapper_t *this)
+METHOD(ocsp_response_wrapper_t, destroy, void,
+ private_ocsp_response_wrapper_t *this)
{
free(this);
}
@@ -131,16 +126,21 @@ static void destroy(private_ocsp_response_wrapper_t *this)
*/
ocsp_response_wrapper_t *ocsp_response_wrapper_create(ocsp_response_t *response)
{
- private_ocsp_response_wrapper_t *this = malloc_thing(private_ocsp_response_wrapper_t);
-
- this->public.set.create_private_enumerator = (void*)return_null;
- this->public.set.create_cert_enumerator = (void*)create_enumerator;
- this->public.set.create_shared_enumerator = (void*)return_null;
- this->public.set.create_cdp_enumerator = (void*)return_null;
- this->public.set.cache_cert = (void*)nop;
- this->public.destroy = (void(*)(ocsp_response_wrapper_t*))destroy;
-
- this->response = response;
+ private_ocsp_response_wrapper_t *this;
+
+ INIT(this,
+ .public = {
+ .set = {
+ .create_cert_enumerator = _create_enumerator,
+ .create_private_enumerator = (void*)return_null,
+ .create_shared_enumerator = (void*)return_null,
+ .create_cdp_enumerator = (void*)return_null,
+ .cache_cert = (void*)nop,
+ },
+ .destroy = _destroy,
+ },
+ .response = response,
+ );
return &this->public;
}
diff --git a/src/libstrongswan/crypto/aead.h b/src/libstrongswan/crypto/aead.h
index d560381d9..3f6abb4f9 100644
--- a/src/libstrongswan/crypto/aead.h
+++ b/src/libstrongswan/crypto/aead.h
@@ -111,7 +111,7 @@ struct aead_t {
* Create a aead instance using traditional transforms.
*
* @param crypter encryption transform for this aead
- * @param signer integrity tranform for this aead
+ * @param signer integrity transform for this aead
* @return aead transform
*/
aead_t *aead_create(crypter_t *crypter, signer_t *signer);
diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c
index 4635dccea..8b1daa885 100644
--- a/src/libstrongswan/crypto/crypto_tester.c
+++ b/src/libstrongswan/crypto/crypto_tester.c
@@ -102,6 +102,8 @@ static const char* get_name(void *sym)
return "unknown";
}
+#ifdef CLOCK_THREAD_CPUTIME_ID
+
/**
* Start a benchmark timer
*/
@@ -122,6 +124,14 @@ static u_int end_timing(struct timespec *start)
(end.tv_sec - start->tv_sec) * 1000;
}
+#else /* CLOCK_THREAD_CPUTIME_ID */
+
+/* Make benchmarking a no-op if CLOCK_THREAD_CPUTIME_ID is not available */
+#define start_timing(start) ((start)->tv_sec = 0, (start)->tv_nsec = 0)
+#define end_timing(...) (this->bench_time)
+
+#endif /* CLOCK_THREAD_CPUTIME_ID */
+
/**
* Benchmark a crypter
*/
diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/diffie_hellman.c
index 5f7365321..1124ee6f7 100644
--- a/src/libstrongswan/crypto/diffie_hellman.c
+++ b/src/libstrongswan/crypto/diffie_hellman.c
@@ -64,7 +64,8 @@ static struct {
0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
- 0xF4,0x4C,0x42,0xE9,0xA6,0x3A,0x36,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF)
+ 0xF4,0x4C,0x42,0xE9,0xA6,0x3A,0x36,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF),
+ .exp_len = 0,
},
},{
.group = MODP_1024_BIT, .opt_exp = 32, .public = {
@@ -77,7 +78,8 @@ static struct {
0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
- 0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF)
+ 0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF),
+ .exp_len = 0,
},
},{
.group = MODP_1536_BIT, .opt_exp = 32, .public = {
@@ -94,7 +96,8 @@ static struct {
0x98,0xDA,0x48,0x36,0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,0x20,0x85,0x52,0xBB,
0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,
- 0xF1,0x74,0x6C,0x08,0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF)
+ 0xF1,0x74,0x6C,0x08,0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF),
+ .exp_len = 0,
},
},{
.group = MODP_2048_BIT, .opt_exp = 48, .public = {
@@ -115,7 +118,8 @@ static struct {
0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,0xEC,0x07,0xA2,0x8F,
0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,
0x39,0x95,0x49,0x7C,0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
- 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF)
+ 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF),
+ .exp_len = 0,
},
},{
.group = MODP_3072_BIT, .opt_exp = 48, .public = {
@@ -144,7 +148,8 @@ static struct {
0xD8,0x76,0x02,0x73,0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,0xBA,0xD9,0x46,0xE2,
0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,
- 0x4B,0x82,0xD1,0x20,0xA9,0x3A,0xD2,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF)
+ 0x4B,0x82,0xD1,0x20,0xA9,0x3A,0xD2,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF),
+ .exp_len = 0,
},
},{
.group = MODP_4096_BIT, .opt_exp = 64, .public = {
@@ -181,7 +186,8 @@ static struct {
0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,
0xB8,0x1B,0xDD,0x76,0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,0x90,0xA6,0xC0,0x8F,
- 0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF)
+ 0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF),
+ .exp_len = 0,
},
},{
.group = MODP_6144_BIT, .opt_exp = 64, .public = {
@@ -234,7 +240,8 @@ static struct {
0xF5,0x50,0xAA,0x3D,0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,0x6E,0x3C,0x04,0x68,
0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,
- 0xE6,0x94,0xF9,0x1E,0x6D,0xCC,0x40,0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF)
+ 0xE6,0x94,0xF9,0x1E,0x6D,0xCC,0x40,0x24,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF),
+ .exp_len = 0,
},
},{
.group = MODP_8192_BIT, .opt_exp = 64, .public = {
@@ -303,7 +310,8 @@ static struct {
0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,0xD5,0xEE,0x38,0x2B,
0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,
0x9E,0x30,0x50,0xE2,0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
- 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF)
+ 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF),
+ .exp_len = 0,
},
},{
.group = MODP_1024_160, .opt_exp = 20, .public = {
diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/diffie_hellman.h
index 9ae772363..cab3b1ba7 100644
--- a/src/libstrongswan/crypto/diffie_hellman.h
+++ b/src/libstrongswan/crypto/diffie_hellman.h
@@ -57,7 +57,7 @@ enum diffie_hellman_group_t {
ECP_224_BIT = 26,
/** insecure NULL diffie hellman group for testing, in PRIVATE USE */
MODP_NULL = 1024,
- /** MODP group with custon generator, prime */
+ /** MODP group with custom generator/prime */
MODP_CUSTOM = 1025,
};
@@ -74,8 +74,7 @@ struct diffie_hellman_t {
/**
* Returns the shared secret of this diffie hellman exchange.
*
- * Space for returned secret is allocated and must be
- * freed by the caller.
+ * Space for returned secret is allocated and must be freed by the caller.
*
* @param secret shared secret will be written into this chunk
* @return SUCCESS, FAILED if not both DH values are set
@@ -108,7 +107,7 @@ struct diffie_hellman_t {
diffie_hellman_group_t (*get_dh_group) (diffie_hellman_t *this);
/**
- * Destroys an diffie_hellman_t object.
+ * Destroys a diffie_hellman_t object.
*/
void (*destroy) (diffie_hellman_t *this);
};
diff --git a/src/libstrongswan/crypto/pkcs9.c b/src/libstrongswan/crypto/pkcs9.c
index e3ba0f129..63a615238 100644
--- a/src/libstrongswan/crypto/pkcs9.c
+++ b/src/libstrongswan/crypto/pkcs9.c
@@ -68,8 +68,6 @@ struct attribute_t {
/**
* Destroys the attribute.
- *
- * @param this attribute to destroy
*/
void (*destroy) (attribute_t *this);
@@ -184,23 +182,24 @@ static void attribute_destroy(attribute_t *this)
*/
static attribute_t *attribute_create(int oid, chunk_t value)
{
- attribute_t *this = malloc_thing(attribute_t);
-
- this->oid = oid;
- this->value = chunk_clone(value);
- this->encoding = asn1_wrap(ASN1_SEQUENCE, "cm",
- asn1_attributeIdentifier(oid),
- asn1_simple_object(ASN1_SET, value));
- this->destroy = (void (*) (attribute_t*))attribute_destroy;
+ attribute_t *this;
+
+ INIT(this,
+ .destroy = attribute_destroy,
+ .oid = oid,
+ .value = chunk_clone(value),
+ .encoding = asn1_wrap(ASN1_SEQUENCE, "cm",
+ asn1_attributeIdentifier(oid),
+ asn1_simple_object(ASN1_SET, value)),
+ );
+
return this;
}
-/**
- * Implements pkcs9_t.build_encoding
- */
-static void build_encoding(private_pkcs9_t *this)
+METHOD(pkcs9_t, build_encoding, void,
+ private_pkcs9_t *this)
{
- iterator_t *iterator;
+ enumerator_t *enumerator;
attribute_t *attribute;
u_int attributes_len = 0;
@@ -214,33 +213,31 @@ static void build_encoding(private_pkcs9_t *this)
}
/* compute the total length of the encoded attributes */
- iterator = this->attributes->create_iterator(this->attributes, TRUE);
+ enumerator = this->attributes->create_enumerator(this->attributes);
- while (iterator->iterate(iterator, (void**)&attribute))
+ while (enumerator->enumerate(enumerator, (void**)&attribute))
{
attributes_len += attribute->encoding.len;
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
/* allocate memory for the attributes and build the encoding */
{
u_char *pos = asn1_build_object(&this->encoding, ASN1_SET, attributes_len);
- iterator = this->attributes->create_iterator(this->attributes, TRUE);
+ enumerator = this->attributes->create_enumerator(this->attributes);
- while (iterator->iterate(iterator, (void**)&attribute))
+ while (enumerator->enumerate(enumerator, (void**)&attribute))
{
memcpy(pos, attribute->encoding.ptr, attribute->encoding.len);
pos += attribute->encoding.len;
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
}
-/**
- * Implements pkcs9_t.get_encoding
- */
-static chunk_t get_encoding(private_pkcs9_t *this)
+METHOD(pkcs9_t, get_encoding, chunk_t,
+ private_pkcs9_t *this)
{
if (this->encoding.ptr == NULL)
{
@@ -249,16 +246,15 @@ static chunk_t get_encoding(private_pkcs9_t *this)
return this->encoding;
}
-/**
- * Implements pkcs9_t.get_attribute
- */
-static chunk_t get_attribute(private_pkcs9_t *this, int oid)
+METHOD(pkcs9_t, get_attribute, chunk_t,
+ private_pkcs9_t *this, int oid)
{
- iterator_t *iterator = this->attributes->create_iterator(this->attributes, TRUE);
+ enumerator_t *enumerator;
chunk_t value = chunk_empty;
attribute_t *attribute;
- while (iterator->iterate(iterator, (void**)&attribute))
+ enumerator = this->attributes->create_enumerator(this->attributes);
+ while (enumerator->enumerate(enumerator, (void**)&attribute))
{
if (attribute->oid == oid)
{
@@ -266,24 +262,20 @@ static chunk_t get_attribute(private_pkcs9_t *this, int oid)
break;
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return value;
}
-/**
- * Implements pkcs9_t.set_attribute
- */
-static void set_attribute(private_pkcs9_t *this, int oid, chunk_t value)
+METHOD(pkcs9_t, set_attribute, void,
+ private_pkcs9_t *this, int oid, chunk_t value)
{
attribute_t *attribute = attribute_create(oid, value);
this->attributes->insert_last(this->attributes, (void*)attribute);
}
-/**
- * Implements pkcs9_t.get_messageDigest
- */
-static chunk_t get_messageDigest(private_pkcs9_t *this)
+METHOD(pkcs9_t, get_messageDigest, chunk_t,
+ private_pkcs9_t *this)
{
const int oid = OID_PKCS9_MESSAGE_DIGEST;
chunk_t value = get_attribute(this, oid);
@@ -300,10 +292,8 @@ static chunk_t get_messageDigest(private_pkcs9_t *this)
return chunk_clone(value);
}
-/**
- * Implements pkcs9_t.set_attribute
- */
-static void set_messageDigest(private_pkcs9_t *this, chunk_t value)
+METHOD(pkcs9_t, set_messageDigest, void,
+ private_pkcs9_t *this, chunk_t value)
{
const int oid = OID_PKCS9_MESSAGE_DIGEST;
chunk_t messageDigest = asn1_simple_object(asn1_attributeType(oid), value);
@@ -312,10 +302,8 @@ static void set_messageDigest(private_pkcs9_t *this, chunk_t value)
free(messageDigest.ptr);
}
-/**
- * Implements pkcs9_t.destroy
- */
-static void destroy(private_pkcs9_t *this)
+METHOD(pkcs9_t, destroy, void,
+ private_pkcs9_t *this)
{
this->attributes->destroy_offset(this->attributes, offsetof(attribute_t, destroy));
free(this->encoding.ptr);
@@ -327,20 +315,20 @@ static void destroy(private_pkcs9_t *this)
*/
static private_pkcs9_t *pkcs9_create_empty(void)
{
- private_pkcs9_t *this = malloc_thing(private_pkcs9_t);
-
- /* initialize */
- this->encoding = chunk_empty;
- this->attributes = linked_list_create();
-
- /*public functions */
- this->public.build_encoding = (void (*) (pkcs9_t*))build_encoding;
- this->public.get_encoding = (chunk_t (*) (pkcs9_t*))get_encoding;
- this->public.get_attribute = (chunk_t (*) (pkcs9_t*,int))get_attribute;
- this->public.set_attribute = (void (*) (pkcs9_t*,int,chunk_t))set_attribute;
- this->public.get_messageDigest = (chunk_t (*) (pkcs9_t*))get_messageDigest;
- this->public.set_messageDigest = (void (*) (pkcs9_t*,chunk_t))set_messageDigest;
- this->public.destroy = (void (*) (pkcs9_t*))destroy;
+ private_pkcs9_t *this;
+
+ INIT(this,
+ .public = {
+ .build_encoding = _build_encoding,
+ .get_encoding = _get_encoding,
+ .get_attribute = _get_attribute,
+ .set_attribute = _set_attribute,
+ .get_messageDigest = _get_messageDigest,
+ .set_messageDigest = _set_messageDigest,
+ .destroy = _destroy,
+ },
+ .attributes = linked_list_create(),
+ );
return this;
}
diff --git a/src/libstrongswan/crypto/prf_plus.c b/src/libstrongswan/crypto/prf_plus.c
index 6bd0f7465..8e815e608 100644
--- a/src/libstrongswan/crypto/prf_plus.c
+++ b/src/libstrongswan/crypto/prf_plus.c
@@ -56,10 +56,8 @@ struct private_prf_plus_t {
u_int8_t appending_octet;
};
-/**
- * Implementation of prf_plus_t.get_bytes.
- */
-static void get_bytes(private_prf_plus_t *this, size_t length, u_int8_t *buffer)
+METHOD(prf_plus_t, get_bytes, void,
+ private_prf_plus_t *this, size_t length, u_int8_t *buffer)
{
chunk_t appending_chunk;
size_t bytes_in_round;
@@ -89,10 +87,8 @@ static void get_bytes(private_prf_plus_t *this, size_t length, u_int8_t *buffer)
}
}
-/**
- * Implementation of prf_plus_t.allocate_bytes.
- */
-static void allocate_bytes(private_prf_plus_t *this, size_t length, chunk_t *chunk)
+METHOD(prf_plus_t, allocate_bytes, void,
+ private_prf_plus_t *this, size_t length, chunk_t *chunk)
{
if (length)
{
@@ -106,10 +102,8 @@ static void allocate_bytes(private_prf_plus_t *this, size_t length, chunk_t *chu
}
}
-/**
- * Implementation of prf_plus_t.destroy.
- */
-static void destroy(private_prf_plus_t *this)
+METHOD(prf_plus_t, destroy, void,
+ private_prf_plus_t *this)
{
free(this->buffer.ptr);
free(this->seed.ptr);
@@ -124,15 +118,14 @@ prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed)
private_prf_plus_t *this;
chunk_t appending_chunk;
- this = malloc_thing(private_prf_plus_t);
-
- /* set public methods */
- this->public.get_bytes = (void (*)(prf_plus_t *,size_t,u_int8_t*))get_bytes;
- this->public.allocate_bytes = (void (*)(prf_plus_t *,size_t,chunk_t*))allocate_bytes;
- this->public.destroy = (void (*)(prf_plus_t *))destroy;
-
- /* take over prf */
- this->prf = prf;
+ INIT(this,
+ .public = {
+ .get_bytes = _get_bytes,
+ .allocate_bytes = _allocate_bytes,
+ .destroy = _destroy,
+ },
+ .prf = prf,
+ );
/* allocate buffer for prf output */
this->buffer.len = prf->get_block_size(prf);
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.c b/src/libstrongswan/crypto/proposal/proposal_keywords.c
index d65955a2e..2060864a5 100644
--- a/src/libstrongswan/crypto/proposal/proposal_keywords.c
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords.c
@@ -59,7 +59,7 @@ struct proposal_token {
u_int16_t keysize;
};
-#define TOTAL_KEYWORDS 119
+#define TOTAL_KEYWORDS 122
#define MIN_WORD_LENGTH 3
#define MAX_WORD_LENGTH 17
#define MIN_HASH_VALUE 9
@@ -90,7 +90,7 @@ hash (str, len)
214, 214, 214, 214, 214, 214, 214, 214, 214, 214,
214, 214, 214, 214, 214, 214, 214, 214, 214, 214,
214, 214, 214, 214, 214, 131, 214, 3, 22, 21,
- 3, 1, 101, 48, 3, 4, 214, 214, 3, 214,
+ 3, 1, 101, 48, 3, 4, 214, 214, 3, 10,
57, 4, 214, 214, 94, 6, 3, 32, 214, 214,
214, 214, 214, 214, 214, 214, 214, 214, 214, 214,
214, 214, 214, 214, 214, 214, 214, 214, 214, 214,
@@ -196,7 +196,9 @@ static const struct proposal_token wordlist[] =
{"modp768", DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0},
{"md5", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0},
{"sha384", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0},
+ {"aescmac", INTEGRITY_ALGORITHM, AUTH_AES_CMAC_96, 0},
{"aes256ccm8", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8, 256},
+ {"md5_128", INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_128, 0},
{"aes256ccm96", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256},
{"aes256ccm12", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12, 256},
{"aes256ccm128", ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16, 256},
@@ -250,6 +252,7 @@ static const struct proposal_token wordlist[] =
{"aes192gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 192},
{"aes128gcm64", ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8, 128},
{"esn", EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0},
+ {"sha1_160", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_160, 0},
{"aes256ctr", ENCRYPTION_ALGORITHM, ENCR_AES_CTR, 256},
{"blowfish256", ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256},
{"sha2_256", INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0},
@@ -273,20 +276,20 @@ static const short lookup[] =
-1, -1, -1, -1, 29, 30, 31, 32, 33, 34,
35, -1, 36, -1, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
- 53, -1, 54, -1, 55, -1, 56, -1, 57, -1,
- 58, -1, 59, 60, 61, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, -1, 73, -1, 74,
- -1, 75, -1, 76, 77, 78, 79, 80, -1, 81,
- 82, 83, 84, 85, -1, 86, 87, -1, 88, -1,
- -1, 89, 90, -1, 91, -1, -1, 92, -1, 93,
- 94, 95, 96, -1, 97, -1, 98, 99, 100, 101,
- 102, 103, -1, -1, -1, 104, -1, -1, 105, 106,
- -1, 107, -1, -1, -1, 108, 109, -1, -1, 110,
- 111, -1, -1, -1, 112, 113, -1, 114, 115, -1,
+ 53, 54, 55, 56, 57, -1, 58, -1, 59, -1,
+ 60, -1, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 74, -1, 75, -1, 76,
+ -1, 77, -1, 78, 79, 80, 81, 82, -1, 83,
+ 84, 85, 86, 87, -1, 88, 89, -1, 90, -1,
+ -1, 91, 92, -1, 93, -1, -1, 94, -1, 95,
+ 96, 97, 98, -1, 99, -1, 100, 101, 102, 103,
+ 104, 105, -1, -1, -1, 106, -1, -1, 107, 108,
+ -1, 109, -1, -1, 110, 111, 112, -1, -1, 113,
+ 114, -1, -1, -1, 115, 116, -1, 117, 118, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 116, -1, -1, -1, 117,
- -1, -1, -1, 118
+ -1, -1, -1, -1, -1, 119, -1, -1, -1, 120,
+ -1, -1, -1, 121
};
#ifdef __GNUC__
diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.txt b/src/libstrongswan/crypto/proposal/proposal_keywords.txt
index 4ef664d8f..1d04f2dc4 100644
--- a/src/libstrongswan/crypto/proposal/proposal_keywords.txt
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords.txt
@@ -118,6 +118,7 @@ twofish192, ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 192
twofish256, ENCRYPTION_ALGORITHM, ENCR_TWOFISH_CBC, 256
sha, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0
sha1, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0
+sha1_160, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_160, 0
sha256, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0
sha2_256, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0
sha256_96, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_96, 0
@@ -127,8 +128,10 @@ sha2_384, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0
sha512, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0
sha2_512, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0
md5, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0
+md5_128, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_128, 0
aesxcbc, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0
camelliaxcbc, INTEGRITY_ALGORITHM, AUTH_CAMELLIA_XCBC_96, 0
+aescmac, INTEGRITY_ALGORITHM, AUTH_AES_CMAC_96, 0
modpnull, DIFFIE_HELLMAN_GROUP, MODP_NULL, 0
modp768, DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0
modp1024, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0
diff --git a/src/libstrongswan/crypto/signers/signer.h b/src/libstrongswan/crypto/signers/signer.h
index e2c224d8b..c6870e475 100644
--- a/src/libstrongswan/crypto/signers/signer.h
+++ b/src/libstrongswan/crypto/signers/signer.h
@@ -66,9 +66,9 @@ enum integrity_algorithm_t {
AUTH_HMAC_SHA1_128 = 1025,
/** SHA256 96 bit truncation variant, supported by Linux kernels */
AUTH_HMAC_SHA2_256_96 = 1026,
- /** SHA256 full length tuncation variant, as used in TLS */
+ /** SHA256 full length truncation variant, as used in TLS */
AUTH_HMAC_SHA2_256_256 = 1027,
- /** SHA384 full length tuncation variant, as used in TLS */
+ /** SHA384 full length truncation variant, as used in TLS */
AUTH_HMAC_SHA2_384_384 = 1028,
/** draft-kanno-ipsecme-camellia-xcbc, not yet assigned by IANA */
AUTH_CAMELLIA_XCBC_96 = 1029,
diff --git a/src/libstrongswan/database/database.c b/src/libstrongswan/database/database.c
new file mode 100644
index 000000000..60ef6cd7c
--- /dev/null
+++ b/src/libstrongswan/database/database.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 "database.h"
+
+ENUM(db_driver_names, DB_ANY, DB_MYSQL,
+ "any",
+ "SQLite",
+ "MySQL",
+);
diff --git a/src/libstrongswan/database/database.h b/src/libstrongswan/database/database.h
index 8df1c6f7f..dda29b5fb 100644
--- a/src/libstrongswan/database/database.h
+++ b/src/libstrongswan/database/database.h
@@ -49,6 +49,8 @@ enum db_type_t {
* Database implementation type.
*/
enum db_driver_t {
+ /** matches to other databases */
+ DB_ANY = 0,
/** SQLite database */
DB_SQLITE,
/** MySQL database */
@@ -56,6 +58,11 @@ enum db_driver_t {
};
/**
+ * Names for db_driver_t
+ */
+extern enum_name_t *db_driver_names;
+
+/**
* Interface for a database implementation.
*
* @code
diff --git a/src/libstrongswan/database/database_factory.c b/src/libstrongswan/database/database_factory.c
index 3936565a1..909522d64 100644
--- a/src/libstrongswan/database/database_factory.c
+++ b/src/libstrongswan/database/database_factory.c
@@ -41,10 +41,8 @@ struct private_database_factory_t {
mutex_t *mutex;
};
-/**
- * Implementation of database_factory_t.create.
- */
-static database_t* create(private_database_factory_t *this, char *uri)
+METHOD(database_factory_t, create, database_t*,
+ private_database_factory_t *this, char *uri)
{
enumerator_t *enumerator;
database_t *database = NULL;
@@ -65,32 +63,24 @@ static database_t* create(private_database_factory_t *this, char *uri)
return database;
}
-/**
- * Implementation of database_factory_t.add_database.
- */
-static void add_database(private_database_factory_t *this,
- database_constructor_t create)
+METHOD(database_factory_t, add_database, void,
+ private_database_factory_t *this, database_constructor_t create)
{
this->mutex->lock(this->mutex);
this->databases->insert_last(this->databases, create);
this->mutex->unlock(this->mutex);
}
-/**
- * Implementation of database_factory_t.remove_database.
- */
-static void remove_database(private_database_factory_t *this,
- database_constructor_t create)
+METHOD(database_factory_t, remove_database, void,
+ private_database_factory_t *this, database_constructor_t create)
{
this->mutex->lock(this->mutex);
this->databases->remove(this->databases, create, NULL);
this->mutex->unlock(this->mutex);
}
-/**
- * Implementation of database_factory_t.destroy
- */
-static void destroy(private_database_factory_t *this)
+METHOD(database_factory_t, destroy, void,
+ private_database_factory_t *this)
{
this->databases->destroy(this->databases);
this->mutex->destroy(this->mutex);
@@ -102,15 +92,18 @@ static void destroy(private_database_factory_t *this)
*/
database_factory_t *database_factory_create()
{
- private_database_factory_t *this = malloc_thing(private_database_factory_t);
-
- this->public.create = (database_t*(*)(database_factory_t*, char *url))create;
- this->public.add_database = (void(*)(database_factory_t*, database_constructor_t))add_database;
- this->public.remove_database = (void(*)(database_factory_t*, database_constructor_t))remove_database;
- this->public.destroy = (void(*)(database_factory_t*))destroy;
-
- this->databases = linked_list_create();
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
+ private_database_factory_t *this;
+
+ INIT(this,
+ .public = {
+ .create = _create,
+ .add_database = _add_database,
+ .remove_database = _remove_database,
+ .destroy = _destroy,
+ },
+ .databases = linked_list_create(),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ );
return &this->public;
}
diff --git a/src/libstrongswan/debug.c b/src/libstrongswan/debug.c
index 6ded70248..d6c5b06b6 100644
--- a/src/libstrongswan/debug.c
+++ b/src/libstrongswan/debug.c
@@ -26,8 +26,12 @@ ENUM(debug_names, DBG_DMN, DBG_LIB,
"CFG",
"KNL",
"NET",
+ "ASN",
"ENC",
"TNC",
+ "IMC",
+ "IMV",
+ "PTS",
"TLS",
"LIB",
);
@@ -41,8 +45,12 @@ ENUM(debug_lower_names, DBG_DMN, DBG_LIB,
"cfg",
"knl",
"net",
+ "asn",
"enc",
"tnc",
+ "imc",
+ "imv",
+ "pts",
"tls",
"lib",
);
diff --git a/src/libstrongswan/debug.h b/src/libstrongswan/debug.h
index d3399bff6..2a6ff98ad 100644
--- a/src/libstrongswan/debug.h
+++ b/src/libstrongswan/debug.h
@@ -48,10 +48,18 @@ enum debug_t {
DBG_KNL,
/** networking/sockets */
DBG_NET,
+ /** low-level encoding/decoding (ASN.1, X.509 etc.) */
+ DBG_ASN,
/** message encoding/decoding */
DBG_ENC,
/** trusted network connect */
DBG_TNC,
+ /** integrity measurement client */
+ DBG_IMC,
+ /** integrity measurement verifier */
+ DBG_IMV,
+ /** platform trust service */
+ DBG_PTS,
/** libtls */
DBG_TLS,
/** libstrongswan */
diff --git a/src/libstrongswan/eap/eap.c b/src/libstrongswan/eap/eap.c
index 11b475d8f..efd3ee981 100644
--- a/src/libstrongswan/eap/eap.c
+++ b/src/libstrongswan/eap/eap.c
@@ -87,24 +87,6 @@ ENUM_NEXT(eap_type_short_names, EAP_DYNAMIC, EAP_EXPERIMENTAL, EAP_TNC,
"XP");
ENUM_END(eap_type_short_names, EAP_EXPERIMENTAL);
-ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_SUBJECT_HASH_URL,
- "RULE_IDENTITY",
- "RULE_AUTH_CLASS",
- "RULE_EAP_IDENTITY",
- "RULE_EAP_TYPE",
- "RULE_EAP_VENDOR",
- "RULE_CA_CERT",
- "RULE_IM_CERT",
- "RULE_SUBJECT_CERT",
- "RULE_CRL_VALIDATION",
- "RULE_OCSP_VALIDATION",
- "RULE_GROUP",
- "HELPER_IM_CERT",
- "HELPER_SUBJECT_CERT",
- "HELPER_IM_HASH_URL",
- "HELPER_SUBJECT_HASH_URL",
-);
-
/*
* See header
*/
diff --git a/src/libstrongswan/fetcher/fetcher_manager.h b/src/libstrongswan/fetcher/fetcher_manager.h
index 15250d531..449f284f7 100644
--- a/src/libstrongswan/fetcher/fetcher_manager.h
+++ b/src/libstrongswan/fetcher/fetcher_manager.h
@@ -26,7 +26,7 @@ typedef struct fetcher_manager_t fetcher_manager_t;
#include <fetcher/fetcher.h>
/**
- * Fetches from URIs using registerd fetcher_t instances.
+ * Fetches from URIs using registered fetcher_t instances.
*/
struct fetcher_manager_t {
diff --git a/src/libstrongswan/integrity_checker.h b/src/libstrongswan/integrity_checker.h
index 55a4658f7..891ccccf7 100644
--- a/src/libstrongswan/integrity_checker.h
+++ b/src/libstrongswan/integrity_checker.h
@@ -22,7 +22,6 @@
#define INTEGRITY_CHECKER_H_
#include "utils.h"
-#include "plugins/plugin.h"
typedef struct integrity_checker_t integrity_checker_t;
typedef struct integrity_checksum_t integrity_checksum_t;
diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c
index b7e75aec5..cd6a41f44 100644
--- a/src/libstrongswan/library.c
+++ b/src/libstrongswan/library.c
@@ -22,12 +22,10 @@
#include <threading/thread.h>
#include <utils/identification.h>
#include <utils/host.h>
+#include <utils/hashtable.h>
#include <selectors/traffic_selector.h>
-#ifdef LEAK_DETECTIVE
-#include <utils/leak_detective.h>
-#endif
-#define CHECKSUM_LIBRARY IPSEC_DIR"/libchecksum.so"
+#define CHECKSUM_LIBRARY IPSEC_LIB_DIR"/libchecksum.so"
typedef struct private_library_t private_library_t;
@@ -41,12 +39,10 @@ struct private_library_t {
*/
library_t public;
-#ifdef LEAK_DETECTIVE
/**
- * Memory leak detective, if enabled
+ * Hashtable with registered objects (name => object)
*/
- leak_detective_t *detective;
-#endif /* LEAK_DETECTIVE */
+ hashtable_t *objects;
};
/**
@@ -55,7 +51,7 @@ struct private_library_t {
library_t *lib;
/**
- * Implementation of library_t.destroy
+ * Deinitialize library
*/
void library_deinit()
{
@@ -65,6 +61,9 @@ void library_deinit()
detailed = lib->settings->get_bool(lib->settings,
"libstrongswan.leak_detective.detailed", TRUE);
+ /* make sure the cache is clear before unloading plugins */
+ lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
+
this->public.scheduler->destroy(this->public.scheduler);
this->public.processor->destroy(this->public.processor);
this->public.plugins->destroy(this->public.plugins);
@@ -76,18 +75,17 @@ void library_deinit()
this->public.fetcher->destroy(this->public.fetcher);
this->public.db->destroy(this->public.db);
this->public.printf_hook->destroy(this->public.printf_hook);
+ this->objects->destroy(this->objects);
if (this->public.integrity)
{
this->public.integrity->destroy(this->public.integrity);
}
-#ifdef LEAK_DETECTIVE
- if (this->detective)
+ if (lib->leak_detective)
{
- this->detective->report(this->detective, detailed);
- this->detective->destroy(this->detective);
+ lib->leak_detective->report(lib->leak_detective, detailed);
+ lib->leak_detective->destroy(lib->leak_detective);
}
-#endif /* LEAK_DETECTIVE */
threads_deinit();
@@ -95,21 +93,63 @@ void library_deinit()
lib = NULL;
}
+METHOD(library_t, get, void*,
+ private_library_t *this, char *name)
+{
+ return this->objects->get(this->objects, name);
+}
+
+METHOD(library_t, set, bool,
+ private_library_t *this, char *name, void *object)
+{
+ if (object)
+ {
+ if (this->objects->get(this->objects, name))
+ {
+ return FALSE;
+ }
+ this->objects->put(this->objects, name, object);
+ return TRUE;
+ }
+ return this->objects->remove(this->objects, name) != NULL;
+}
+
+/**
+ * Hashtable hash function
+ */
+static u_int hash(char *key)
+{
+ return chunk_hash(chunk_create(key, strlen(key)));
+}
+
+/**
+ * Hashtable equals function
+ */
+static bool equals(char *a, char *b)
+{
+ return streq(a, b);
+}
+
/*
* see header file
*/
bool library_init(char *settings)
{
+ private_library_t *this;
printf_hook_t *pfh;
- private_library_t *this = malloc_thing(private_library_t);
+
+ INIT(this,
+ .public = {
+ .get = _get,
+ .set = _set,
+ },
+ );
lib = &this->public;
threads_init();
- lib->leak_detective = FALSE;
-
#ifdef LEAK_DETECTIVE
- this->detective = leak_detective_create();
+ lib->leak_detective = leak_detective_create();
#endif /* LEAK_DETECTIVE */
pfh = printf_hook_create();
@@ -136,6 +176,8 @@ bool library_init(char *settings)
pfh->add_handler(pfh, 'R', traffic_selector_printf_hook,
PRINTF_HOOK_ARGTYPE_POINTER, PRINTF_HOOK_ARGTYPE_END);
+ this->objects = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 4);
this->public.settings = settings_create(settings);
this->public.crypto = crypto_factory_create();
this->public.creds = credential_factory_create();
@@ -146,7 +188,6 @@ bool library_init(char *settings)
this->public.processor = processor_create();
this->public.scheduler = scheduler_create();
this->public.plugins = plugin_loader_create();
- this->public.integrity = NULL;
if (lib->settings->get_bool(lib->settings,
"libstrongswan.integrity_test", FALSE))
diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h
index 034ff10c5..7e76e1927 100644
--- a/src/libstrongswan/library.h
+++ b/src/libstrongswan/library.h
@@ -19,6 +19,9 @@
* @defgroup asn1 asn1
* @ingroup libstrongswan
*
+ * @defgroup bio bio
+ * @ingroup libstrongswan
+ *
* @defgroup credentials credentials
* @ingroup libstrongswan
*
@@ -69,7 +72,6 @@
#include "chunk.h"
#include "settings.h"
#include "integrity_checker.h"
-#include "plugins/plugin_loader.h"
#include "processing/processor.h"
#include "processing/scheduler.h"
#include "crypto/crypto_factory.h"
@@ -78,6 +80,8 @@
#include "credentials/credential_factory.h"
#include "credentials/credential_manager.h"
#include "credentials/cred_encoding.h"
+#include "utils/leak_detective.h"
+#include "plugins/plugin_loader.h"
typedef struct library_t library_t;
@@ -87,6 +91,23 @@ typedef struct library_t library_t;
struct library_t {
/**
+ * Get an arbitrary object registered by name.
+ *
+ * @param name name of the object to get
+ * @return object, NULL if none found
+ */
+ void* (*get)(library_t *this, char *name);
+
+ /**
+ * (Un-)Register an arbitrary object using the given name.
+ *
+ * @param name name to register object under
+ * @param object object to register, NULL to unregister
+ * @return TRUE if registered, FALSE if name already taken
+ */
+ bool (*set)(library_t *this, char *name, void *object);
+
+ /**
* Printf hook registering facility
*/
printf_hook_t *printf_hook;
@@ -147,15 +168,15 @@ struct library_t {
integrity_checker_t *integrity;
/**
- * is leak detective running?
+ * Leak detective, if built and enabled
*/
- bool leak_detective;
+ leak_detective_t *leak_detective;
};
/**
* Initialize library, creates "lib" instance.
*
- * @param settings file to read settings from, may be NULL for none
+ * @param settings file to read settings from, may be NULL for default
* @return FALSE if integrity check failed
*/
bool library_init(char *settings);
@@ -166,7 +187,7 @@ bool library_init(char *settings);
void library_deinit();
/**
- * Library instance, set after between library_init() and library_deinit() calls.
+ * Library instance, set after library_init() and before library_deinit() calls.
*/
extern library_t *lib;
diff --git a/src/libstrongswan/pen/pen.c b/src/libstrongswan/pen/pen.c
new file mode 100644
index 000000000..3dd92218d
--- /dev/null
+++ b/src/libstrongswan/pen/pen.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 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 "pen.h"
+
+ENUM_BEGIN(pen_names, PEN_IETF, PEN_IETF,
+ "IETF");
+ENUM_NEXT(pen_names, PEN_MICROSOFT, PEN_MICROSOFT, PEN_IETF,
+ "Microsoft");
+ENUM_NEXT(pen_names, PEN_OSC, PEN_OSC, PEN_MICROSOFT,
+ "OSC");
+ENUM_NEXT(pen_names, PEN_TCG, PEN_TCG, PEN_OSC,
+ "TCG");
+ENUM_NEXT(pen_names, PEN_FHH, PEN_FHH, PEN_TCG,
+ "FHH");
+ENUM_NEXT(pen_names, PEN_ITA, PEN_ITA, PEN_FHH,
+ "ITA-HSR");
+ENUM_NEXT(pen_names, PEN_RESERVED, PEN_RESERVED, PEN_ITA,
+ "Reserved");
+ENUM_END(pen_names, PEN_RESERVED);
+
diff --git a/src/libstrongswan/pen/pen.h b/src/libstrongswan/pen/pen.h
new file mode 100644
index 000000000..396cc7199
--- /dev/null
+++ b/src/libstrongswan/pen/pen.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011 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 pen pen
+ * @ingroup libstrongswan
+ *
+ * @defgroup pent pen
+ * @{ @ingroup pen
+ */
+
+#ifndef PEN_H_
+#define PEN_H_
+
+#include <library.h>
+
+typedef enum pen_t pen_t;
+
+enum pen_t {
+ PEN_IETF = 0x000000, /* 0 */
+ PEN_MICROSOFT = 0x000137, /* 311 */
+ PEN_OSC = 0x002358, /* 9048 */
+ PEN_TCG = 0x005597, /* 21911 */
+ PEN_FHH = 0x0080ab, /* 32939 */
+ PEN_ITA = 0x00902a, /* 36906 */
+ PEN_RESERVED = 0xffffff, /* 16777215 */
+};
+
+/**
+ * enum names for pen_t.
+ */
+extern enum_name_t *pen_names;
+
+#endif /** PEN_H_ @}*/
diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in
index c93f84ca7..53eecbe8d 100644
--- a/src/libstrongswan/plugins/aes/Makefile.in
+++ b/src/libstrongswan/plugins/aes/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/aes/aes_plugin.c b/src/libstrongswan/plugins/aes/aes_plugin.c
index d17355d1d..1e84a7c86 100644
--- a/src/libstrongswan/plugins/aes/aes_plugin.c
+++ b/src/libstrongswan/plugins/aes/aes_plugin.c
@@ -37,11 +37,22 @@ METHOD(plugin_t, get_name, char*,
return "aes";
}
+METHOD(plugin_t, get_features, int,
+ private_aes_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(CRYPTER, aes_crypter_create),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_aes_plugin_t *this)
{
- lib->crypto->remove_crypter(lib->crypto,
- (crypter_constructor_t)aes_crypter_create);
free(this);
}
@@ -56,15 +67,12 @@ plugin_t *aes_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC, get_name(this),
- (crypter_constructor_t)aes_crypter_create);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/af_alg/Makefile.in b/src/libstrongswan/plugins/af_alg/Makefile.in
index 00b54b026..679e883e1 100644
--- a/src/libstrongswan/plugins/af_alg/Makefile.in
+++ b/src/libstrongswan/plugins/af_alg/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_crypter.c b/src/libstrongswan/plugins/af_alg/af_alg_crypter.c
index 7b3c062aa..9c547140d 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_crypter.c
+++ b/src/libstrongswan/plugins/af_alg/af_alg_crypter.c
@@ -61,7 +61,7 @@ static struct {
/* size of the keying material (key + nonce for ctr mode) */
size_t keymat_size;
size_t iv_size;
-} algs[] = {
+} algs[AF_ALG_CRYPTER] = {
{ENCR_DES, "cbc(des)", 8, 8, 8, 8, },
{ENCR_DES_ECB, "ecb(des)", 8, 8, 8, 0, },
{ENCR_3DES, "cbc(des3_ede)", 8, 24, 24, 8, },
@@ -92,25 +92,20 @@ static struct {
/**
* See header.
*/
-void af_alg_crypter_probe(char *plugin)
+void af_alg_crypter_probe(plugin_feature_t *features, int *pos)
{
- encryption_algorithm_t prev = -1;
af_alg_ops_t *ops;
int i;
for (i = 0; i < countof(algs); i++)
{
- if (prev != algs[i].id)
+ ops = af_alg_ops_create("skcipher", algs[i].name);
+ if (ops)
{
- ops = af_alg_ops_create("skcipher", algs[i].name);
- if (ops)
- {
- ops->destroy(ops);
- lib->crypto->add_crypter(lib->crypto, algs[i].id, plugin,
- (crypter_constructor_t)af_alg_crypter_create);
- }
+ ops->destroy(ops);
+ features[(*pos)++] = PLUGIN_PROVIDE(CRYPTER,
+ algs[i].id, algs[i].key_size);
}
- prev = algs[i].id;
}
}
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_crypter.h b/src/libstrongswan/plugins/af_alg/af_alg_crypter.h
index ed7799cc8..ad2d42a97 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_crypter.h
+++ b/src/libstrongswan/plugins/af_alg/af_alg_crypter.h
@@ -23,8 +23,12 @@
typedef struct af_alg_crypter_t af_alg_crypter_t;
+#include <plugins/plugin.h>
#include <crypto/crypters/crypter.h>
+/** Number of crypters */
+#define AF_ALG_CRYPTER 25
+
/**
* Implementation of signers using AF_ALG.
*/
@@ -47,10 +51,11 @@ af_alg_crypter_t *af_alg_crypter_create(encryption_algorithm_t algo,
size_t key_size);
/**
- * Probe algorithms and register af_alg_crypter_create().
+ * Probe algorithms and return plugin features.
*
- * @param plugin plugin name to register algorithms for
+ * @param features plugin features to create
+ * @param pos current position in features
*/
-void af_alg_crypter_probe(char *plugin);
+void af_alg_crypter_probe(plugin_feature_t *features, int *pos);
#endif /** AF_ALG_CRYPTER_H_ @}*/
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_hasher.c b/src/libstrongswan/plugins/af_alg/af_alg_hasher.c
index 11074c4bd..ef2350497 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_hasher.c
+++ b/src/libstrongswan/plugins/af_alg/af_alg_hasher.c
@@ -46,7 +46,7 @@ static struct {
hash_algorithm_t id;
char *name;
size_t size;
-} algs[] = {
+} algs[AF_ALG_HASHER] = {
{HASH_SHA1, "sha1", HASH_SIZE_SHA1 },
{HASH_MD5, "md5", HASH_SIZE_MD5 },
{HASH_SHA224, "sha224", HASH_SIZE_SHA224 },
@@ -59,7 +59,7 @@ static struct {
/**
* See header.
*/
-void af_alg_hasher_probe(char *plugin)
+void af_alg_hasher_probe(plugin_feature_t *features, int *pos)
{
af_alg_ops_t *ops;
int i;
@@ -70,8 +70,7 @@ void af_alg_hasher_probe(char *plugin)
if (ops)
{
ops->destroy(ops);
- lib->crypto->add_hasher(lib->crypto, algs[i].id, plugin,
- (hasher_constructor_t)af_alg_hasher_create);
+ features[(*pos)++] = PLUGIN_PROVIDE(HASHER, algs[i].id);
}
}
}
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_hasher.h b/src/libstrongswan/plugins/af_alg/af_alg_hasher.h
index f44ba2938..5b540875a 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_hasher.h
+++ b/src/libstrongswan/plugins/af_alg/af_alg_hasher.h
@@ -23,8 +23,12 @@
typedef struct af_alg_hasher_t af_alg_hasher_t;
+#include <plugins/plugin.h>
#include <crypto/hashers/hasher.h>
+/** Number of hashers */
+#define AF_ALG_HASHER 7
+
/**
* Implementation of hashers using AF_ALG.
*/
@@ -45,10 +49,11 @@ struct af_alg_hasher_t {
af_alg_hasher_t *af_alg_hasher_create(hash_algorithm_t algo);
/**
- * Probe algorithms and register af_alg_hasher_create().
+ * Probe algorithms and return plugin features.
*
- * @param plugin plugin name to register algorithms for
+ * @param features plugin features to create
+ * @param pos current position in deps
*/
-void af_alg_hasher_probe(char *plugin);
+void af_alg_hasher_probe(plugin_feature_t *features, int *pos);
#endif /** af_alg_HASHER_H_ @}*/
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_ops.c b/src/libstrongswan/plugins/af_alg/af_alg_ops.c
index 82a227d97..a7b5de264 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_ops.c
+++ b/src/libstrongswan/plugins/af_alg/af_alg_ops.c
@@ -122,7 +122,7 @@ METHOD(af_alg_ops_t, crypt, void,
cmsg->cmsg_level = SOL_ALG;
cmsg->cmsg_type = ALG_SET_OP;
cmsg->cmsg_len = CMSG_LEN(sizeof(type));
- *(u_int32_t*)CMSG_DATA(cmsg) = type;
+ memcpy(CMSG_DATA(cmsg), &type, sizeof(type));
cmsg = CMSG_NXTHDR(&msg, cmsg);
cmsg->cmsg_level = SOL_ALG;
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_plugin.c b/src/libstrongswan/plugins/af_alg/af_alg_plugin.c
index 280ea4e98..445667507 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_plugin.c
+++ b/src/libstrongswan/plugins/af_alg/af_alg_plugin.c
@@ -41,18 +41,31 @@ METHOD(plugin_t, get_name, char*,
return "af-alg";
}
+METHOD(plugin_t, get_features, int,
+ private_af_alg_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[AF_ALG_HASHER + AF_ALG_SIGNER +
+ AF_ALG_PRF + AF_ALG_CRYPTER + 4] = {};
+ static int count = 0;
+
+ if (!count)
+ { /* initialize only once */
+ f[count++] = PLUGIN_REGISTER(HASHER, af_alg_hasher_create);
+ af_alg_hasher_probe(f, &count);
+ f[count++] = PLUGIN_REGISTER(SIGNER, af_alg_signer_create);
+ af_alg_signer_probe(f, &count);
+ f[count++] = PLUGIN_REGISTER(PRF, af_alg_prf_create);
+ af_alg_prf_probe(f, &count);
+ f[count++] = PLUGIN_REGISTER(CRYPTER, af_alg_crypter_create);
+ af_alg_crypter_probe(f, &count);
+ }
+ *features = f;
+ return count;
+}
+
METHOD(plugin_t, destroy, void,
private_af_alg_plugin_t *this)
{
- lib->crypto->remove_hasher(lib->crypto,
- (hasher_constructor_t)af_alg_hasher_create);
- lib->crypto->remove_signer(lib->crypto,
- (signer_constructor_t)af_alg_signer_create);
- lib->crypto->remove_prf(lib->crypto,
- (prf_constructor_t)af_alg_prf_create);
- lib->crypto->remove_crypter(lib->crypto,
- (crypter_constructor_t)af_alg_crypter_create);
-
free(this);
}
@@ -67,16 +80,11 @@ plugin_t *af_alg_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- af_alg_hasher_probe(get_name(this));
- af_alg_signer_probe(get_name(this));
- af_alg_prf_probe(get_name(this));
- af_alg_crypter_probe(get_name(this));
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_prf.c b/src/libstrongswan/plugins/af_alg/af_alg_prf.c
index 1c1174abb..a7912291f 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_prf.c
+++ b/src/libstrongswan/plugins/af_alg/af_alg_prf.c
@@ -57,7 +57,7 @@ static struct {
char *name;
size_t block_size;
bool xcbc;
-} algs[] = {
+} algs[AF_ALG_PRF] = {
{PRF_HMAC_SHA1, "hmac(sha1)", 20, FALSE, },
{PRF_HMAC_SHA2_256, "hmac(sha256)", 32, FALSE, },
{PRF_HMAC_MD5, "hmac(md5)", 16, FALSE, },
@@ -70,7 +70,7 @@ static struct {
/**
* See header.
*/
-void af_alg_prf_probe(char *plugin)
+void af_alg_prf_probe(plugin_feature_t *features, int *pos)
{
af_alg_ops_t *ops;
int i;
@@ -81,8 +81,7 @@ void af_alg_prf_probe(char *plugin)
if (ops)
{
ops->destroy(ops);
- lib->crypto->add_prf(lib->crypto, algs[i].id, plugin,
- (prf_constructor_t)af_alg_prf_create);
+ features[(*pos)++] = PLUGIN_PROVIDE(PRF, algs[i].id);
}
}
}
@@ -90,7 +89,7 @@ void af_alg_prf_probe(char *plugin)
/**
* Get the kernel algorithm string and block size for our identifier
*/
-static size_t lookup_alg(integrity_algorithm_t algo, char **name, bool *xcbc)
+static size_t lookup_alg(pseudo_random_function_t algo, char **name, bool *xcbc)
{
int i;
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_prf.h b/src/libstrongswan/plugins/af_alg/af_alg_prf.h
index d3275e7be..2f6cf0cf1 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_prf.h
+++ b/src/libstrongswan/plugins/af_alg/af_alg_prf.h
@@ -23,8 +23,12 @@
typedef struct af_alg_prf_t af_alg_prf_t;
+#include <plugins/plugin.h>
#include <crypto/prfs/prf.h>
+/** Number of PRFs */
+#define AF_ALG_PRF 7
+
/**
* Implementation of PRFs using AF_ALG.
*/
@@ -45,10 +49,11 @@ struct af_alg_prf_t {
af_alg_prf_t *af_alg_prf_create(pseudo_random_function_t algo);
/**
- * Probe algorithms and register af_alg_prf_create().
+ * Probe algorithms and return plugin features.
*
- * @param plugin plugin name to register algorithms for
+ * @param features plugin features to create
+ * @param pos current position in features
*/
-void af_alg_prf_probe(char *plugin);
+void af_alg_prf_probe(plugin_feature_t *features, int *pos);
#endif /** AF_ALG_PRF_H_ @}*/
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_signer.c b/src/libstrongswan/plugins/af_alg/af_alg_signer.c
index 34534a06b..6cd79f8f2 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_signer.c
+++ b/src/libstrongswan/plugins/af_alg/af_alg_signer.c
@@ -52,7 +52,7 @@ static struct {
char *name;
size_t block_size;
size_t key_size;
-} algs[] = {
+} algs[AF_ALG_SIGNER] = {
{AUTH_HMAC_SHA1_96, "hmac(sha1)", 12, 20, },
{AUTH_HMAC_SHA1_128, "hmac(sha1)", 16, 20, },
{AUTH_HMAC_SHA1_160, "hmac(sha1)", 20, 20, },
@@ -71,7 +71,7 @@ static struct {
/**
* See header.
*/
-void af_alg_signer_probe(char *plugin)
+void af_alg_signer_probe(plugin_feature_t *features, int *pos)
{
af_alg_ops_t *ops;
int i;
@@ -82,8 +82,7 @@ void af_alg_signer_probe(char *plugin)
if (ops)
{
ops->destroy(ops);
- lib->crypto->add_signer(lib->crypto, algs[i].id, plugin,
- (signer_constructor_t)af_alg_signer_create);
+ features[(*pos)++] = PLUGIN_PROVIDE(SIGNER, algs[i].id);
}
}
}
diff --git a/src/libstrongswan/plugins/af_alg/af_alg_signer.h b/src/libstrongswan/plugins/af_alg/af_alg_signer.h
index 21487a118..deced7110 100644
--- a/src/libstrongswan/plugins/af_alg/af_alg_signer.h
+++ b/src/libstrongswan/plugins/af_alg/af_alg_signer.h
@@ -23,8 +23,12 @@
typedef struct af_alg_signer_t af_alg_signer_t;
+#include <plugins/plugin.h>
#include <crypto/signers/signer.h>
+/** Number of signers */
+#define AF_ALG_SIGNER 13
+
/**
* Implementation of signers using AF_ALG.
*/
@@ -45,10 +49,11 @@ struct af_alg_signer_t {
af_alg_signer_t *af_alg_signer_create(integrity_algorithm_t algo);
/**
- * Probe algorithms and register af_alg_signer_create().
+ * Probe algorithms and return plugin features.
*
- * @param plugin plugin name to register algorithms for
+ * @param features plugin features to create
+ * @param pos current position in features
*/
-void af_alg_signer_probe(char *plugin);
+void af_alg_signer_probe(plugin_feature_t *features, int *pos);
#endif /** AF_ALG_SIGNER_H_ @}*/
diff --git a/src/libstrongswan/plugins/agent/Makefile.in b/src/libstrongswan/plugins/agent/Makefile.in
index ce333660d..452233b85 100644
--- a/src/libstrongswan/plugins/agent/Makefile.in
+++ b/src/libstrongswan/plugins/agent/Makefile.in
@@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -201,6 +204,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -217,11 +221,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/agent/agent_plugin.c b/src/libstrongswan/plugins/agent/agent_plugin.c
index 79c13b7c1..980a140b9 100644
--- a/src/libstrongswan/plugins/agent/agent_plugin.c
+++ b/src/libstrongswan/plugins/agent/agent_plugin.c
@@ -37,11 +37,20 @@ METHOD(plugin_t, get_name, char*,
return "agent";
}
+METHOD(plugin_t, get_features, int,
+ private_agent_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(PRIVKEY, agent_private_key_open, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_agent_plugin_t *this)
{
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)agent_private_key_open);
free(this);
}
@@ -56,14 +65,12 @@ plugin_t *agent_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE,
- (builder_function_t)agent_private_key_open);
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/agent/agent_private_key.c b/src/libstrongswan/plugins/agent/agent_private_key.c
index 0864f4118..60b57ad2d 100644
--- a/src/libstrongswan/plugins/agent/agent_private_key.c
+++ b/src/libstrongswan/plugins/agent/agent_private_key.c
@@ -161,7 +161,7 @@ static int open_connection(char *path)
*/
static bool read_key(private_agent_private_key_t *this, public_key_t *pubkey)
{
- int len, count;
+ int len;
char buf[2048];
chunk_t blob, key, type, n;
@@ -184,7 +184,7 @@ static bool read_key(private_agent_private_key_t *this, public_key_t *pubkey)
DBG1(DBG_LIB, "received invalid ssh-agent identity response");
return FALSE;
}
- count = read_uint32(&blob);
+ read_uint32(&blob);
while (blob.len)
{
@@ -398,7 +398,7 @@ agent_private_key_t *agent_private_key_open(key_type_t type, va_list args)
}
if (!path)
{
- return FALSE;
+ return NULL;
}
INIT(this,
diff --git a/src/libstrongswan/plugins/blowfish/Makefile.in b/src/libstrongswan/plugins/blowfish/Makefile.in
index be8ba72ee..52f5fa98a 100644
--- a/src/libstrongswan/plugins/blowfish/Makefile.in
+++ b/src/libstrongswan/plugins/blowfish/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/ccm/Makefile.in b/src/libstrongswan/plugins/ccm/Makefile.in
index b2bc4a51f..2ffe6194b 100644
--- a/src/libstrongswan/plugins/ccm/Makefile.in
+++ b/src/libstrongswan/plugins/ccm/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/ccm/ccm_aead.c b/src/libstrongswan/plugins/ccm/ccm_aead.c
index 7fee2b3c4..0d2a56a49 100644
--- a/src/libstrongswan/plugins/ccm/ccm_aead.c
+++ b/src/libstrongswan/plugins/ccm/ccm_aead.c
@@ -67,7 +67,7 @@ typedef struct __attribute__((packed)) {
u_char salt[SALT_SIZE];
u_char iv[IV_SIZE];
} nonce;
- /* lenght of plain text, q */
+ /* length of plain text, q */
u_char q[Q_SIZE];
} b0_t;
diff --git a/src/libstrongswan/plugins/ccm/ccm_plugin.c b/src/libstrongswan/plugins/ccm/ccm_plugin.c
index 2865c2ae4..549f0a736 100644
--- a/src/libstrongswan/plugins/ccm/ccm_plugin.c
+++ b/src/libstrongswan/plugins/ccm/ccm_plugin.c
@@ -5,11 +5,11 @@
* 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>.
+ * 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
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
@@ -38,12 +38,55 @@ METHOD(plugin_t, get_name, char*,
return "ccm";
}
+METHOD(plugin_t, get_features, int,
+ private_ccm_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(AEAD, ccm_aead_create),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 16),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 24),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV8, 32),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 16),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 24),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV12, 32),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 16),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 24),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_CCM_ICV16, 32),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV8, 16),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV8, 24),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV8, 32),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV12, 16),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV12, 24),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV12, 32),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV16, 16),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV16, 24),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_CAMELLIA_CCM_ICV16, 32),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 32),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_ccm_plugin_t *this)
{
- lib->crypto->remove_aead(lib->crypto,
- (aead_constructor_t)ccm_aead_create);
-
free(this);
}
@@ -53,40 +96,16 @@ METHOD(plugin_t, destroy, void,
plugin_t *ccm_plugin_create()
{
private_ccm_plugin_t *this;
- crypter_t *crypter;
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, 0);
- if (crypter)
- {
- crypter->destroy(crypter);
- lib->crypto->add_aead(lib->crypto, ENCR_AES_CCM_ICV8, get_name(this),
- (aead_constructor_t)ccm_aead_create);
- lib->crypto->add_aead(lib->crypto, ENCR_AES_CCM_ICV12, get_name(this),
- (aead_constructor_t)ccm_aead_create);
- lib->crypto->add_aead(lib->crypto, ENCR_AES_CCM_ICV16, get_name(this),
- (aead_constructor_t)ccm_aead_create);
- }
- crypter = lib->crypto->create_crypter(lib->crypto, ENCR_CAMELLIA_CBC, 0);
- if (crypter)
- {
- crypter->destroy(crypter);
- lib->crypto->add_aead(lib->crypto, ENCR_CAMELLIA_CCM_ICV8, get_name(this),
- (aead_constructor_t)ccm_aead_create);
- lib->crypto->add_aead(lib->crypto, ENCR_CAMELLIA_CCM_ICV12, get_name(this),
- (aead_constructor_t)ccm_aead_create);
- lib->crypto->add_aead(lib->crypto, ENCR_CAMELLIA_CCM_ICV16, get_name(this),
- (aead_constructor_t)ccm_aead_create);
- }
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/cmac/Makefile.am b/src/libstrongswan/plugins/cmac/Makefile.am
new file mode 100644
index 000000000..ce0104f11
--- /dev/null
+++ b/src/libstrongswan/plugins/cmac/Makefile.am
@@ -0,0 +1,16 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-cmac.la
+else
+plugin_LTLIBRARIES = libstrongswan-cmac.la
+endif
+
+libstrongswan_cmac_la_SOURCES = \
+ cmac_plugin.h cmac_plugin.c cmac.h cmac.c \
+ cmac_prf.h cmac_prf.c cmac_signer.h cmac_signer.c
+
+libstrongswan_cmac_la_LDFLAGS = -module -avoid-version
diff --git a/src/libstrongswan/plugins/cmac/Makefile.in b/src/libstrongswan/plugins/cmac/Makefile.in
new file mode 100644
index 000000000..093e63f32
--- /dev/null
+++ b/src/libstrongswan/plugins/cmac/Makefile.in
@@ -0,0 +1,613 @@
+# 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/libstrongswan/plugins/cmac
+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_cmac_la_LIBADD =
+am_libstrongswan_cmac_la_OBJECTS = cmac_plugin.lo cmac.lo cmac_prf.lo \
+ cmac_signer.lo
+libstrongswan_cmac_la_OBJECTS = $(am_libstrongswan_cmac_la_OBJECTS)
+libstrongswan_cmac_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_cmac_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_cmac_la_rpath = -rpath $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_cmac_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_cmac_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_cmac_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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
+AM_CFLAGS = -rdynamic
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-cmac.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-cmac.la
+libstrongswan_cmac_la_SOURCES = \
+ cmac_plugin.h cmac_plugin.c cmac.h cmac.c \
+ cmac_prf.h cmac_prf.c cmac_signer.h cmac_signer.c
+
+libstrongswan_cmac_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/cmac/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/cmac/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-cmac.la: $(libstrongswan_cmac_la_OBJECTS) $(libstrongswan_cmac_la_DEPENDENCIES)
+ $(libstrongswan_cmac_la_LINK) $(am_libstrongswan_cmac_la_rpath) $(libstrongswan_cmac_la_OBJECTS) $(libstrongswan_cmac_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac_prf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmac_signer.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/libstrongswan/plugins/cmac/cmac.c b/src/libstrongswan/plugins/cmac/cmac.c
new file mode 100644
index 000000000..5ec7073c7
--- /dev/null
+++ b/src/libstrongswan/plugins/cmac/cmac.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2012 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 <string.h>
+
+#include "cmac.h"
+
+#include <debug.h>
+
+typedef struct private_cmac_t private_cmac_t;
+
+/**
+ * Private data of a cmac_t object.
+ *
+ * The variable names are the same as in the RFC.
+ */
+struct private_cmac_t {
+
+ /**
+ * Public interface.
+ */
+ cmac_t public;
+
+ /**
+ * Block size, in bytes
+ */
+ u_int8_t b;
+
+ /**
+ * Crypter with key K
+ */
+ crypter_t *k;
+
+ /**
+ * K1
+ */
+ u_int8_t *k1;
+
+ /**
+ * K2
+ */
+ u_int8_t *k2;
+
+ /**
+ * T
+ */
+ u_int8_t *t;
+
+ /**
+ * remaining, unprocessed bytes in append mode
+ */
+ u_int8_t *remaining;
+
+ /**
+ * number of bytes in remaining
+ */
+ int remaining_bytes;
+};
+
+/**
+ * process supplied data, but do not run final operation
+ */
+static void update(private_cmac_t *this, chunk_t data)
+{
+ chunk_t iv;
+
+ if (this->remaining_bytes + data.len <= this->b)
+ { /* no complete block (or last block), just copy into remaining */
+ memcpy(this->remaining + this->remaining_bytes, data.ptr, data.len);
+ this->remaining_bytes += data.len;
+ return;
+ }
+
+ iv = chunk_alloca(this->b);
+ memset(iv.ptr, 0, iv.len);
+
+ /* T := 0x00000000000000000000000000000000 (initially)
+ * for each block M_i (except the last)
+ * X := T XOR M_i;
+ * T := AES-128(K, X);
+ */
+
+ /* append data to remaining bytes, process block M_1 */
+ memcpy(this->remaining + this->remaining_bytes, data.ptr,
+ this->b - this->remaining_bytes);
+ data = chunk_skip(data, this->b - this->remaining_bytes);
+ memxor(this->t, this->remaining, this->b);
+ this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL);
+
+ /* process blocks M_2 ... M_n-1 */
+ while (data.len > this->b)
+ {
+ memcpy(this->remaining, data.ptr, this->b);
+ data = chunk_skip(data, this->b);
+ memxor(this->t, this->remaining, this->b);
+ this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL);
+ }
+
+ /* store remaining bytes of block M_n */
+ memcpy(this->remaining, data.ptr, data.len);
+ this->remaining_bytes = data.len;
+}
+
+/**
+ * process last block M_last
+ */
+static void final(private_cmac_t *this, u_int8_t *out)
+{
+ chunk_t iv;
+
+ iv = chunk_alloca(this->b);
+ memset(iv.ptr, 0, iv.len);
+
+ /* if last block is complete
+ * M_last := M_n XOR K1;
+ * else
+ * M_last := padding(M_n) XOR K2;
+ */
+ if (this->remaining_bytes == this->b)
+ {
+ memxor(this->remaining, this->k1, this->b);
+ }
+ else
+ {
+ /* padding(x) = x || 10^i where i is 128-8*r-1
+ * That is, padding(x) is the concatenation of x and a single '1',
+ * followed by the minimum number of '0's, so that the total length is
+ * equal to 128 bits.
+ */
+ if (this->remaining_bytes < this->b)
+ {
+ this->remaining[this->remaining_bytes] = 0x80;
+ while (++this->remaining_bytes < this->b)
+ {
+ this->remaining[this->remaining_bytes] = 0x00;
+ }
+ }
+ memxor(this->remaining, this->k2, this->b);
+ }
+ /* T := M_last XOR T;
+ * T := AES-128(K,T);
+ */
+ memxor(this->t, this->remaining, this->b);
+ this->k->encrypt(this->k, chunk_create(this->t, this->b), iv, NULL);
+
+ memcpy(out, this->t, this->b);
+
+ /* reset state */
+ memset(this->t, 0, this->b);
+ this->remaining_bytes = 0;
+}
+
+METHOD(cmac_t, get_mac, void,
+ private_cmac_t *this, chunk_t data, u_int8_t *out)
+{
+ /* update T, do not process last block */
+ update(this, data);
+
+ if (out)
+ { /* if not in append mode, process last block and output result */
+ final(this, out);
+ }
+}
+
+METHOD(cmac_t, get_block_size, size_t,
+ private_cmac_t *this)
+{
+ return this->b;
+}
+
+/**
+ * Left-shift the given chunk by one bit.
+ */
+static void bit_shift(chunk_t chunk)
+{
+ size_t i;
+
+ for (i = 0; i < chunk.len; i++)
+ {
+ chunk.ptr[i] <<= 1;
+ if (i < chunk.len - 1 && chunk.ptr[i + 1] & 0x80)
+ {
+ chunk.ptr[i] |= 0x01;
+ }
+ }
+}
+
+/**
+ * Apply the following key derivation (in-place):
+ * if MSB(C) == 0
+ * C := C << 1
+ * else
+ * C := (C << 1) XOR 0x00000000000000000000000000000087
+ */
+static void derive_key(chunk_t chunk)
+{
+ if (chunk.ptr[0] & 0x80)
+ {
+ chunk_t rb;
+
+ rb = chunk_alloca(chunk.len);
+ memset(rb.ptr, 0, rb.len);
+ rb.ptr[rb.len - 1] = 0x87;
+ bit_shift(chunk);
+ memxor(chunk.ptr, rb.ptr, chunk.len);
+ }
+ else
+ {
+ bit_shift(chunk);
+ }
+}
+
+METHOD(cmac_t, set_key, void,
+ private_cmac_t *this, chunk_t key)
+{
+ chunk_t resized, iv, l;
+
+ /* we support variable keys as defined in RFC 4615 */
+ if (key.len == this->b)
+ {
+ resized = key;
+ }
+ else
+ { /* use cmac recursively to resize longer or shorter keys */
+ resized = chunk_alloca(this->b);
+ memset(resized.ptr, 0, resized.len);
+ set_key(this, resized);
+ get_mac(this, key, resized.ptr);
+ }
+
+ /*
+ * Rb = 0x00000000000000000000000000000087
+ * L = 0x00000000000000000000000000000000 encrypted with K
+ * if MSB(L) == 0
+ * K1 = L << 1
+ * else
+ * K1 = (L << 1) XOR Rb
+ * if MSB(K1) == 0
+ * K2 = K1 << 1
+ * else
+ * K2 = (K1 << 1) XOR Rb
+ */
+ iv = chunk_alloca(this->b);
+ memset(iv.ptr, 0, iv.len);
+ l = chunk_alloca(this->b);
+ memset(l.ptr, 0, l.len);
+ this->k->set_key(this->k, resized);
+ this->k->encrypt(this->k, l, iv, NULL);
+ derive_key(l);
+ memcpy(this->k1, l.ptr, l.len);
+ derive_key(l);
+ memcpy(this->k2, l.ptr, l.len);
+ memwipe(l.ptr, l.len);
+}
+
+METHOD(cmac_t, destroy, void,
+ private_cmac_t *this)
+{
+ this->k->destroy(this->k);
+ memwipe(this->k1, this->b);
+ free(this->k1);
+ memwipe(this->k2, this->b);
+ free(this->k2);
+ free(this->t);
+ free(this->remaining);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+cmac_t *cmac_create(encryption_algorithm_t algo, size_t key_size)
+{
+ private_cmac_t *this;
+ crypter_t *crypter;
+ u_int8_t b;
+
+ crypter = lib->crypto->create_crypter(lib->crypto, algo, key_size);
+ if (!crypter)
+ {
+ return NULL;
+ }
+ b = crypter->get_block_size(crypter);
+ /* input and output of crypter must be equal for cmac */
+ if (b != key_size)
+ {
+ crypter->destroy(crypter);
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .get_mac = _get_mac,
+ .get_block_size = _get_block_size,
+ .set_key = _set_key,
+ .destroy = _destroy,
+ },
+ .b = b,
+ .k = crypter,
+ .k1 = malloc(b),
+ .k2 = malloc(b),
+ .t = malloc(b),
+ .remaining = malloc(b),
+ );
+ memset(this->t, 0, b);
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/cmac/cmac.h b/src/libstrongswan/plugins/cmac/cmac.h
new file mode 100644
index 000000000..061609127
--- /dev/null
+++ b/src/libstrongswan/plugins/cmac/cmac.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 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 cmac cmac
+ * @{ @ingroup cmac_p
+ */
+
+#ifndef CMAC_H_
+#define CMAC_H_
+
+#include <crypto/crypters/crypter.h>
+
+typedef struct cmac_t cmac_t;
+
+/**
+ * Cipher-based Message Authentication Code (CMAC).
+ *
+ * This class implements the message authentication algorithm
+ * described in RFC 4493.
+ */
+struct cmac_t {
+
+ /**
+ * Generate message authentication code.
+ *
+ * If buffer is NULL, no result is given back. A next call will
+ * append the data to already supplied data. If buffer is not NULL,
+ * the mac of all apended data is calculated, returned and the internal
+ * state is reset.
+ *
+ * @param data chunk of data to authenticate
+ * @param buffer pointer where the generated bytes will be written
+ */
+ void (*get_mac) (cmac_t *this, chunk_t data, u_int8_t *buffer);
+
+ /**
+ * Get the block size of this cmac_t object.
+ *
+ * @return block size in bytes
+ */
+ size_t (*get_block_size) (cmac_t *this);
+
+ /**
+ * Set the key for this cmac_t object.
+ *
+ * @param key key to set
+ */
+ void (*set_key) (cmac_t *this, chunk_t key);
+
+ /**
+ * Destroys a cmac_t object.
+ */
+ void (*destroy) (cmac_t *this);
+};
+
+/**
+ * Creates a new cmac_t object.
+ *
+ * @param algo underlying crypto algorithm
+ * @param key_size key size to use, if required for algorithm
+ * @return cmac_t object, NULL if not supported
+ */
+cmac_t *cmac_create(encryption_algorithm_t algo, size_t key_size);
+
+#endif /** CMAC_H_ @}*/
diff --git a/src/libstrongswan/plugins/cmac/cmac_plugin.c b/src/libstrongswan/plugins/cmac/cmac_plugin.c
new file mode 100644
index 000000000..5b42c5002
--- /dev/null
+++ b/src/libstrongswan/plugins/cmac/cmac_plugin.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2012 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 "cmac_plugin.h"
+
+#include <library.h>
+#include "cmac_prf.h"
+#include "cmac_signer.h"
+
+typedef struct private_cmac_plugin_t private_cmac_plugin_t;
+
+/**
+ * private data of cmac_plugin
+ */
+struct private_cmac_plugin_t {
+
+ /**
+ * public functions
+ */
+ cmac_plugin_t public;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_cmac_plugin_t *this)
+{
+ return "cmac";
+}
+
+METHOD(plugin_t, get_features, int,
+ private_cmac_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(PRF, cmac_prf_create),
+ PLUGIN_PROVIDE(PRF, PRF_AES128_CMAC),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_REGISTER(SIGNER, cmac_signer_create),
+ PLUGIN_PROVIDE(SIGNER, AUTH_AES_CMAC_96),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_cmac_plugin_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *cmac_plugin_create()
+{
+ private_cmac_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ );
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/cmac/cmac_plugin.h b/src/libstrongswan/plugins/cmac/cmac_plugin.h
new file mode 100644
index 000000000..a31e1077d
--- /dev/null
+++ b/src/libstrongswan/plugins/cmac/cmac_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 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 cmac_p cmac
+ * @ingroup plugins
+ *
+ * @defgroup cmac_plugin cmac_plugin
+ * @{ @ingroup cmac_p
+ */
+
+#ifndef CMAC_PLUGIN_H_
+#define CMAC_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct cmac_plugin_t cmac_plugin_t;
+
+/**
+ * Plugin implementing CMAC algorithm to provide crypter based PRF and signer.
+ */
+struct cmac_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** CMAC_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/cmac/cmac_prf.c b/src/libstrongswan/plugins/cmac/cmac_prf.c
new file mode 100644
index 000000000..17affe439
--- /dev/null
+++ b/src/libstrongswan/plugins/cmac/cmac_prf.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2012 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 "cmac_prf.h"
+
+#include "cmac.h"
+
+typedef struct private_cmac_prf_t private_cmac_prf_t;
+
+/**
+ * Private data of a cmac_prf_t object.
+ */
+struct private_cmac_prf_t {
+
+ /**
+ * Public cmac_prf_t interface.
+ */
+ cmac_prf_t public;
+
+ /**
+ * cmac to use for generation.
+ */
+ cmac_t *cmac;
+};
+
+METHOD(prf_t, get_bytes, void,
+ private_cmac_prf_t *this, chunk_t seed, u_int8_t *buffer)
+{
+ this->cmac->get_mac(this->cmac, seed, buffer);
+}
+
+METHOD(prf_t, allocate_bytes, void,
+ private_cmac_prf_t *this, chunk_t seed, chunk_t *chunk)
+{
+ if (chunk)
+ {
+ *chunk = chunk_alloc(this->cmac->get_block_size(this->cmac));
+ get_bytes(this, seed, chunk->ptr);
+ }
+ else
+ {
+ get_bytes(this, seed, NULL);
+ }
+}
+
+METHOD(prf_t, get_block_size, size_t,
+ private_cmac_prf_t *this)
+{
+ return this->cmac->get_block_size(this->cmac);
+}
+
+METHOD(prf_t, get_key_size, size_t,
+ private_cmac_prf_t *this)
+{
+ /* in cmac, block and key size are always equal */
+ return this->cmac->get_block_size(this->cmac);
+}
+
+METHOD(prf_t, set_key, void,
+ private_cmac_prf_t *this, chunk_t key)
+{
+ this->cmac->set_key(this->cmac, key);
+}
+
+METHOD(prf_t, destroy, void,
+ private_cmac_prf_t *this)
+{
+ this->cmac->destroy(this->cmac);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+cmac_prf_t *cmac_prf_create(pseudo_random_function_t algo)
+{
+ private_cmac_prf_t *this;
+ cmac_t *cmac;
+
+ switch (algo)
+ {
+ case PRF_AES128_CMAC:
+ cmac = cmac_create(ENCR_AES_CBC, 16);
+ break;
+ default:
+ return NULL;
+ }
+ if (!cmac)
+ {
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .prf = {
+ .get_bytes = _get_bytes,
+ .allocate_bytes = _allocate_bytes,
+ .get_block_size = _get_block_size,
+ .get_key_size = _get_key_size,
+ .set_key = _set_key,
+ .destroy = _destroy,
+ },
+ },
+ .cmac = cmac,
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/cmac/cmac_prf.h b/src/libstrongswan/plugins/cmac/cmac_prf.h
new file mode 100644
index 000000000..a53cc5947
--- /dev/null
+++ b/src/libstrongswan/plugins/cmac/cmac_prf.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 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 cmac_prf cmac_prf
+ * @{ @ingroup cmac_p
+ */
+
+#ifndef PRF_CMAC_H_
+#define PRF_CMAC_H_
+
+typedef struct cmac_prf_t cmac_prf_t;
+
+#include <crypto/prfs/prf.h>
+
+/**
+ * Implementation of prf_t on CBC block cipher using CMAC, RFC 4493 / RFC 4615.
+ *
+ * This simply wraps a cmac_t in a prf_t. More a question of
+ * interface matching.
+ */
+struct cmac_prf_t {
+
+ /**
+ * Implements prf_t interface.
+ */
+ prf_t prf;
+};
+
+/**
+ * Creates a new cmac_prf_t object.
+ *
+ * @param algo algorithm to implement
+ * @return cmac_prf_t object, NULL if hash not supported
+ */
+cmac_prf_t *cmac_prf_create(pseudo_random_function_t algo);
+
+#endif /** PRF_CMAC_H_ @}*/
diff --git a/src/libstrongswan/plugins/cmac/cmac_signer.c b/src/libstrongswan/plugins/cmac/cmac_signer.c
new file mode 100644
index 000000000..82e8885d6
--- /dev/null
+++ b/src/libstrongswan/plugins/cmac/cmac_signer.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2012 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 <string.h>
+
+#include "cmac_signer.h"
+#include "cmac.h"
+
+typedef struct private_cmac_signer_t private_cmac_signer_t;
+
+/**
+ * Private data structure with signing context.
+ */
+struct private_cmac_signer_t {
+
+ /**
+ * Public interface.
+ */
+ cmac_signer_t public;
+
+ /**
+ * Assigned cmac function.
+ */
+ cmac_t *cmac;
+
+ /**
+ * Block size (truncation of CMAC MAC)
+ */
+ size_t block_size;
+};
+
+METHOD(signer_t, get_signature, void,
+ private_cmac_signer_t *this, chunk_t data, u_int8_t *buffer)
+{
+ if (buffer == NULL)
+ { /* append mode */
+ this->cmac->get_mac(this->cmac, data, NULL);
+ }
+ else
+ {
+ u_int8_t mac[this->cmac->get_block_size(this->cmac)];
+
+ this->cmac->get_mac(this->cmac, data, mac);
+ memcpy(buffer, mac, this->block_size);
+ }
+}
+
+METHOD(signer_t, allocate_signature, void,
+ private_cmac_signer_t *this, chunk_t data, chunk_t *chunk)
+{
+ if (chunk == NULL)
+ { /* append mode */
+ this->cmac->get_mac(this->cmac, data, NULL);
+ }
+ else
+ {
+ u_int8_t mac[this->cmac->get_block_size(this->cmac)];
+
+ this->cmac->get_mac(this->cmac, data, mac);
+
+ chunk->ptr = malloc(this->block_size);
+ chunk->len = this->block_size;
+
+ memcpy(chunk->ptr, mac, this->block_size);
+ }
+}
+
+METHOD(signer_t, verify_signature, bool,
+ private_cmac_signer_t *this, chunk_t data, chunk_t signature)
+{
+ u_int8_t mac[this->cmac->get_block_size(this->cmac)];
+
+ if (signature.len != this->block_size)
+ {
+ return FALSE;
+ }
+
+ this->cmac->get_mac(this->cmac, data, mac);
+ return memeq(signature.ptr, mac, this->block_size);
+}
+
+METHOD(signer_t, get_key_size, size_t,
+ private_cmac_signer_t *this)
+{
+ return this->cmac->get_block_size(this->cmac);
+}
+
+METHOD(signer_t, get_block_size, size_t,
+ private_cmac_signer_t *this)
+{
+ return this->block_size;
+}
+
+METHOD(signer_t, set_key, void,
+ private_cmac_signer_t *this, chunk_t key)
+{
+ this->cmac->set_key(this->cmac, key);
+}
+
+METHOD(signer_t, destroy, void,
+ private_cmac_signer_t *this)
+{
+ this->cmac->destroy(this->cmac);
+ free(this);
+}
+
+/*
+ * Described in header
+ */
+cmac_signer_t *cmac_signer_create(integrity_algorithm_t algo)
+{
+ private_cmac_signer_t *this;
+ size_t truncation;
+ cmac_t *cmac;
+
+ switch (algo)
+ {
+ case AUTH_AES_CMAC_96:
+ cmac = cmac_create(ENCR_AES_CBC, 16);
+ truncation = 12;
+ break;
+ default:
+ return NULL;
+ }
+ if (cmac == NULL)
+ {
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .signer = {
+ .get_signature = _get_signature,
+ .allocate_signature = _allocate_signature,
+ .verify_signature = _verify_signature,
+ .get_key_size = _get_key_size,
+ .get_block_size = _get_block_size,
+ .set_key = _set_key,
+ .destroy = _destroy,
+ },
+ },
+ .cmac = cmac,
+ .block_size = min(truncation, cmac->get_block_size(cmac)),
+ );
+
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/cmac/cmac_signer.h b/src/libstrongswan/plugins/cmac/cmac_signer.h
new file mode 100644
index 000000000..2e3724471
--- /dev/null
+++ b/src/libstrongswan/plugins/cmac/cmac_signer.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 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 cmac_signer cmac_signer
+ * @{ @ingroup cmac_p
+ */
+
+#ifndef CMAC_SIGNER_H_
+#define CMAC_SIGNER_H_
+
+typedef struct cmac_signer_t cmac_signer_t;
+
+#include <crypto/signers/signer.h>
+
+/**
+ * Implementation of signer_t on CBC symmetric cipher using CMAC, RFC 4494.
+ */
+struct cmac_signer_t {
+
+ /**
+ * Implements signer_t interface.
+ */
+ signer_t signer;
+};
+
+/**
+ * Creates a new cmac_signer_t.
+ *
+ * @param algo algorithm to implement
+ * @return cmac_signer_t, NULL if not supported
+ */
+cmac_signer_t *cmac_signer_create(integrity_algorithm_t algo);
+
+#endif /** CMAC_SIGNER_H_ @}*/
diff --git a/src/libstrongswan/plugins/constraints/Makefile.in b/src/libstrongswan/plugins/constraints/Makefile.in
index 8be502a9c..06b66db60 100644
--- a/src/libstrongswan/plugins/constraints/Makefile.in
+++ b/src/libstrongswan/plugins/constraints/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/ctr/Makefile.in b/src/libstrongswan/plugins/ctr/Makefile.in
index 0db640829..853625a19 100644
--- a/src/libstrongswan/plugins/ctr/Makefile.in
+++ b/src/libstrongswan/plugins/ctr/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/ctr/ctr_plugin.c b/src/libstrongswan/plugins/ctr/ctr_plugin.c
index 6850cacf0..c01308a52 100644
--- a/src/libstrongswan/plugins/ctr/ctr_plugin.c
+++ b/src/libstrongswan/plugins/ctr/ctr_plugin.c
@@ -38,12 +38,31 @@ METHOD(plugin_t, get_name, char*,
return "ctr";
}
+METHOD(plugin_t, get_features, int,
+ private_ctr_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(CRYPTER, ctr_ipsec_crypter_create),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 16),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 24),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 32),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 16),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 24),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 32),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 32),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_ctr_plugin_t *this)
{
- lib->crypto->remove_crypter(lib->crypto,
- (crypter_constructor_t)ctr_ipsec_crypter_create);
-
free(this);
}
@@ -53,31 +72,16 @@ METHOD(plugin_t, destroy, void,
plugin_t *ctr_plugin_create()
{
private_ctr_plugin_t *this;
- crypter_t *crypter;
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, 16);
- if (crypter)
- {
- crypter->destroy(crypter);
- lib->crypto->add_crypter(lib->crypto, ENCR_AES_CTR, get_name(this),
- (crypter_constructor_t)ctr_ipsec_crypter_create);
- }
- crypter = lib->crypto->create_crypter(lib->crypto, ENCR_CAMELLIA_CBC, 16);
- if (crypter)
- {
- crypter->destroy(crypter);
- lib->crypto->add_crypter(lib->crypto, ENCR_CAMELLIA_CTR, get_name(this),
- (crypter_constructor_t)ctr_ipsec_crypter_create);
- }
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in
index cdfb2b801..5b83c60f8 100644
--- a/src/libstrongswan/plugins/curl/Makefile.in
+++ b/src/libstrongswan/plugins/curl/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/curl/curl_plugin.c b/src/libstrongswan/plugins/curl/curl_plugin.c
index d0e532055..8628c4bb5 100644
--- a/src/libstrongswan/plugins/curl/curl_plugin.c
+++ b/src/libstrongswan/plugins/curl/curl_plugin.c
@@ -40,11 +40,23 @@ METHOD(plugin_t, get_name, char*,
return "curl";
}
+METHOD(plugin_t, get_features, int,
+ private_curl_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(FETCHER, curl_fetcher_create),
+ PLUGIN_PROVIDE(FETCHER, "file://"),
+ PLUGIN_PROVIDE(FETCHER, "http://"),
+ PLUGIN_PROVIDE(FETCHER, "https://"),
+ PLUGIN_PROVIDE(FETCHER, "ftp://"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_curl_plugin_t *this)
{
- lib->fetcher->remove_fetcher(lib->fetcher,
- (fetcher_constructor_t)curl_fetcher_create);
curl_global_cleanup();
free(this);
}
@@ -61,28 +73,19 @@ plugin_t *curl_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
res = curl_global_init(CURL_GLOBAL_NOTHING);
- if (res == CURLE_OK)
- {
- lib->fetcher->add_fetcher(lib->fetcher,
- (fetcher_constructor_t)curl_fetcher_create, "file://");
- lib->fetcher->add_fetcher(lib->fetcher,
- (fetcher_constructor_t)curl_fetcher_create, "http://");
- lib->fetcher->add_fetcher(lib->fetcher,
- (fetcher_constructor_t)curl_fetcher_create, "https://");
- lib->fetcher->add_fetcher(lib->fetcher,
- (fetcher_constructor_t)curl_fetcher_create, "ftp://");
- }
- else
+ if (res != CURLE_OK)
{
- DBG1(DBG_LIB, "global libcurl initializing failed: %s, curl disabled",
+ DBG1(DBG_LIB, "global libcurl initializing failed: %s",
curl_easy_strerror(res));
+ destroy(this);
+ return NULL;
}
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in
index d24ac40f8..f4056951a 100644
--- a/src/libstrongswan/plugins/des/Makefile.in
+++ b/src/libstrongswan/plugins/des/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/des/des_crypter.c b/src/libstrongswan/plugins/des/des_crypter.c
index 695e7e4c4..bc399ef8a 100644
--- a/src/libstrongswan/plugins/des/des_crypter.c
+++ b/src/libstrongswan/plugins/des/des_crypter.c
@@ -80,7 +80,7 @@ struct private_des_crypter_t {
des_crypter_t public;
/**
- * Key size, depends on algoritm...
+ * Key size, depends on algorithm...
*/
size_t key_size;
@@ -127,7 +127,7 @@ YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
#endif
/* Unroll the inner loop, this sometimes helps, sometimes hinders.
- * Very mucy CPU dependant */
+ * Very much CPU dependent */
#ifndef DES_UNROLL
#define DES_UNROLL
#endif
@@ -316,7 +316,7 @@ YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
* bytes, probably an issue of accessing non-word aligned objects :-( */
#ifdef DES_PTR
-/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
+/* It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there
* is no reason to not xor all the sub items together. This potentially
* saves a register since things can be xored directly into L */
diff --git a/src/libstrongswan/plugins/des/des_plugin.c b/src/libstrongswan/plugins/des/des_plugin.c
index 78b73347d..be2587679 100644
--- a/src/libstrongswan/plugins/des/des_plugin.c
+++ b/src/libstrongswan/plugins/des/des_plugin.c
@@ -37,11 +37,22 @@ METHOD(plugin_t, get_name, char*,
return "des";
}
+METHOD(plugin_t, get_features, int,
+ private_des_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(CRYPTER, des_crypter_create),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_des_plugin_t *this)
{
- lib->crypto->remove_crypter(lib->crypto,
- (crypter_constructor_t)des_crypter_create);
free(this);
}
@@ -56,19 +67,12 @@ plugin_t *des_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->crypto->add_crypter(lib->crypto, ENCR_3DES, get_name(this),
- (crypter_constructor_t)des_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_DES, get_name(this),
- (crypter_constructor_t)des_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_DES_ECB, get_name(this),
- (crypter_constructor_t)des_crypter_create);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/dnskey/Makefile.in b/src/libstrongswan/plugins/dnskey/Makefile.in
index 62c52498c..dabddd6d0 100644
--- a/src/libstrongswan/plugins/dnskey/Makefile.in
+++ b/src/libstrongswan/plugins/dnskey/Makefile.in
@@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +205,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +222,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/dnskey/dnskey_plugin.c b/src/libstrongswan/plugins/dnskey/dnskey_plugin.c
index 4e08746f8..b6863e8e3 100644
--- a/src/libstrongswan/plugins/dnskey/dnskey_plugin.c
+++ b/src/libstrongswan/plugins/dnskey/dnskey_plugin.c
@@ -37,11 +37,22 @@ METHOD(plugin_t, get_name, char*,
return "dnskey";
}
+METHOD(plugin_t, get_features, int,
+ private_dnskey_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(PUBKEY, dnskey_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
+ PLUGIN_REGISTER(PUBKEY, dnskey_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_dnskey_plugin_t *this)
{
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)dnskey_public_key_load);
free(this);
}
@@ -56,15 +67,11 @@ plugin_t *dnskey_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, FALSE,
- (builder_function_t)dnskey_public_key_load);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, FALSE,
- (builder_function_t)dnskey_public_key_load);
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in
index e88a102b8..cbe9ef303 100644
--- a/src/libstrongswan/plugins/fips_prf/Makefile.in
+++ b/src/libstrongswan/plugins/fips_prf/Makefile.in
@@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +205,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +222,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf.c b/src/libstrongswan/plugins/fips_prf/fips_prf.c
index ee71f6efd..c0666367a 100644
--- a/src/libstrongswan/plugins/fips_prf/fips_prf.c
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf.c
@@ -127,14 +127,14 @@ METHOD(prf_t, get_bytes, void,
{
/* a. XVAL = (XKEY + XSEED j) mod 2^b */
add_mod(this->b, xkey, xseed, xval);
- DBG3(DBG_LIB, "XVAL %b", xval, this->b);
+ DBG3(DBG_LIB, "XVAL %b", xval, (u_int)this->b);
/* b. wi = G(t, XVAL ) */
this->g(this, chunk_create(xval, this->b), &w[i * this->b]);
- DBG3(DBG_LIB, "w[%d] %b", i, &w[i * this->b], this->b);
+ DBG3(DBG_LIB, "w[%d] %b", i, &w[i * this->b], (u_int)this->b);
/* c. XKEY = (1 + XKEY + wi) mod 2b */
add_mod(this->b, xkey, &w[i * this->b], sum);
add_mod(this->b, sum, one, xkey);
- DBG3(DBG_LIB, "XKEY %b", xkey, this->b);
+ DBG3(DBG_LIB, "XKEY %b", xkey, (u_int)this->b);
}
/* 3.3 done already, mod q not used */
diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c
index 7038da146..68b6bacb2 100644
--- a/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c
+++ b/src/libstrongswan/plugins/fips_prf/fips_prf_plugin.c
@@ -37,11 +37,21 @@ METHOD(plugin_t, get_name, char*,
return "fips-prf";
}
+METHOD(plugin_t, get_features, int,
+ private_fips_prf_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(PRF, fips_prf_create),
+ PLUGIN_PROVIDE(PRF, PRF_FIPS_SHA1_160),
+ PLUGIN_DEPENDS(PRF, PRF_KEYED_SHA1),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_fips_prf_plugin_t *this)
{
- lib->crypto->remove_prf(lib->crypto,
- (prf_constructor_t)fips_prf_create);
free(this);
}
@@ -51,25 +61,16 @@ METHOD(plugin_t, destroy, void,
plugin_t *fips_prf_plugin_create()
{
private_fips_prf_plugin_t *this;
- prf_t *prf;
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1);
- if (prf)
- {
- prf->destroy(prf);
- lib->crypto->add_prf(lib->crypto, PRF_FIPS_SHA1_160, get_name(this),
- (prf_constructor_t)fips_prf_create);
- }
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/gcm/Makefile.in b/src/libstrongswan/plugins/gcm/Makefile.in
index 202849eb6..8285b5aeb 100644
--- a/src/libstrongswan/plugins/gcm/Makefile.in
+++ b/src/libstrongswan/plugins/gcm/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/gcm/gcm_plugin.c b/src/libstrongswan/plugins/gcm/gcm_plugin.c
index 4b46f0ee4..abfa4f007 100644
--- a/src/libstrongswan/plugins/gcm/gcm_plugin.c
+++ b/src/libstrongswan/plugins/gcm/gcm_plugin.c
@@ -38,12 +38,37 @@ METHOD(plugin_t, get_name, char*,
return "gcm";
}
+METHOD(plugin_t, get_features, int,
+ private_gcm_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(AEAD, gcm_aead_create),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 16),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 24),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 32),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 16),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 24),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 32),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 16),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 24),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 24),
+ PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 32),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 32),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_gcm_plugin_t *this)
{
- lib->crypto->remove_aead(lib->crypto,
- (aead_constructor_t)gcm_aead_create);
-
free(this);
}
@@ -53,29 +78,16 @@ METHOD(plugin_t, destroy, void,
plugin_t *gcm_plugin_create()
{
private_gcm_plugin_t *this;
- crypter_t *crypter;
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, 0);
- if (crypter)
- {
- crypter->destroy(crypter);
- lib->crypto->add_aead(lib->crypto, ENCR_AES_GCM_ICV8, get_name(this),
- (aead_constructor_t)gcm_aead_create);
- lib->crypto->add_aead(lib->crypto, ENCR_AES_GCM_ICV12, get_name(this),
- (aead_constructor_t)gcm_aead_create);
- lib->crypto->add_aead(lib->crypto, ENCR_AES_GCM_ICV16, get_name(this),
- (aead_constructor_t)gcm_aead_create);
- }
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.in b/src/libstrongswan/plugins/gcrypt/Makefile.in
index bedb918b9..4dc72fed0 100644
--- a/src/libstrongswan/plugins/gcrypt/Makefile.in
+++ b/src/libstrongswan/plugins/gcrypt/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
index e26277b0b..a48d4a133 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_plugin.c
@@ -99,25 +99,81 @@ METHOD(plugin_t, get_name, char*,
return "gcrypt";
}
+METHOD(plugin_t, get_features, int,
+ private_gcrypt_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ /* crypters */
+ PLUGIN_REGISTER(CRYPTER, gcrypt_crypter_create),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 16),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CTR, 32),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
+ /* gcrypt only supports 128 bit blowfish */
+ PLUGIN_PROVIDE(CRYPTER, ENCR_BLOWFISH, 16),
+#ifdef HAVE_GCRY_CIPHER_CAMELLIA
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 16),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CTR, 32),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 32),
+#endif
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAST, 0),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 16),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_SERPENT_CBC, 32),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_TWOFISH_CBC, 16),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_TWOFISH_CBC, 32),
+ /* hashers */
+ PLUGIN_REGISTER(HASHER, gcrypt_hasher_create),
+ PLUGIN_PROVIDE(HASHER, HASH_MD4),
+ PLUGIN_PROVIDE(HASHER, HASH_MD5),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA1),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA224),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA256),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA384),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA512),
+ /* MODP DH groups */
+ PLUGIN_REGISTER(DH, gcrypt_dh_create),
+ PLUGIN_PROVIDE(DH, MODP_2048_BIT),
+ PLUGIN_PROVIDE(DH, MODP_2048_224),
+ PLUGIN_PROVIDE(DH, MODP_2048_256),
+ PLUGIN_PROVIDE(DH, MODP_1536_BIT),
+ PLUGIN_PROVIDE(DH, MODP_3072_BIT),
+ PLUGIN_PROVIDE(DH, MODP_4096_BIT),
+ PLUGIN_PROVIDE(DH, MODP_6144_BIT),
+ PLUGIN_PROVIDE(DH, MODP_8192_BIT),
+ PLUGIN_PROVIDE(DH, MODP_1024_BIT),
+ PLUGIN_PROVIDE(DH, MODP_1024_160),
+ PLUGIN_PROVIDE(DH, MODP_768_BIT),
+ PLUGIN_REGISTER(DH, gcrypt_dh_create_custom),
+ PLUGIN_PROVIDE(DH, MODP_CUSTOM),
+ /* RSA private/public key loading */
+ PLUGIN_REGISTER(PUBKEY, gcrypt_rsa_public_key_load, TRUE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
+ PLUGIN_REGISTER(PRIVKEY, gcrypt_rsa_private_key_load, TRUE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
+ PLUGIN_REGISTER(PRIVKEY_GEN, gcrypt_rsa_private_key_gen, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
+ /* random numbers */
+ PLUGIN_REGISTER(RNG, gcrypt_rng_create),
+ PLUGIN_PROVIDE(RNG, RNG_WEAK),
+ PLUGIN_PROVIDE(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(RNG, RNG_TRUE),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_gcrypt_plugin_t *this)
{
- lib->crypto->remove_hasher(lib->crypto,
- (hasher_constructor_t)gcrypt_hasher_create);
- lib->crypto->remove_crypter(lib->crypto,
- (crypter_constructor_t)gcrypt_crypter_create);
- lib->crypto->remove_rng(lib->crypto,
- (rng_constructor_t)gcrypt_rng_create);
- lib->crypto->remove_dh(lib->crypto,
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->remove_dh(lib->crypto,
- (dh_constructor_t)gcrypt_dh_create_custom);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)gcrypt_rsa_private_key_gen);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)gcrypt_rsa_private_key_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)gcrypt_rsa_public_key_load);
free(this);
}
@@ -149,96 +205,12 @@ plugin_t *gcrypt_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- /* hashers */
- lib->crypto->add_hasher(lib->crypto, HASH_SHA1, get_name(this),
- (hasher_constructor_t)gcrypt_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_MD4, get_name(this),
- (hasher_constructor_t)gcrypt_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_MD5, get_name(this),
- (hasher_constructor_t)gcrypt_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA224, get_name(this),
- (hasher_constructor_t)gcrypt_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA256, get_name(this),
- (hasher_constructor_t)gcrypt_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA384, get_name(this),
- (hasher_constructor_t)gcrypt_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA512, get_name(this),
- (hasher_constructor_t)gcrypt_hasher_create);
-
- /* crypters */
- lib->crypto->add_crypter(lib->crypto, ENCR_3DES, get_name(this),
- (crypter_constructor_t)gcrypt_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_CAST, get_name(this),
- (crypter_constructor_t)gcrypt_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_BLOWFISH, get_name(this),
- (crypter_constructor_t)gcrypt_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_DES, get_name(this),
- (crypter_constructor_t)gcrypt_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_DES_ECB, get_name(this),
- (crypter_constructor_t)gcrypt_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC, get_name(this),
- (crypter_constructor_t)gcrypt_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_AES_CTR, get_name(this),
- (crypter_constructor_t)gcrypt_crypter_create);
-#ifdef HAVE_GCRY_CIPHER_CAMELLIA
- lib->crypto->add_crypter(lib->crypto, ENCR_CAMELLIA_CBC, get_name(this),
- (crypter_constructor_t)gcrypt_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_CAMELLIA_CTR, get_name(this),
- (crypter_constructor_t)gcrypt_crypter_create);
-#endif /* HAVE_GCRY_CIPHER_CAMELLIA */
- lib->crypto->add_crypter(lib->crypto, ENCR_SERPENT_CBC, get_name(this),
- (crypter_constructor_t)gcrypt_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_TWOFISH_CBC, get_name(this),
- (crypter_constructor_t)gcrypt_crypter_create);
-
- /* random numbers */
- lib->crypto->add_rng(lib->crypto, RNG_WEAK, get_name(this),
- (rng_constructor_t)gcrypt_rng_create);
- lib->crypto->add_rng(lib->crypto, RNG_STRONG, get_name(this),
- (rng_constructor_t)gcrypt_rng_create);
- lib->crypto->add_rng(lib->crypto, RNG_TRUE, get_name(this),
- (rng_constructor_t)gcrypt_rng_create);
-
- /* diffie hellman groups, using modp */
- lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, get_name(this),
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->add_dh(lib->crypto, MODP_2048_224, get_name(this),
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->add_dh(lib->crypto, MODP_2048_256, get_name(this),
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->add_dh(lib->crypto, MODP_1536_BIT, get_name(this),
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->add_dh(lib->crypto, MODP_3072_BIT, get_name(this),
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->add_dh(lib->crypto, MODP_4096_BIT, get_name(this),
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->add_dh(lib->crypto, MODP_6144_BIT, get_name(this),
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->add_dh(lib->crypto, MODP_8192_BIT, get_name(this),
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->add_dh(lib->crypto, MODP_1024_BIT, get_name(this),
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->add_dh(lib->crypto, MODP_1024_160, get_name(this),
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->add_dh(lib->crypto, MODP_768_BIT, get_name(this),
- (dh_constructor_t)gcrypt_dh_create);
- lib->crypto->add_dh(lib->crypto, MODP_CUSTOM, get_name(this),
- (dh_constructor_t)gcrypt_dh_create_custom);
-
- /* RSA */
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE,
- (builder_function_t)gcrypt_rsa_private_key_gen);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, TRUE,
- (builder_function_t)gcrypt_rsa_private_key_load);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, TRUE,
- (builder_function_t)gcrypt_rsa_public_key_load);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
index 38ce2cd6c..eb38eea3b 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
@@ -68,7 +68,7 @@ chunk_t gcrypt_rsa_find_token(gcry_sexp_t sexp, char *name, gcry_sexp_t key)
if (key)
{
/* gcrypt might return more bytes than necessary. Truncate
- * to key lenght if key given, or prepend zeros if needed */
+ * to key length if key given, or prepend zeros if needed */
len = gcry_pk_get_nbits(key);
len = len / 8 + (len % 8 ? 1 : 0);
if (len > data.len)
@@ -504,7 +504,7 @@ gcrypt_rsa_private_key_t *gcrypt_rsa_private_key_load(key_type_t type,
va_list args)
{
private_gcrypt_rsa_private_key_t *this;
- chunk_t n, e, d, p, q, exp, u;
+ chunk_t n, e, d, p, q, u;
gcry_error_t err;
n = e = d = p = q = u = chunk_empty;
@@ -531,7 +531,7 @@ gcrypt_rsa_private_key_t *gcrypt_rsa_private_key_load(key_type_t type,
case BUILD_RSA_EXP1:
case BUILD_RSA_EXP2:
/* not required for gcrypt */
- exp = va_arg(args, chunk_t);
+ va_arg(args, chunk_t);
continue;
case BUILD_RSA_COEFF:
u = va_arg(args, chunk_t);
diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in
index 18592ab4a..34a23312b 100644
--- a/src/libstrongswan/plugins/gmp/Makefile.in
+++ b/src/libstrongswan/plugins/gmp/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/gmp/gmp_plugin.c b/src/libstrongswan/plugins/gmp/gmp_plugin.c
index 55ccd4a4f..d93aa14a1 100644
--- a/src/libstrongswan/plugins/gmp/gmp_plugin.c
+++ b/src/libstrongswan/plugins/gmp/gmp_plugin.c
@@ -39,19 +39,85 @@ METHOD(plugin_t, get_name, char*,
return "gmp";
}
+METHOD(plugin_t, get_features, int,
+ private_gmp_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ /* DH groups */
+ PLUGIN_REGISTER(DH, gmp_diffie_hellman_create),
+ PLUGIN_PROVIDE(DH, MODP_2048_BIT),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(DH, MODP_2048_224),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(DH, MODP_2048_256),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(DH, MODP_1536_BIT),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(DH, MODP_3072_BIT),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(DH, MODP_4096_BIT),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(DH, MODP_6144_BIT),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(DH, MODP_8192_BIT),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(DH, MODP_1024_BIT),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(DH, MODP_1024_160),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(DH, MODP_768_BIT),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ PLUGIN_REGISTER(DH, gmp_diffie_hellman_create_custom),
+ PLUGIN_PROVIDE(DH, MODP_CUSTOM),
+ PLUGIN_DEPENDS(RNG, RNG_STRONG),
+ /* private/public keys */
+ PLUGIN_REGISTER(PRIVKEY, gmp_rsa_private_key_load, TRUE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
+ PLUGIN_REGISTER(PRIVKEY_GEN, gmp_rsa_private_key_gen, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
+ PLUGIN_DEPENDS(RNG, RNG_TRUE),
+ PLUGIN_REGISTER(PUBKEY, gmp_rsa_public_key_load, TRUE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
+ /* signature schemes, private */
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA224),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA224),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA256),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA256),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA384),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA384),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA512),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA512),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ /* signature verification schemes */
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA224),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA224),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA256),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA256),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA384),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA384),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA512),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA512),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ /* en-/decryption schemes */
+ PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_PKCS1),
+ PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_PKCS1),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_gmp_plugin_t *this)
{
- lib->crypto->remove_dh(lib->crypto,
- (dh_constructor_t)gmp_diffie_hellman_create);
- lib->crypto->remove_dh(lib->crypto,
- (dh_constructor_t)gmp_diffie_hellman_create_custom);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)gmp_rsa_private_key_gen);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)gmp_rsa_private_key_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)gmp_rsa_public_key_load);
free(this);
}
@@ -66,45 +132,12 @@ plugin_t *gmp_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_2048_224, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_2048_256, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_1536_BIT, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_3072_BIT, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_4096_BIT, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_6144_BIT, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_8192_BIT, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_1024_BIT, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_1024_160, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_768_BIT, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create);
-
- lib->crypto->add_dh(lib->crypto, MODP_CUSTOM, get_name(this),
- (dh_constructor_t)gmp_diffie_hellman_create_custom);
-
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE,
- (builder_function_t)gmp_rsa_private_key_gen);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, TRUE,
- (builder_function_t)gmp_rsa_private_key_load);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, TRUE,
- (builder_function_t)gmp_rsa_public_key_load);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
index a7ba80138..898892f5b 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
@@ -137,7 +137,7 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
if (signature.len == 0 || signature.len > this->k)
{
- return INVALID_ARG;
+ return FALSE;
}
/* unpack signature */
diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in
index b9e2cd817..5242764d4 100644
--- a/src/libstrongswan/plugins/hmac/Makefile.in
+++ b/src/libstrongswan/plugins/hmac/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/hmac/hmac.c b/src/libstrongswan/plugins/hmac/hmac.c
index 397a1ea11..91294305e 100644
--- a/src/libstrongswan/plugins/hmac/hmac.c
+++ b/src/libstrongswan/plugins/hmac/hmac.c
@@ -4,13 +4,13 @@
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General hmac License as published by the
+ * 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 hmac License
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
diff --git a/src/libstrongswan/plugins/hmac/hmac.h b/src/libstrongswan/plugins/hmac/hmac.h
index be1bce66d..1ed041596 100644
--- a/src/libstrongswan/plugins/hmac/hmac.h
+++ b/src/libstrongswan/plugins/hmac/hmac.h
@@ -29,8 +29,8 @@ typedef struct hmac_t hmac_t;
/**
* Message authentication using hash functions.
*
- * This class implements the message authenticaion algorithm
- * described in RFC2104. It uses a hash function, wich must
+ * This class implements the message authentication algorithm
+ * described in RFC2104. It uses a hash function, which must
* be implemented as a hasher_t class.
*/
struct hmac_t {
diff --git a/src/libstrongswan/plugins/hmac/hmac_plugin.c b/src/libstrongswan/plugins/hmac/hmac_plugin.c
index 47d6d3cde..7d9ff3c67 100644
--- a/src/libstrongswan/plugins/hmac/hmac_plugin.c
+++ b/src/libstrongswan/plugins/hmac/hmac_plugin.c
@@ -38,13 +38,50 @@ METHOD(plugin_t, get_name, char*,
return "hmac";
}
+METHOD(plugin_t, get_features, int,
+ private_hmac_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(PRF, hmac_prf_create),
+ PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA1),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_PROVIDE(PRF, PRF_HMAC_MD5),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_256),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA256),
+ PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_384),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA384),
+ PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_512),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA512),
+ PLUGIN_REGISTER(SIGNER, hmac_signer_create),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_96),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_128),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_160),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_96),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_128),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_128),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA256),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_256),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA256),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_192),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA384),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_384),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA384),
+ PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_256),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA512),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_hmac_plugin_t *this)
{
- lib->crypto->remove_prf(lib->crypto,
- (prf_constructor_t)hmac_prf_create);
- lib->crypto->remove_signer(lib->crypto,
- (signer_constructor_t)hmac_signer_create);
free(this);
}
@@ -54,75 +91,17 @@ METHOD(plugin_t, destroy, void,
plugin_t *hmac_plugin_create()
{
private_hmac_plugin_t *this;
- hasher_t *hasher;
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (hasher)
- {
- hasher->destroy(hasher);
- lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA1, get_name(this),
- (prf_constructor_t)hmac_prf_create);
- lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_96, get_name(this),
- (signer_constructor_t)hmac_signer_create);
- lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_128, get_name(this),
- (signer_constructor_t)hmac_signer_create);
- lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA1_160, get_name(this),
- (signer_constructor_t)hmac_signer_create);
- }
- hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA256);
- if (hasher)
- {
- hasher->destroy(hasher);
- lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_256, get_name(this),
- (prf_constructor_t)hmac_prf_create);
- lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_256_128, get_name(this),
- (signer_constructor_t)hmac_signer_create);
- lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_256_256, get_name(this),
- (signer_constructor_t)hmac_signer_create);
-
- }
- hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
- if (hasher)
- {
- hasher->destroy(hasher);
- lib->crypto->add_prf(lib->crypto, PRF_HMAC_MD5, get_name(this),
- (prf_constructor_t)hmac_prf_create);
- lib->crypto->add_signer(lib->crypto, AUTH_HMAC_MD5_96, get_name(this),
- (signer_constructor_t)hmac_signer_create);
- lib->crypto->add_signer(lib->crypto, AUTH_HMAC_MD5_128, get_name(this),
- (signer_constructor_t)hmac_signer_create);
- }
- hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA384);
- if (hasher)
- {
- hasher->destroy(hasher);
- lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_384, get_name(this),
- (prf_constructor_t)hmac_prf_create);
- lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_384_192, get_name(this),
- (signer_constructor_t)hmac_signer_create);
- lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_384_384, get_name(this),
- (signer_constructor_t)hmac_signer_create);
- }
- hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512);
- if (hasher)
- {
- hasher->destroy(hasher);
- lib->crypto->add_prf(lib->crypto, PRF_HMAC_SHA2_512, get_name(this),
- (prf_constructor_t)hmac_prf_create);
- lib->crypto->add_signer(lib->crypto, AUTH_HMAC_SHA2_512_256, get_name(this),
- (signer_constructor_t)hmac_signer_create);
- }
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in
index b496ace28..851df5667 100644
--- a/src/libstrongswan/plugins/ldap/Makefile.in
+++ b/src/libstrongswan/plugins/ldap/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/ldap/ldap_plugin.c b/src/libstrongswan/plugins/ldap/ldap_plugin.c
index 08d9748ce..210d33a93 100644
--- a/src/libstrongswan/plugins/ldap/ldap_plugin.c
+++ b/src/libstrongswan/plugins/ldap/ldap_plugin.c
@@ -37,11 +37,21 @@ METHOD(plugin_t, get_name, char*,
return "ldap";
}
+METHOD(plugin_t, get_features, int,
+ private_ldap_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(FETCHER, ldap_fetcher_create),
+ PLUGIN_PROVIDE(FETCHER, "ldap://"),
+ PLUGIN_PROVIDE(FETCHER, "ldaps://"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_ldap_plugin_t *this)
{
- lib->fetcher->remove_fetcher(lib->fetcher,
- (fetcher_constructor_t)ldap_fetcher_create);
free(this);
}
@@ -56,17 +66,12 @@ plugin_t *ldap_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->fetcher->add_fetcher(lib->fetcher,
- (fetcher_constructor_t)ldap_fetcher_create, "ldap://");
- lib->fetcher->add_fetcher(lib->fetcher,
- (fetcher_constructor_t)ldap_fetcher_create, "ldaps://");
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/md4/Makefile.in b/src/libstrongswan/plugins/md4/Makefile.in
index 82781054b..f5b06a0df 100644
--- a/src/libstrongswan/plugins/md4/Makefile.in
+++ b/src/libstrongswan/plugins/md4/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/md4/md4_hasher.c b/src/libstrongswan/plugins/md4/md4_hasher.c
index 366d37328..6a31017c2 100644
--- a/src/libstrongswan/plugins/md4/md4_hasher.c
+++ b/src/libstrongswan/plugins/md4/md4_hasher.c
@@ -268,10 +268,8 @@ static void MD4Final (private_md4_hasher_t *this, u_int8_t digest[16])
-/**
- * Implementation of hasher_t.get_hash.
- */
-static void get_hash(private_md4_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
+METHOD(hasher_t, get_hash, void,
+ private_md4_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
MD4Update(this, chunk.ptr, chunk.len);
if (buffer != NULL)
@@ -281,11 +279,8 @@ static void get_hash(private_md4_hasher_t *this, chunk_t chunk, u_int8_t *buffer
}
}
-
-/**
- * Implementation of hasher_t.allocate_hash.
- */
-static void allocate_hash(private_md4_hasher_t *this, chunk_t chunk, chunk_t *hash)
+METHOD(hasher_t, allocate_hash, void,
+ private_md4_hasher_t *this, chunk_t chunk, chunk_t *hash)
{
chunk_t allocated_hash;
@@ -302,18 +297,14 @@ static void allocate_hash(private_md4_hasher_t *this, chunk_t chunk, chunk_t *ha
}
}
-/**
- * Implementation of hasher_t.get_hash_size.
- */
-static size_t get_hash_size(private_md4_hasher_t *this)
+METHOD(hasher_t, get_hash_size, size_t,
+ private_md4_hasher_t *this)
{
return HASH_SIZE_MD4;
}
-/**
- * Implementation of hasher_t.reset.
- */
-static void reset(private_md4_hasher_t *this)
+METHOD(hasher_t, reset, void,
+ private_md4_hasher_t *this)
{
this->state[0] = 0x67452301;
this->state[1] = 0xefcdab89;
@@ -323,10 +314,8 @@ static void reset(private_md4_hasher_t *this)
this->count[1] = 0;
}
-/**
- * Implementation of hasher_t.destroy.
- */
-static void destroy(private_md4_hasher_t *this)
+METHOD(hasher_t, destroy, void,
+ private_md4_hasher_t *this)
{
free(this);
}
@@ -342,13 +331,18 @@ md4_hasher_t *md4_hasher_create(hash_algorithm_t algo)
{
return NULL;
}
- this = malloc_thing(private_md4_hasher_t);
- this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
- this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
- this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
- this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
- this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
+ INIT(this,
+ .public = {
+ .hasher_interface = {
+ .get_hash = _get_hash,
+ .allocate_hash = _allocate_hash,
+ .get_hash_size = _get_hash_size,
+ .reset = _reset,
+ .destroy = _destroy,
+ },
+ },
+ );
/* initialize */
reset(this);
diff --git a/src/libstrongswan/plugins/md4/md4_plugin.c b/src/libstrongswan/plugins/md4/md4_plugin.c
index 371bba280..baa44b7f5 100644
--- a/src/libstrongswan/plugins/md4/md4_plugin.c
+++ b/src/libstrongswan/plugins/md4/md4_plugin.c
@@ -37,11 +37,20 @@ METHOD(plugin_t, get_name, char*,
return "md4";
}
+METHOD(plugin_t, get_features, int,
+ private_md4_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(HASHER, md4_hasher_create),
+ PLUGIN_PROVIDE(HASHER, HASH_MD4),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_md4_plugin_t *this)
{
- lib->crypto->remove_hasher(lib->crypto,
- (hasher_constructor_t)md4_hasher_create);
free(this);
}
@@ -56,15 +65,12 @@ plugin_t *md4_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->crypto->add_hasher(lib->crypto, HASH_MD4, get_name(this),
- (hasher_constructor_t)md4_hasher_create);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in
index 0e3c37e7e..f7762c37e 100644
--- a/src/libstrongswan/plugins/md5/Makefile.in
+++ b/src/libstrongswan/plugins/md5/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/md5/md5_hasher.c b/src/libstrongswan/plugins/md5/md5_hasher.c
index a97ad5cae..45c2391ef 100644
--- a/src/libstrongswan/plugins/md5/md5_hasher.c
+++ b/src/libstrongswan/plugins/md5/md5_hasher.c
@@ -299,12 +299,8 @@ static void MD5Final (private_md5_hasher_t *this, u_int8_t digest[16])
}
}
-
-
-/**
- * Implementation of hasher_t.get_hash.
- */
-static void get_hash(private_md5_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
+METHOD(hasher_t, get_hash, void,
+ private_md5_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
MD5Update(this, chunk.ptr, chunk.len);
if (buffer != NULL)
@@ -314,11 +310,8 @@ static void get_hash(private_md5_hasher_t *this, chunk_t chunk, u_int8_t *buffer
}
}
-
-/**
- * Implementation of hasher_t.allocate_hash.
- */
-static void allocate_hash(private_md5_hasher_t *this, chunk_t chunk, chunk_t *hash)
+METHOD(hasher_t, allocate_hash, void,
+ private_md5_hasher_t *this, chunk_t chunk, chunk_t *hash)
{
chunk_t allocated_hash;
@@ -335,18 +328,14 @@ static void allocate_hash(private_md5_hasher_t *this, chunk_t chunk, chunk_t *ha
}
}
-/**
- * Implementation of hasher_t.get_hash_size.
- */
-static size_t get_hash_size(private_md5_hasher_t *this)
+METHOD(hasher_t, get_hash_size, size_t,
+ private_md5_hasher_t *this)
{
return HASH_SIZE_MD5;
}
-/**
- * Implementation of hasher_t.reset.
- */
-static void reset(private_md5_hasher_t *this)
+METHOD(hasher_t, reset, void,
+ private_md5_hasher_t *this)
{
this->state[0] = 0x67452301;
this->state[1] = 0xefcdab89;
@@ -356,10 +345,8 @@ static void reset(private_md5_hasher_t *this)
this->count[1] = 0;
}
-/**
- * Implementation of hasher_t.destroy.
- */
-static void destroy(private_md5_hasher_t *this)
+METHOD(hasher_t, destroy, void,
+ private_md5_hasher_t *this)
{
free(this);
}
@@ -375,13 +362,18 @@ md5_hasher_t *md5_hasher_create(hash_algorithm_t algo)
{
return NULL;
}
- this = malloc_thing(private_md5_hasher_t);
- this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
- this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
- this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
- this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
- this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
+ INIT(this,
+ .public = {
+ .hasher_interface = {
+ .get_hash = _get_hash,
+ .allocate_hash = _allocate_hash,
+ .get_hash_size = _get_hash_size,
+ .reset = _reset,
+ .destroy = _destroy,
+ },
+ },
+ );
/* initialize */
reset(this);
diff --git a/src/libstrongswan/plugins/md5/md5_plugin.c b/src/libstrongswan/plugins/md5/md5_plugin.c
index c72284193..a3ad7b305 100644
--- a/src/libstrongswan/plugins/md5/md5_plugin.c
+++ b/src/libstrongswan/plugins/md5/md5_plugin.c
@@ -37,6 +37,17 @@ METHOD(plugin_t, get_name, char*,
return "md5";
}
+METHOD(plugin_t, get_features, int,
+ private_md5_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(HASHER, md5_hasher_create),
+ PLUGIN_PROVIDE(HASHER, HASH_MD5),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_md5_plugin_t *this)
{
@@ -56,15 +67,12 @@ plugin_t *md5_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->crypto->add_hasher(lib->crypto, HASH_MD5, get_name(this),
- (hasher_constructor_t)md5_hasher_create);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in
index 32067d5b4..5025a0eb8 100644
--- a/src/libstrongswan/plugins/mysql/Makefile.in
+++ b/src/libstrongswan/plugins/mysql/Makefile.in
@@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -201,6 +204,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -217,11 +221,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/mysql/mysql_database.c b/src/libstrongswan/plugins/mysql/mysql_database.c
index 5fbfa0f28..25ea42a4f 100644
--- a/src/libstrongswan/plugins/mysql/mysql_database.c
+++ b/src/libstrongswan/plugins/mysql/mysql_database.c
@@ -20,6 +20,7 @@
#include "mysql_database.h"
#include <debug.h>
+#include <chunk.h>
#include <threading/thread_value.h>
#include <threading/mutex.h>
#include <utils/linked_list.h>
diff --git a/src/libstrongswan/plugins/mysql/mysql_plugin.c b/src/libstrongswan/plugins/mysql/mysql_plugin.c
index 579df4d50..dd8b32761 100644
--- a/src/libstrongswan/plugins/mysql/mysql_plugin.c
+++ b/src/libstrongswan/plugins/mysql/mysql_plugin.c
@@ -38,11 +38,20 @@ METHOD(plugin_t, get_name, char*,
return "mysql";
}
+METHOD(plugin_t, get_features, int,
+ private_mysql_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(DATABASE, mysql_database_create),
+ PLUGIN_PROVIDE(DATABASE, DB_MYSQL),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_mysql_plugin_t *this)
{
- lib->db->remove_database(lib->db,
- (database_constructor_t)mysql_database_create);
mysql_database_deinit();
free(this);
}
@@ -64,15 +73,12 @@ plugin_t *mysql_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->db->add_database(lib->db,
- (database_constructor_t)mysql_database_create);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in
index d1c8fce81..8994ff1b4 100644
--- a/src/libstrongswan/plugins/openssl/Makefile.in
+++ b/src/libstrongswan/plugins/openssl/Makefile.in
@@ -198,6 +198,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -206,6 +209,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -222,11 +226,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -270,6 +276,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/openssl/openssl_crl.c b/src/libstrongswan/plugins/openssl/openssl_crl.c
index 58401faa5..9a9efb2b6 100644
--- a/src/libstrongswan/plugins/openssl/openssl_crl.c
+++ b/src/libstrongswan/plugins/openssl/openssl_crl.c
@@ -185,7 +185,7 @@ METHOD(crl_t, create_enumerator, enumerator_t*,
free(enumerator);
return enumerator_create_empty();
}
- enumerator->num = sk_X509_EXTENSION_num(enumerator->stack);
+ enumerator->num = sk_X509_REVOKED_num(enumerator->stack);
return &enumerator->public;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
index 78ed2811a..9e4067589 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c
@@ -219,7 +219,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
return;
}
- chunk_free(&this->shared_secret);
+ chunk_clear(&this->shared_secret);
if (!compute_shared_key(this, &this->shared_secret)) {
DBG1(DBG_LIB, "ECDH shared secret computation failed");
diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
index f4c4759bf..950504573 100644
--- a/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
@@ -1,6 +1,6 @@
/*
+ * Copyright (C) 2008-2012 Tobias Brunner
* Copyright (C) 2009 Martin Willi
- * Copyright (C) 2008 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -371,14 +371,17 @@ openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type,
va_list args)
{
private_openssl_ec_private_key_t *this;
- chunk_t blob = chunk_empty;
+ chunk_t par = chunk_empty, key = chunk_empty;
while (TRUE)
{
switch (va_arg(args, builder_part_t))
{
+ case BUILD_BLOB_ALGID_PARAMS:
+ par = va_arg(args, chunk_t);
+ continue;
case BUILD_BLOB_ASN1_DER:
- blob = va_arg(args, chunk_t);
+ key = va_arg(args, chunk_t);
continue;
case BUILD_END:
break;
@@ -389,18 +392,36 @@ openssl_ec_private_key_t *openssl_ec_private_key_load(key_type_t type,
}
this = create_empty();
- this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len);
- if (!this->ec)
+
+ if (par.ptr)
{
- destroy(this);
- return NULL;
+ this->ec = d2i_ECParameters(NULL, (const u_char**)&par.ptr, par.len);
+ if (!this->ec)
+ {
+ goto error;
+ }
+ if (!d2i_ECPrivateKey(&this->ec, (const u_char**)&key.ptr, key.len))
+ {
+ goto error;
+ }
+ }
+ else
+ {
+ this->ec = d2i_ECPrivateKey(NULL, (const u_char**)&key.ptr, key.len);
+ if (!this->ec)
+ {
+ goto error;
+ }
}
if (!EC_KEY_check_key(this->ec))
{
- destroy(this);
- return NULL;
+ goto error;
}
return &this->public;
+
+error:
+ destroy(this);
+ return NULL;
}
#endif /* OPENSSL_NO_EC */
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
index 96aa38bb6..c93ceacc9 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -199,40 +199,175 @@ METHOD(plugin_t, get_name, char*,
return "openssl";
}
+METHOD(plugin_t, get_features, int,
+ private_openssl_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ /* crypters */
+ PLUGIN_REGISTER(CRYPTER, openssl_crypter_create),
+#ifndef OPENSSL_NO_AES
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
+#endif
+#ifndef OPENSSL_NO_CAMELLIA
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 32),
+#endif
+#ifndef OPENSSL_NO_RC5
+ PLUGIN_PROVIDE(CRYPTER, ENCR_RC5, 0),
+#endif
+#ifndef OPENSSL_NO_CAST
+ PLUGIN_PROVIDE(CRYPTER, ENCR_CAST, 0),
+#endif
+#ifndef OPENSSL_NO_BLOWFISH
+ PLUGIN_PROVIDE(CRYPTER, ENCR_BLOWFISH, 0),
+#endif
+#ifndef OPENSSL_NO_IDEA
+ PLUGIN_PROVIDE(CRYPTER, ENCR_IDEA, 16),
+#endif
+#ifndef OPENSSL_NO_DES
+ PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8),
+ PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8),
+#endif
+ PLUGIN_PROVIDE(CRYPTER, ENCR_NULL, 0),
+ /* hashers */
+ PLUGIN_REGISTER(HASHER, openssl_hasher_create),
+#ifndef OPENSSL_NO_SHA1
+ PLUGIN_PROVIDE(HASHER, HASH_SHA1),
+#endif
+#ifndef OPENSSL_NO_MD2
+ PLUGIN_PROVIDE(HASHER, HASH_MD2),
+#endif
+#ifndef OPENSSL_NO_MD4
+ PLUGIN_PROVIDE(HASHER, HASH_MD4),
+#endif
+#ifndef OPENSSL_NO_MD5
+ PLUGIN_PROVIDE(HASHER, HASH_MD5),
+#endif
+#ifndef OPENSSL_NO_SHA256
+ PLUGIN_PROVIDE(HASHER, HASH_SHA224),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA256),
+#endif
+#ifndef OPENSSL_NO_SHA512
+ PLUGIN_PROVIDE(HASHER, HASH_SHA384),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA512),
+#endif
+#ifndef OPENSSL_NO_SHA1
+ /* keyed sha1 hasher (aka prf) */
+ PLUGIN_REGISTER(PRF, openssl_sha1_prf_create),
+ PLUGIN_PROVIDE(PRF, PRF_KEYED_SHA1),
+#endif
+#ifndef OPENSSL_NO_DH
+ /* MODP DH groups */
+ PLUGIN_REGISTER(DH, openssl_diffie_hellman_create),
+ PLUGIN_PROVIDE(DH, MODP_2048_BIT),
+ PLUGIN_PROVIDE(DH, MODP_2048_224),
+ PLUGIN_PROVIDE(DH, MODP_2048_256),
+ PLUGIN_PROVIDE(DH, MODP_1536_BIT),
+ PLUGIN_PROVIDE(DH, MODP_3072_BIT),
+ PLUGIN_PROVIDE(DH, MODP_4096_BIT),
+ PLUGIN_PROVIDE(DH, MODP_6144_BIT),
+ PLUGIN_PROVIDE(DH, MODP_8192_BIT),
+ PLUGIN_PROVIDE(DH, MODP_1024_BIT),
+ PLUGIN_PROVIDE(DH, MODP_1024_160),
+ PLUGIN_PROVIDE(DH, MODP_768_BIT),
+ PLUGIN_PROVIDE(DH, MODP_CUSTOM),
+#endif
+#ifndef OPENSSL_NO_RSA
+ /* RSA private/public key loading */
+ PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_load, TRUE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
+ PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_connect, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
+ PLUGIN_REGISTER(PRIVKEY_GEN, openssl_rsa_private_key_gen, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
+ PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
+ PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
+ /* signature/encryption schemes */
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
+#ifndef OPENSSL_NO_SHA1
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
+#endif
+#ifndef OPENSSL_NO_SHA256
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA224),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA256),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA224),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA256),
+#endif
+#ifndef OPENSSL_NO_SHA512
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA384),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA512),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA384),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA512),
+#endif
+#ifndef OPENSSL_NO_MD5
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
+#endif
+ PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_PKCS1),
+ PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_PKCS1),
+#endif /* OPENSSL_NO_RSA */
+ /* certificate/CRL loading */
+ PLUGIN_REGISTER(CERT_DECODE, openssl_x509_load, TRUE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_X509),
+ PLUGIN_REGISTER(CERT_DECODE, openssl_crl_load, TRUE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL),
+#ifndef OPENSSL_NO_ECDH
+ /* EC DH groups */
+ PLUGIN_REGISTER(DH, openssl_ec_diffie_hellman_create),
+ PLUGIN_PROVIDE(DH, ECP_256_BIT),
+ PLUGIN_PROVIDE(DH, ECP_384_BIT),
+ PLUGIN_PROVIDE(DH, ECP_521_BIT),
+ PLUGIN_PROVIDE(DH, ECP_224_BIT),
+ PLUGIN_PROVIDE(DH, ECP_192_BIT),
+#endif
+#ifndef OPENSSL_NO_ECDSA
+ /* EC private/public key loading */
+ PLUGIN_REGISTER(PRIVKEY, openssl_ec_private_key_load, TRUE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA),
+ PLUGIN_REGISTER(PRIVKEY_GEN, openssl_ec_private_key_gen, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ECDSA),
+ PLUGIN_REGISTER(PUBKEY, openssl_ec_public_key_load, TRUE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
+ /* signature encryption schemes */
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_NULL),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_NULL),
+#ifndef OPENSSL_NO_SHA1
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA1_DER),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA1_DER),
+#endif
+#ifndef OPENSSL_NO_SHA256
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA256_DER),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA256_DER),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_256),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_256),
+#endif
+#ifndef OPENSSL_NO_SHA512
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA384_DER),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA512_DER),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA384_DER),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA512_DER),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_384),
+ PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_521),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_384),
+ PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521),
+#endif
+#endif /* OPENSSL_NO_ECDSA */
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_openssl_plugin_t *this)
{
- lib->crypto->remove_crypter(lib->crypto,
- (crypter_constructor_t)openssl_crypter_create);
- lib->crypto->remove_hasher(lib->crypto,
- (hasher_constructor_t)openssl_hasher_create);
- lib->crypto->remove_prf(lib->crypto,
- (prf_constructor_t)openssl_sha1_prf_create);
- lib->crypto->remove_dh(lib->crypto,
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)openssl_rsa_private_key_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)openssl_rsa_private_key_gen);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)openssl_rsa_private_key_connect);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)openssl_rsa_public_key_load);
-#ifndef OPENSSL_NO_EC
- lib->crypto->remove_dh(lib->crypto,
- (dh_constructor_t)openssl_ec_diffie_hellman_create);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)openssl_ec_private_key_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)openssl_ec_private_key_gen);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)openssl_ec_public_key_load);
-#endif /* OPENSSL_NO_EC */
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)openssl_x509_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)openssl_crl_load);
-
#ifndef OPENSSL_NO_ENGINE
ENGINE_cleanup();
#endif /* OPENSSL_NO_ENGINE */
@@ -255,7 +390,7 @@ plugin_t *openssl_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
@@ -279,116 +414,6 @@ plugin_t *openssl_plugin_create()
return NULL;
}
- /* crypter */
- lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC, get_name(this),
- (crypter_constructor_t)openssl_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_CAMELLIA_CBC, get_name(this),
- (crypter_constructor_t)openssl_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_3DES, get_name(this),
- (crypter_constructor_t)openssl_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_RC5, get_name(this),
- (crypter_constructor_t)openssl_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_IDEA, get_name(this),
- (crypter_constructor_t)openssl_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_CAST, get_name(this),
- (crypter_constructor_t)openssl_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_BLOWFISH, get_name(this),
- (crypter_constructor_t)openssl_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_DES, get_name(this),
- (crypter_constructor_t)openssl_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_DES_ECB, get_name(this),
- (crypter_constructor_t)openssl_crypter_create);
- lib->crypto->add_crypter(lib->crypto, ENCR_NULL, get_name(this),
- (crypter_constructor_t)openssl_crypter_create);
-
- /* hasher */
- lib->crypto->add_hasher(lib->crypto, HASH_SHA1, get_name(this),
- (hasher_constructor_t)openssl_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_MD2, get_name(this),
- (hasher_constructor_t)openssl_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_MD4, get_name(this),
- (hasher_constructor_t)openssl_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_MD5, get_name(this),
- (hasher_constructor_t)openssl_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA224, get_name(this),
- (hasher_constructor_t)openssl_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA256, get_name(this),
- (hasher_constructor_t)openssl_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA384, get_name(this),
- (hasher_constructor_t)openssl_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA512, get_name(this),
- (hasher_constructor_t)openssl_hasher_create);
-
- /* prf */
- lib->crypto->add_prf(lib->crypto, PRF_KEYED_SHA1, get_name(this),
- (prf_constructor_t)openssl_sha1_prf_create);
-
- /* (ec) diffie hellman */
- lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_2048_224, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_2048_256, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_1536_BIT, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
-#ifndef OPENSSL_NO_EC
- lib->crypto->add_dh(lib->crypto, ECP_256_BIT, get_name(this),
- (dh_constructor_t)openssl_ec_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, ECP_384_BIT, get_name(this),
- (dh_constructor_t)openssl_ec_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, ECP_521_BIT, get_name(this),
- (dh_constructor_t)openssl_ec_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, ECP_224_BIT, get_name(this),
- (dh_constructor_t)openssl_ec_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, ECP_192_BIT, get_name(this),
- (dh_constructor_t)openssl_ec_diffie_hellman_create);
-#endif /* OPENSSL_NO_EC */
- lib->crypto->add_dh(lib->crypto, MODP_3072_BIT, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_4096_BIT, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_6144_BIT, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_8192_BIT, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_1024_BIT, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_1024_160, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_768_BIT, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
- lib->crypto->add_dh(lib->crypto, MODP_CUSTOM, get_name(this),
- (dh_constructor_t)openssl_diffie_hellman_create);
-
- /* rsa */
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, TRUE,
- (builder_function_t)openssl_rsa_private_key_load);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE,
- (builder_function_t)openssl_rsa_private_key_gen);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY, FALSE,
- (builder_function_t)openssl_rsa_private_key_connect);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, TRUE,
- (builder_function_t)openssl_rsa_public_key_load);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, FALSE,
- (builder_function_t)openssl_rsa_public_key_load);
-
-#ifndef OPENSSL_NO_EC
- /* ecdsa */
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, TRUE,
- (builder_function_t)openssl_ec_private_key_load);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, FALSE,
- (builder_function_t)openssl_ec_private_key_gen);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA, TRUE,
- (builder_function_t)openssl_ec_public_key_load);
-#endif /* OPENSSL_NO_EC */
-
- /* X509 certificates */
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509, TRUE,
- (builder_function_t)openssl_x509_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, TRUE,
- (builder_function_t)openssl_crl_load);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
index 422e31521..a24bae5d6 100644
--- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
+++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
@@ -44,6 +44,8 @@ struct private_openssl_rsa_public_key_t {
refcount_t ref;
};
+
+
/**
* Verification of an EMPSA PKCS1 signature described in PKCS#1
*/
@@ -386,4 +388,3 @@ openssl_rsa_public_key_t *openssl_rsa_public_key_load(key_type_t type,
destroy(this);
return NULL;
}
-
diff --git a/src/libstrongswan/plugins/openssl/openssl_util.c b/src/libstrongswan/plugins/openssl/openssl_util.c
index 99dca3631..1eb1c6723 100644
--- a/src/libstrongswan/plugins/openssl/openssl_util.c
+++ b/src/libstrongswan/plugins/openssl/openssl_util.c
@@ -130,7 +130,7 @@ chunk_t openssl_asn1_obj2chunk(ASN1_OBJECT *asn1)
{
if (asn1)
{
- return chunk_create(asn1->data, asn1->length);
+ return chunk_create((u_char*)asn1->data, asn1->length);
}
return chunk_empty;
}
diff --git a/src/libstrongswan/plugins/openssl/openssl_x509.c b/src/libstrongswan/plugins/openssl/openssl_x509.c
index f7495b2ae..5caf5182c 100644
--- a/src/libstrongswan/plugins/openssl/openssl_x509.c
+++ b/src/libstrongswan/plugins/openssl/openssl_x509.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2011 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -597,7 +600,7 @@ static bool parse_basicConstraints_ext(private_openssl_x509_t *this,
}
if (constraints->pathlen)
{
-
+
pathlen = ASN1_INTEGER_get(constraints->pathlen);
this->pathlen = (pathlen >= 0 && pathlen < 128) ?
pathlen : X509_NO_CONSTRAINT;
@@ -609,6 +612,41 @@ static bool parse_basicConstraints_ext(private_openssl_x509_t *this,
}
/**
+ * parse key usage
+ */
+static bool parse_keyUsage_ext(private_openssl_x509_t *this,
+ X509_EXTENSION *ext)
+{
+ ASN1_BIT_STRING *usage;
+
+ usage = X509V3_EXT_d2i(ext);
+ if (usage)
+ {
+ if (usage->length > 0)
+ {
+ int flags = usage->data[0];
+ if (usage->length > 1)
+ {
+ flags |= usage->data[1] << 8;
+ }
+ switch (flags)
+ {
+ case X509v3_KU_CRL_SIGN:
+ this->flags |= X509_CRL_SIGN;
+ break;
+ case X509v3_KU_KEY_CERT_SIGN:
+ /* we use the caBasicContraint, MUST be set */
+ default:
+ break;
+ }
+ }
+ ASN1_BIT_STRING_free(usage);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
* Parse CRL distribution points
*/
static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this,
@@ -713,7 +751,7 @@ static bool parse_authorityInfoAccess_ext(private_openssl_x509_t *this,
{
if (asprintf(&uri, "%Y", id) > 0)
{
- this->ocsp_uris->insert_first(this->ocsp_uris, uri);
+ this->ocsp_uris->insert_last(this->ocsp_uris, uri);
}
id->destroy(id);
}
@@ -804,6 +842,9 @@ static bool parse_extensions(private_openssl_x509_t *this)
case NID_basic_constraints:
ok = parse_basicConstraints_ext(this, ext);
break;
+ case NID_key_usage:
+ ok = parse_keyUsage_ext(this, ext);
+ break;
case NID_crl_distribution_points:
ok = parse_crlDistributionPoints_ext(this, ext);
break;
diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in
index 7bc342995..6ff607456 100644
--- a/src/libstrongswan/plugins/padlock/Makefile.in
+++ b/src/libstrongswan/plugins/padlock/Makefile.in
@@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +205,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +222,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/pem/Makefile.in b/src/libstrongswan/plugins/pem/Makefile.in
index 92c7fa2fe..98c196ef4 100644
--- a/src/libstrongswan/plugins/pem/Makefile.in
+++ b/src/libstrongswan/plugins/pem/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c
index b760adda9..c5d96be47 100644
--- a/src/libstrongswan/plugins/pem/pem_builder.c
+++ b/src/libstrongswan/plugins/pem/pem_builder.c
@@ -73,7 +73,7 @@ static bool find_boundary(char* tag, chunk_t *line)
{
if (present("-----", line))
{
- DBG2(DBG_LIB, " -----%s %.*s-----", tag, (int)name.len, name.ptr);
+ DBG2(DBG_ASN, " -----%s %.*s-----", tag, (int)name.len, name.ptr);
return TRUE;
}
line->ptr++; line->len--; name.len++;
@@ -99,7 +99,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg,
hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
if (hasher == NULL)
{
- DBG1(DBG_LIB, " MD5 hash algorithm not available");
+ DBG1(DBG_ASN, " MD5 hash algorithm not available");
return NOT_SUPPORTED;
}
hash.len = hasher->get_hash_size(hasher);
@@ -121,7 +121,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg,
crypter = lib->crypto->create_crypter(lib->crypto, alg, key_size);
if (crypter == NULL)
{
- DBG1(DBG_LIB, " %N encryption algorithm not available",
+ DBG1(DBG_ASN, " %N encryption algorithm not available",
encryption_algorithm_names, alg);
return NOT_SUPPORTED;
}
@@ -131,7 +131,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg,
blob->len % crypter->get_block_size(crypter))
{
crypter->destroy(crypter);
- DBG1(DBG_LIB, " data size is not multiple of block size");
+ DBG1(DBG_ASN, " data size is not multiple of block size");
return PARSE_ERROR;
}
crypter->decrypt(crypter, *blob, iv, &decrypted);
@@ -155,7 +155,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg,
{
if (*last_padding_pos != padding)
{
- DBG1(DBG_LIB, " invalid passphrase");
+ DBG1(DBG_ASN, " invalid passphrase");
return INVALID_ARG;
}
}
@@ -234,7 +234,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp)
}
/* we are looking for a parameter: value pair */
- DBG2(DBG_LIB, " %.*s", (int)line.len, line.ptr);
+ DBG2(DBG_ASN, " %.*s", (int)line.len, line.ptr);
ugh = extract_parameter_value(&name, &value, &line);
if (ugh != NULL)
{
@@ -274,7 +274,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp)
}
else
{
- DBG1(DBG_LIB, " encryption algorithm '%.*s'"
+ DBG1(DBG_ASN, " encryption algorithm '%.*s'"
" not supported", dek.len, dek.ptr);
return NOT_SUPPORTED;
}
@@ -298,7 +298,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp)
*pgp = TRUE;
data.ptr++;
data.len--;
- DBG2(DBG_LIB, " armor checksum: %.*s", (int)data.len,
+ DBG2(DBG_ASN, " armor checksum: %.*s", (int)data.len,
data.ptr);
continue;
}
@@ -355,7 +355,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp)
* load the credential from a blob
*/
static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
- x509_flag_t flags)
+ identification_t *subject, x509_flag_t flags)
{
void *cred = NULL;
bool pgp = FALSE;
@@ -381,10 +381,19 @@ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
{
subtype = pgp ? CERT_GPG : CERT_X509;
}
- cred = lib->creds->create(lib->creds, type, subtype,
+ if (type == CRED_CERTIFICATE && subtype == CERT_TRUSTED_PUBKEY && subject)
+ {
+ cred = lib->creds->create(lib->creds, type, subtype,
+ BUILD_BLOB_ASN1_DER, blob, BUILD_SUBJECT, subject,
+ BUILD_END);
+ }
+ else
+ {
+ cred = lib->creds->create(lib->creds, type, subtype,
pgp ? BUILD_BLOB_PGP : BUILD_BLOB_ASN1_DER, blob,
flags ? BUILD_X509_FLAG : BUILD_END,
flags, BUILD_END);
+ }
chunk_clear(&blob);
return cred;
}
@@ -393,7 +402,7 @@ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype,
* load the credential from a file
*/
static void *load_from_file(char *file, credential_type_t type, int subtype,
- x509_flag_t flags)
+ identification_t *subject, x509_flag_t flags)
{
void *cred = NULL;
struct stat sb;
@@ -423,7 +432,8 @@ static void *load_from_file(char *file, credential_type_t type, int subtype,
return NULL;
}
- cred = load_from_blob(chunk_create(addr, sb.st_size), type, subtype, flags);
+ cred = load_from_blob(chunk_create(addr, sb.st_size), type, subtype,
+ subject, flags);
munmap(addr, sb.st_size);
close(fd);
@@ -434,7 +444,7 @@ static void *load_from_file(char *file, credential_type_t type, int subtype,
* load the credential from a file descriptor
*/
static void *load_from_fd(int fd, credential_type_t type, int subtype,
- x509_flag_t flags)
+ identification_t *subject, x509_flag_t flags)
{
char buf[8096];
char *pos = buf;
@@ -460,7 +470,8 @@ static void *load_from_fd(int fd, credential_type_t type, int subtype,
return NULL;
}
}
- return load_from_blob(chunk_create(buf, total), type, subtype, flags);
+ return load_from_blob(chunk_create(buf, total), type, subtype,
+ subject, flags);
}
/**
@@ -471,6 +482,7 @@ static void *pem_load(credential_type_t type, int subtype, va_list args)
char *file = NULL;
int fd = -1;
chunk_t pem = chunk_empty;
+ identification_t *subject = NULL;
int flags = 0;
while (TRUE)
@@ -486,6 +498,9 @@ static void *pem_load(credential_type_t type, int subtype, va_list args)
case BUILD_BLOB_PEM:
pem = va_arg(args, chunk_t);
continue;
+ case BUILD_SUBJECT:
+ subject = va_arg(args, identification_t*);
+ continue;
case BUILD_X509_FLAG:
flags = va_arg(args, int);
continue;
@@ -499,15 +514,15 @@ static void *pem_load(credential_type_t type, int subtype, va_list args)
if (pem.len)
{
- return load_from_blob(pem, type, subtype, flags);
+ return load_from_blob(pem, type, subtype, subject, flags);
}
if (file)
{
- return load_from_file(file, type, subtype, flags);
+ return load_from_file(file, type, subtype, subject, flags);
}
if (fd != -1)
{
- return load_from_fd(fd, type, subtype, flags);
+ return load_from_fd(fd, type, subtype, subject, flags);
}
return NULL;
}
diff --git a/src/libstrongswan/plugins/pem/pem_plugin.c b/src/libstrongswan/plugins/pem/pem_plugin.c
index c81605ae5..fca717a10 100644
--- a/src/libstrongswan/plugins/pem/pem_plugin.c
+++ b/src/libstrongswan/plugins/pem/pem_plugin.c
@@ -39,15 +39,69 @@ METHOD(plugin_t, get_name, char*,
return "pem";
}
+METHOD(plugin_t, get_features, int,
+ private_pem_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ /* private key PEM decoding */
+ PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+ PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_DSA),
+ PLUGIN_DEPENDS(HASHER, HASH_MD5),
+
+ /* public key PEM decoding */
+ PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
+ PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
+ PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
+ PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_DSA),
+
+ /* certificate PEM decoding */
+ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_ANY),
+ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_X509),
+ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL),
+ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_OCSP_REQUEST),
+ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_OCSP_RESPONSE),
+ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_AC),
+ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_PKCS10_REQUEST),
+ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_TRUSTED_PUBKEY),
+ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_GPG),
+
+ /* pluto specific certificate formats */
+ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_PLUTO_CERT),
+ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_PLUTO_CRL),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_pem_plugin_t *this)
{
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)pem_private_key_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)pem_public_key_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)pem_certificate_load);
+ lib->encoding->remove_encoder(lib->encoding, pem_encoder_encode);
+
free(this);
}
@@ -62,58 +116,12 @@ plugin_t *pem_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- /* register private key PEM decoding builders */
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY, FALSE,
- (builder_function_t)pem_private_key_load);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE,
- (builder_function_t)pem_private_key_load);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ECDSA, FALSE,
- (builder_function_t)pem_private_key_load);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_DSA, FALSE,
- (builder_function_t)pem_private_key_load);
-
- /* register public key PEM decoding builders */
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, FALSE,
- (builder_function_t)pem_public_key_load);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, FALSE,
- (builder_function_t)pem_public_key_load);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA, FALSE,
- (builder_function_t)pem_public_key_load);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_DSA, FALSE,
- (builder_function_t)pem_public_key_load);
-
- /* register certificate PEM decoding builders */
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_ANY, FALSE,
- (builder_function_t)pem_certificate_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509, FALSE,
- (builder_function_t)pem_certificate_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, FALSE,
- (builder_function_t)pem_certificate_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST, FALSE,
- (builder_function_t)pem_certificate_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE, FALSE,
- (builder_function_t)pem_certificate_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC, FALSE,
- (builder_function_t)pem_certificate_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST, FALSE,
- (builder_function_t)pem_certificate_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY, FALSE,
- (builder_function_t)pem_certificate_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_GPG, FALSE,
- (builder_function_t)pem_certificate_load);
-
- /* register pluto specific certificate formats */
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CERT, FALSE,
- (builder_function_t)pem_certificate_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PLUTO_CRL, FALSE,
- (builder_function_t)pem_certificate_load);
-
/* register PEM encoder */
lib->encoding->add_encoder(lib->encoding, pem_encoder_encode);
diff --git a/src/libstrongswan/plugins/pgp/Makefile.in b/src/libstrongswan/plugins/pgp/Makefile.in
index 6be915f29..946424eee 100644
--- a/src/libstrongswan/plugins/pgp/Makefile.in
+++ b/src/libstrongswan/plugins/pgp/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/pgp/pgp_builder.c b/src/libstrongswan/plugins/pgp/pgp_builder.c
index 440e70a18..361157742 100644
--- a/src/libstrongswan/plugins/pgp/pgp_builder.c
+++ b/src/libstrongswan/plugins/pgp/pgp_builder.c
@@ -152,7 +152,7 @@ static private_key_t *parse_private_key(chunk_t blob)
}
if (!pgp_read_scalar(&packet, 1, &version))
{
- return FALSE;
+ return NULL;
}
switch (version)
{
@@ -166,7 +166,7 @@ static private_key_t *parse_private_key(chunk_t blob)
break;
default:
DBG1(DBG_LIB, "PGP packet version V%d not supported", version);
- return FALSE;
+ return NULL;
}
if (!pgp_read_scalar(&packet, 4, &created))
{
diff --git a/src/libstrongswan/plugins/pgp/pgp_cert.c b/src/libstrongswan/plugins/pgp/pgp_cert.c
index 5b21b46d4..70a236855 100644
--- a/src/libstrongswan/plugins/pgp/pgp_cert.c
+++ b/src/libstrongswan/plugins/pgp/pgp_cert.c
@@ -74,35 +74,26 @@ struct private_pgp_cert_t {
};
-/**
- * Implementation of certificate_t.get_type
- */
-static certificate_type_t get_type(private_pgp_cert_t *this)
+METHOD(certificate_t, get_type, certificate_type_t,
+ private_pgp_cert_t *this)
{
return CERT_GPG;
}
-/**
- * Implementation of certificate_t.get_subject
- */
-static identification_t* get_subject(private_pgp_cert_t *this)
+METHOD(certificate_t, get_subject,identification_t*,
+ private_pgp_cert_t *this)
{
return this->user_id;
}
-/**
- * Implementation of certificate_t.get_issuer
- */
-static identification_t* get_issuer(private_pgp_cert_t *this)
+METHOD(certificate_t, get_issuer, identification_t*,
+ private_pgp_cert_t *this)
{
return this->user_id;
}
-/**
- * Implementation of certificate_t.has_subject.
- */
-static id_match_t has_subject(private_pgp_cert_t *this,
- identification_t *subject)
+METHOD(certificate_t, has_subject, id_match_t,
+ private_pgp_cert_t *this, identification_t *subject)
{
id_match_t match_user_id;
@@ -116,46 +107,36 @@ static id_match_t has_subject(private_pgp_cert_t *this,
return match_user_id;
}
-/**
- * Implementation of certificate_t.has_subject.
- */
-static id_match_t has_issuer(private_pgp_cert_t *this, identification_t *issuer)
+METHOD(certificate_t, has_issuer, id_match_t,
+ private_pgp_cert_t *this, identification_t *issuer)
{
return ID_MATCH_NONE;
}
-/**
- * Implementation of certificate_t.issued_by
- */
-static bool issued_by(private_pgp_cert_t *this, certificate_t *issuer)
+METHOD(certificate_t, issued_by,bool,
+ private_pgp_cert_t *this, certificate_t *issuer)
{
/* TODO: check signature blobs for a valid signature */
return FALSE;
}
-/**
- * Implementation of certificate_t.get_public_key
- */
-static public_key_t* get_public_key(private_pgp_cert_t *this)
+METHOD(certificate_t, get_public_key, public_key_t*,
+ private_pgp_cert_t *this)
{
this->key->get_ref(this->key);
return this->key;
}
-/**
- * Implementation of certificate_t.get_ref
- */
-static private_pgp_cert_t* get_ref(private_pgp_cert_t *this)
+METHOD(certificate_t, get_ref, certificate_t*,
+ private_pgp_cert_t *this)
{
ref_get(&this->ref);
- return this;
+ return &this->public.interface.interface;
}
-/**
- * Implementation of certificate_t.get_validity.
- */
-static bool get_validity(private_pgp_cert_t *this, time_t *when,
- time_t *not_before, time_t *not_after)
+METHOD(certificate_t, get_validity, bool,
+ private_pgp_cert_t *this, time_t *when, time_t *not_before,
+ time_t *not_after)
{
time_t t, until;
@@ -187,11 +168,8 @@ static bool get_validity(private_pgp_cert_t *this, time_t *when,
return (t >= this->valid && t <= until);
}
-/**
- * Implementation of certificate_t.get_encoding.
- */
-static bool get_encoding(private_pgp_cert_t *this, cred_encoding_type_t type,
- chunk_t *encoding)
+METHOD(certificate_t, get_encoding, bool,
+ private_pgp_cert_t *this, cred_encoding_type_t type, chunk_t *encoding)
{
if (type == CERT_PGP_PKT)
{
@@ -202,10 +180,8 @@ static bool get_encoding(private_pgp_cert_t *this, cred_encoding_type_t type,
CRED_PART_PGP_CERT, this->encoding, CRED_PART_END);
}
-/**
- * Implementation of certificate_t.equals.
- */
-static bool equals(private_pgp_cert_t *this, certificate_t *other)
+METHOD(certificate_t, equals, bool,
+ private_pgp_cert_t *this, certificate_t *other)
{
chunk_t encoding;
bool equal;
@@ -231,10 +207,8 @@ static bool equals(private_pgp_cert_t *this, certificate_t *other)
return equal;
}
-/**
- * Implementation of pgp_cert_t.destroy.
- */
-static void destroy(private_pgp_cert_t *this)
+METHOD(certificate_t, destroy, void,
+ private_pgp_cert_t *this)
{
if (ref_put(&this->ref))
{
@@ -246,10 +220,8 @@ static void destroy(private_pgp_cert_t *this)
}
}
-/**
- * Implementation of pgp_certificate_t.get_fingerprint.
- */
-static chunk_t get_fingerprint(private_pgp_cert_t *this)
+METHOD(pgp_certificate_t, get_fingerprint, chunk_t,
+ private_pgp_cert_t *this)
{
return this->fingerprint;
}
@@ -259,30 +231,30 @@ static chunk_t get_fingerprint(private_pgp_cert_t *this)
*/
private_pgp_cert_t *create_empty()
{
- private_pgp_cert_t *this = malloc_thing(private_pgp_cert_t);
-
- this->public.interface.interface.get_type = (certificate_type_t (*) (certificate_t*))get_type;
- this->public.interface.interface.get_subject = (identification_t* (*) (certificate_t*))get_subject;
- this->public.interface.interface.get_issuer = (identification_t* (*) (certificate_t*))get_issuer;
- this->public.interface.interface.has_subject = (id_match_t (*) (certificate_t*, identification_t*))has_subject;
- this->public.interface.interface.has_issuer = (id_match_t (*) (certificate_t*, identification_t*))has_issuer;
- this->public.interface.interface.issued_by = (bool (*) (certificate_t*, certificate_t*))issued_by;
- this->public.interface.interface.get_public_key = (public_key_t* (*) (certificate_t*))get_public_key;
- this->public.interface.interface.get_validity = (bool (*) (certificate_t*, time_t*, time_t*, time_t*))get_validity;
- this->public.interface.interface.get_encoding = (bool (*) (certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding;
- this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t*))equals;
- this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t*))get_ref;
- this->public.interface.interface.destroy = (void (*)(certificate_t*))destroy;
- this->public.interface.get_fingerprint = (chunk_t (*)(pgp_certificate_t*))get_fingerprint;
-
- this->key = NULL;
- this->version = 0;
- this->created = 0;
- this->valid = 0;
- this->user_id = NULL;
- this->fingerprint = chunk_empty;
- this->encoding = chunk_empty;
- this->ref = 1;
+ private_pgp_cert_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .interface = {
+ .get_type = _get_type,
+ .get_subject = _get_subject,
+ .get_issuer = _get_issuer,
+ .has_subject = _has_subject,
+ .has_issuer = _has_issuer,
+ .issued_by = _issued_by,
+ .get_public_key = _get_public_key,
+ .get_validity = _get_validity,
+ .get_encoding = _get_encoding,
+ .equals = _equals,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_fingerprint = _get_fingerprint,
+ },
+ },
+ .ref = 1,
+ );
return this;
}
@@ -314,18 +286,18 @@ static bool parse_public_key(private_pgp_cert_t *this, chunk_t packet)
}
break;
default:
- DBG1(DBG_LIB, "PGP packet version V%d not supported",
+ DBG1(DBG_ASN, "PGP packet version V%d not supported",
this->version);
return FALSE;
}
if (this->valid)
{
- DBG2(DBG_LIB, "L2 - created %T, valid %d days", &this->created, FALSE,
+ DBG2(DBG_ASN, "L2 - created %T, valid %d days", &this->created, FALSE,
this->valid);
}
else
{
- DBG2(DBG_LIB, "L2 - created %T, never expires", &this->created, FALSE);
+ DBG2(DBG_ASN, "L2 - created %T, never expires", &this->created, FALSE);
}
DESTROY_IF(this->key);
this->key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY,
@@ -346,13 +318,13 @@ static bool parse_public_key(private_pgp_cert_t *this, chunk_t packet)
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
if (hasher == NULL)
{
- DBG1(DBG_LIB, "no SHA-1 hasher available");
+ DBG1(DBG_ASN, "no SHA-1 hasher available");
return FALSE;
}
hasher->allocate_hash(hasher, pubkey_packet_header, NULL);
hasher->allocate_hash(hasher, pubkey_packet, &this->fingerprint);
hasher->destroy(hasher);
- DBG2(DBG_LIB, "L2 - v4 fingerprint %#B", &this->fingerprint);
+ DBG2(DBG_ASN, "L2 - v4 fingerprint %#B", &this->fingerprint);
}
else
{
@@ -363,7 +335,7 @@ static bool parse_public_key(private_pgp_cert_t *this, chunk_t packet)
return FALSE;
}
this->fingerprint = chunk_clone(this->fingerprint);
- DBG2(DBG_LIB, "L2 - v3 fingerprint %#B", &this->fingerprint);
+ DBG2(DBG_ASN, "L2 - v3 fingerprint %#B", &this->fingerprint);
}
return TRUE;
}
@@ -383,7 +355,7 @@ static bool parse_signature(private_pgp_cert_t *this, chunk_t packet)
/* we parse only v3 or v4 signature packets */
if (version != 3 && version != 4)
{
- DBG2(DBG_LIB, "L2 - v%d signature ignored", version);
+ DBG2(DBG_ASN, "L2 - v%d signature ignored", version);
return TRUE;
}
if (version == 4)
@@ -392,7 +364,7 @@ static bool parse_signature(private_pgp_cert_t *this, chunk_t packet)
{
return FALSE;
}
- DBG2(DBG_LIB, "L2 - v%d signature of type 0x%02x", version, type);
+ DBG2(DBG_ASN, "L2 - v%d signature of type 0x%02x", version, type);
}
else
{
@@ -405,7 +377,7 @@ static bool parse_signature(private_pgp_cert_t *this, chunk_t packet)
{
return FALSE;
}
- DBG2(DBG_LIB, "L2 - v3 signature of type 0x%02x, created %T", type,
+ DBG2(DBG_ASN, "L2 - v3 signature of type 0x%02x, created %T", type,
&created, FALSE);
}
/* TODO: parse and save signature to a list */
@@ -419,7 +391,7 @@ static bool parse_user_id(private_pgp_cert_t *this, chunk_t packet)
{
DESTROY_IF(this->user_id);
this->user_id = identification_create_from_encoding(ID_KEY_ID, packet);
- DBG2(DBG_LIB, "L2 - '%Y'", this->user_id);
+ DBG2(DBG_ASN, "L2 - '%Y'", this->user_id);
return TRUE;
}
@@ -469,14 +441,14 @@ pgp_cert_t *pgp_cert_load(certificate_type_t type, va_list args)
if (!parse_signature(this, packet))
{
destroy(this);
- return FALSE;
+ return NULL;
}
break;
case PGP_PKT_USER_ID:
if (!parse_user_id(this, packet))
{
destroy(this);
- return FALSE;
+ return NULL;
}
break;
default:
diff --git a/src/libstrongswan/plugins/pgp/pgp_plugin.c b/src/libstrongswan/plugins/pgp/pgp_plugin.c
index 52e9d96b1..a2cf403dc 100644
--- a/src/libstrongswan/plugins/pgp/pgp_plugin.c
+++ b/src/libstrongswan/plugins/pgp/pgp_plugin.c
@@ -39,17 +39,30 @@ METHOD(plugin_t, get_name, char*,
return "pgp";
}
-METHOD(plugin_t, destroy, void,
- private_pgp_plugin_t *this)
+METHOD(plugin_t, get_features, int,
+ private_pgp_plugin_t *this, plugin_feature_t *features[])
{
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)pgp_public_key_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)pgp_private_key_load);
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(PRIVKEY, pgp_private_key_load, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
+ PLUGIN_REGISTER(PRIVKEY, pgp_private_key_load, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)pgp_cert_load);
+ PLUGIN_REGISTER(PUBKEY, pgp_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
+ PLUGIN_REGISTER(PUBKEY, pgp_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
+
+ PLUGIN_REGISTER(CERT_DECODE, pgp_cert_load, FALSE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_GPG),
+ };
+ *features = f;
+ return countof(f);
+}
+METHOD(plugin_t, destroy, void,
+ private_pgp_plugin_t *this)
+{
lib->encoding->remove_encoder(lib->encoding, pgp_encoder_encode);
free(this);
@@ -66,21 +79,12 @@ plugin_t *pgp_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, FALSE,
- (builder_function_t)pgp_public_key_load);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, FALSE,
- (builder_function_t)pgp_public_key_load);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY, FALSE,
- (builder_function_t)pgp_private_key_load);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE,
- (builder_function_t)pgp_private_key_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_GPG, FALSE,
- (builder_function_t)pgp_cert_load);
+
lib->encoding->add_encoder(lib->encoding, pgp_encoder_encode);
return &this->public.plugin;
diff --git a/src/libstrongswan/plugins/pgp/pgp_utils.c b/src/libstrongswan/plugins/pgp/pgp_utils.c
index 2d85cc0c8..7fd905ce4 100644
--- a/src/libstrongswan/plugins/pgp/pgp_utils.c
+++ b/src/libstrongswan/plugins/pgp/pgp_utils.c
@@ -79,7 +79,7 @@ bool pgp_read_scalar(chunk_t *blob, size_t bytes, u_int32_t *scalar)
if (bytes > blob->len)
{
- DBG1(DBG_LIB, "PGP data too short to read %d byte scalar", bytes);
+ DBG1(DBG_ASN, "PGP data too short to read %d byte scalar", bytes);
return FALSE;
}
while (bytes-- > 0)
@@ -100,13 +100,13 @@ bool pgp_read_mpi(chunk_t *blob, chunk_t *mpi)
if (!pgp_read_scalar(blob, 2, &bits))
{
- DBG1(DBG_LIB, "PGP data too short to read MPI length");
+ DBG1(DBG_ASN, "PGP data too short to read MPI length");
return FALSE;
}
bytes = (bits + 7) / 8;
if (bytes > blob->len)
{
- DBG1(DBG_LIB, "PGP data too short to read %d byte MPI", bytes);
+ DBG1(DBG_ASN, "PGP data too short to read %d byte MPI", bytes);
return FALSE;
}
*mpi = chunk_create(blob->ptr, bytes);
@@ -146,7 +146,7 @@ bool pgp_read_packet(chunk_t *blob, chunk_t *data, pgp_packet_tag_t *tag)
if (!blob->len)
{
- DBG1(DBG_LIB, "missing input");
+ DBG1(DBG_ASN, "missing input");
return FALSE;
}
t = blob->ptr[0];
@@ -154,27 +154,27 @@ bool pgp_read_packet(chunk_t *blob, chunk_t *data, pgp_packet_tag_t *tag)
/* bit 7 must be set */
if (!(t & 0x80))
{
- DBG1(DBG_LIB, "invalid packet tag");
+ DBG1(DBG_ASN, "invalid packet tag");
return FALSE;
}
/* bit 6 set defines new packet format */
if (t & 0x40)
{
- DBG1(DBG_LIB, "new PGP packet format not supported");
+ DBG1(DBG_ASN, "new PGP packet format not supported");
return FALSE;
}
t = (t & 0x3C) >> 2;
if (!pgp_old_packet_length(blob, &len) || len > blob->len)
{
- DBG1(DBG_LIB, "invalid packet length");
+ DBG1(DBG_ASN, "invalid packet length");
return FALSE;
}
*data = chunk_create(blob->ptr, len);
*blob = chunk_skip(*blob, len);
*tag = t;
- DBG2(DBG_LIB, "L1 - PGP %N (%u bytes)", pgp_packet_tag_names, t, len);
- DBG3(DBG_LIB, "%B", data);
+ DBG2(DBG_ASN, "L1 - PGP %N (%u bytes)", pgp_packet_tag_names, t, len);
+ DBG3(DBG_ASN, "%B", data);
return TRUE;
}
diff --git a/src/libstrongswan/plugins/pkcs1/Makefile.in b/src/libstrongswan/plugins/pkcs1/Makefile.in
index 1ae880c3b..f9322a62d 100644
--- a/src/libstrongswan/plugins/pkcs1/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs1/Makefile.in
@@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -201,6 +204,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -217,11 +221,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
index a605fabc7..6d022f362 100644
--- a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
+++ b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c
@@ -81,10 +81,10 @@ static public_key_t *parse_public_key(chunk_t blob)
/* skip initial bit string octet defining 0 unused bits */
object = chunk_skip(object, 1);
}
- DBG2(DBG_LIB, "-- > --");
+ DBG2(DBG_ASN, "-- > --");
key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, type,
BUILD_BLOB_ASN1_DER, object, BUILD_END);
- DBG2(DBG_LIB, "-- < --");
+ DBG2(DBG_ASN, "-- < --");
break;
}
}
@@ -197,7 +197,7 @@ static private_key_t *parse_rsa_private_key(chunk_t blob)
case PRIV_KEY_VERSION:
if (object.len > 0 && *object.ptr != 0)
{
- DBG1(DBG_LIB, "PKCS#1 private key format is not version 1");
+ DBG1(DBG_ASN, "PKCS#1 private key format is not version 1");
goto end;
}
break;
diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c b/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c
index e0e24cab2..b304a5101 100644
--- a/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c
+++ b/src/libstrongswan/plugins/pkcs1/pkcs1_plugin.c
@@ -38,14 +38,24 @@ METHOD(plugin_t, get_name, char*,
return "pkcs1";
}
+METHOD(plugin_t, get_features, int,
+ private_pkcs1_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(PRIVKEY, pkcs1_private_key_load, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
+ PLUGIN_REGISTER(PUBKEY, pkcs1_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
+ PLUGIN_REGISTER(PUBKEY, pkcs1_public_key_load, FALSE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_pkcs1_plugin_t *this)
{
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)pkcs1_public_key_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)pkcs1_private_key_load);
-
lib->encoding->remove_encoder(lib->encoding, pkcs1_encoder_encode);
free(this);
@@ -62,19 +72,12 @@ plugin_t *pkcs1_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, FALSE,
- (builder_function_t)pkcs1_public_key_load);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, FALSE,
- (builder_function_t)pkcs1_public_key_load);
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, FALSE,
- (builder_function_t)pkcs1_private_key_load);
-
lib->encoding->add_encoder(lib->encoding, pkcs1_encoder_encode);
return &this->public.plugin;
diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.am b/src/libstrongswan/plugins/pkcs11/Makefile.am
index 199039d95..d032b879a 100644
--- a/src/libstrongswan/plugins/pkcs11/Makefile.am
+++ b/src/libstrongswan/plugins/pkcs11/Makefile.am
@@ -16,6 +16,8 @@ libstrongswan_pkcs11_la_SOURCES = \
pkcs11_private_key.h pkcs11_private_key.c \
pkcs11_public_key.h pkcs11_public_key.c \
pkcs11_hasher.h pkcs11_hasher.c \
+ pkcs11_rng.h pkcs11_rng.c \
+ pkcs11_dh.h pkcs11_dh.c \
pkcs11_manager.h pkcs11_manager.c
libstrongswan_pkcs11_la_LDFLAGS = -module -avoid-version
diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.in b/src/libstrongswan/plugins/pkcs11/Makefile.in
index 1a67f88cc..2ead77f5a 100644
--- a/src/libstrongswan/plugins/pkcs11/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs11/Makefile.in
@@ -77,7 +77,8 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
libstrongswan_pkcs11_la_LIBADD =
am_libstrongswan_pkcs11_la_OBJECTS = pkcs11_plugin.lo \
pkcs11_library.lo pkcs11_creds.lo pkcs11_private_key.lo \
- pkcs11_public_key.lo pkcs11_hasher.lo pkcs11_manager.lo
+ pkcs11_public_key.lo pkcs11_hasher.lo pkcs11_rng.lo \
+ pkcs11_dh.lo pkcs11_manager.lo
libstrongswan_pkcs11_la_OBJECTS = \
$(am_libstrongswan_pkcs11_la_OBJECTS)
libstrongswan_pkcs11_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -195,6 +196,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +207,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +224,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +274,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -288,6 +296,8 @@ libstrongswan_pkcs11_la_SOURCES = \
pkcs11_private_key.h pkcs11_private_key.c \
pkcs11_public_key.h pkcs11_public_key.c \
pkcs11_hasher.h pkcs11_hasher.c \
+ pkcs11_rng.h pkcs11_rng.c \
+ pkcs11_dh.h pkcs11_dh.c \
pkcs11_manager.h pkcs11_manager.c
libstrongswan_pkcs11_la_LDFLAGS = -module -avoid-version
@@ -375,12 +385,14 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_creds.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_dh.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_hasher.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_library.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_manager.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_plugin.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_private_key.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_public_key.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs11_rng.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11.h b/src/libstrongswan/plugins/pkcs11/pkcs11.h
index 2e6a1e3ed..da29a77d0 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11.h
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11.h
@@ -179,6 +179,14 @@ extern "C" {
#define unlock_mutex UnlockMutex
#define reserved pReserved
+#define ck_ec_kdf_type_t CK_EC_KDF_TYPE
+
+#define ck_ecdh1_derive_args _CK_ECDH1_DERIVE_PARAMS
+#define shared_data_len ulSharedDataLen
+#define shared_data pSharedData
+#define public_data_len ulPublicDataLen
+#define public_data pPublicData
+
#endif /* CRYPTOKI_COMPAT */
@@ -1090,6 +1098,19 @@ struct ck_c_initialize_args
void *reserved;
};
+typedef unsigned long ck_ec_kdf_type_t;
+
+#define CKD_NULL (1)
+#define CKD_SHA1_DKF (2)
+
+struct ck_ecdh1_derive_params
+{
+ ck_ec_kdf_type_t kdf;
+ unsigned long shared_data_len;
+ void *shared_data;
+ unsigned long public_data_len;
+ void *public_data;
+};
#define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1 << 0)
#define CKF_OS_LOCKING_OK (1 << 1)
@@ -1260,6 +1281,9 @@ typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR;
typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS;
typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR;
+typedef struct ck_ecdh1_derive_params CK_ECDH1_DERIVE_PARAMS;
+typedef struct ck_ecdh1_derive_params *CK_ECDH1_DERIVE_PARAMS_PTR;
+
#define NULL_PTR NULL
/* Delete the helper macros defined at the top of the file. */
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c
new file mode 100644
index 000000000..c870370c8
--- /dev/null
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2011 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 "pkcs11_dh.h"
+
+#include <debug.h>
+#include <library.h>
+#include <asn1/asn1.h>
+#include <asn1/oid.h>
+
+#include "pkcs11_manager.h"
+
+typedef struct private_pkcs11_dh_t private_pkcs11_dh_t;
+
+/**
+ * Private data of an pkcs11_dh_t object.
+ */
+struct private_pkcs11_dh_t {
+
+ /**
+ * Public pkcs11_dh_t interface
+ */
+ pkcs11_dh_t public;
+
+ /**
+ * PKCS#11 library
+ */
+ pkcs11_library_t *lib;
+
+ /**
+ * Session handle for this objct
+ */
+ CK_SESSION_HANDLE session;
+
+ /**
+ * Diffie Hellman group number.
+ */
+ u_int16_t group;
+
+ /**
+ * Handle for own private value
+ */
+ CK_OBJECT_HANDLE pri_key;
+
+ /**
+ * Own public value
+ */
+ chunk_t pub_key;
+
+ /**
+ * Shared secret
+ */
+ chunk_t secret;
+
+ /**
+ * Mechanism to use to generate a key pair
+ */
+ CK_MECHANISM_TYPE mech_key;
+
+ /**
+ * Mechanism to use to derive a shared secret
+ */
+ CK_MECHANISM_TYPE mech_derive;
+
+};
+
+/**
+ * Derive a DH/ECDH shared secret.
+ *
+ * If this succeeds the shared secret is stored in this->secret.
+ */
+static void derive_secret(private_pkcs11_dh_t *this, chunk_t other)
+{
+ CK_OBJECT_CLASS klass = CKO_SECRET_KEY;
+ CK_KEY_TYPE type = CKK_GENERIC_SECRET;
+ CK_ATTRIBUTE attr[] = {
+ { CKA_CLASS, &klass, sizeof(klass) },
+ { CKA_KEY_TYPE, &type, sizeof(type) },
+ };
+ CK_MECHANISM mech = {
+ this->mech_derive,
+ other.ptr,
+ other.len,
+ };
+ CK_OBJECT_HANDLE secret;
+ CK_RV rv;
+
+ rv = this->lib->f->C_DeriveKey(this->session, &mech, this->pri_key,
+ attr, countof(attr), &secret);
+ if (rv != CKR_OK)
+ {
+ DBG1(DBG_CFG, "C_DeriveKey() error: %N", ck_rv_names, rv);
+ return;
+ }
+ if (!this->lib->get_ck_attribute(this->lib, this->session, secret,
+ CKA_VALUE, &this->secret))
+ {
+ chunk_free(&this->secret);
+ return;
+ }
+}
+
+METHOD(diffie_hellman_t, set_other_public_value, void,
+ private_pkcs11_dh_t *this, chunk_t value)
+{
+ switch (this->group)
+ {
+ case ECP_192_BIT:
+ case ECP_224_BIT:
+ case ECP_256_BIT:
+ case ECP_384_BIT:
+ case ECP_521_BIT:
+ { /* we expect the public value to just be the concatenated x and y
+ * coordinates, so we tag the value as an uncompressed ECPoint */
+ chunk_t tag = chunk_from_chars(0x04);
+ chunk_t pubkey = chunk_cata("cc", tag, value);
+ CK_ECDH1_DERIVE_PARAMS params = {
+ CKD_NULL,
+ 0,
+ NULL,
+ pubkey.len,
+ pubkey.ptr,
+ };
+
+ if (!lib->settings->get_bool(lib->settings,
+ "libstrongswan.ecp_x_coordinate_only", TRUE))
+ { /* we only get the x coordinate back */
+ return;
+ }
+ value = chunk_from_thing(params);
+ break;
+ }
+ default:
+ break;
+ }
+ derive_secret(this, value);
+}
+
+METHOD(diffie_hellman_t, get_my_public_value, void,
+ private_pkcs11_dh_t *this, chunk_t *value)
+{
+ *value = chunk_clone(this->pub_key);
+}
+
+METHOD(diffie_hellman_t, get_shared_secret, status_t,
+ private_pkcs11_dh_t *this, chunk_t *secret)
+{
+ if (!this->secret.ptr)
+ {
+ return FAILED;
+ }
+ *secret = chunk_clone(this->secret);
+ return SUCCESS;
+}
+
+METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
+ private_pkcs11_dh_t *this)
+{
+ return this->group;
+}
+
+METHOD(diffie_hellman_t, destroy, void,
+ private_pkcs11_dh_t *this)
+{
+ this->lib->f->C_CloseSession(this->session);
+ chunk_clear(&this->pub_key);
+ chunk_clear(&this->secret);
+ free(this);
+}
+
+/**
+ * Generate a DH/ECDH key pair.
+ *
+ * If this succeeds, this->pri_key has a handle to the private key and
+ * this->pub_key stores the public key.
+ */
+static bool generate_key_pair(private_pkcs11_dh_t *this, CK_ATTRIBUTE_PTR pub,
+ int pub_len, CK_ATTRIBUTE_PTR pri, int pri_len,
+ CK_ATTRIBUTE_TYPE attr)
+{
+ CK_MECHANISM mech = {
+ this->mech_key,
+ NULL,
+ 0,
+ };
+ CK_OBJECT_HANDLE pub_key;
+ CK_RV rv;
+
+ rv = this->lib->f->C_GenerateKeyPair(this->session, &mech, pub, pub_len,
+ pri, pri_len, &pub_key, &this->pri_key);
+ if (rv != CKR_OK)
+ {
+ DBG1(DBG_CFG, "C_GenerateKeyPair() error: %N", ck_rv_names, rv);
+ return FALSE;
+ }
+ if (!this->lib->get_ck_attribute(this->lib, this->session, pub_key,
+ attr, &this->pub_key))
+ {
+ chunk_free(&this->pub_key);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Generate DH key pair.
+ */
+static bool generate_key_pair_modp(private_pkcs11_dh_t *this, size_t exp_len,
+ chunk_t g, chunk_t p)
+{
+ CK_BBOOL ck_true = CK_TRUE;
+ CK_ATTRIBUTE pub_attr[] = {
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ { CKA_PRIME, p.ptr, p.len },
+ { CKA_BASE, g.ptr, g.len },
+ };
+ CK_ULONG bits = exp_len * 8;
+ CK_ATTRIBUTE pri_attr[] = {
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ { CKA_VALUE_BITS, &bits, sizeof(bits) },
+ };
+ return generate_key_pair(this, pub_attr, countof(pub_attr), pri_attr,
+ countof(pri_attr), CKA_VALUE);
+}
+
+/**
+ * Generate ECDH key pair.
+ */
+static bool generate_key_pair_ecp(private_pkcs11_dh_t *this,
+ chunk_t ecparams)
+{
+ CK_BBOOL ck_true = CK_TRUE;
+ CK_ATTRIBUTE pub_attr[] = {
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ { CKA_EC_PARAMS, ecparams.ptr, ecparams.len },
+ };
+ CK_ATTRIBUTE pri_attr[] = {
+ { CKA_DERIVE, &ck_true, sizeof(ck_true) },
+ };
+ chunk_t pub_key;
+ if (!generate_key_pair(this, pub_attr, countof(pub_attr), pri_attr,
+ countof(pri_attr), CKA_EC_POINT))
+ {
+ return FALSE;
+ }
+ if (this->pub_key.len <= 0 || this->pub_key.ptr[0] != 0x04)
+ { /* we currently only support the point in uncompressed form which
+ * looks like this: 0x04 || x || y */
+ chunk_clear(&this->pub_key);
+ return FALSE;
+ }
+ pub_key = chunk_clone(chunk_skip(this->pub_key, 1));
+ chunk_clear(&this->pub_key);
+ this->pub_key = pub_key;
+ return TRUE;
+}
+
+/**
+ * Find a token we can use for DH/ECDH algorithm
+ */
+static pkcs11_library_t *find_token(private_pkcs11_dh_t *this,
+ CK_SESSION_HANDLE *session)
+{
+ enumerator_t *tokens, *mechs;
+ pkcs11_manager_t *manager;
+ pkcs11_library_t *current, *found = NULL;
+ CK_MECHANISM_TYPE type;
+ CK_SLOT_ID slot;
+
+ manager = lib->get(lib, "pkcs11-manager");
+ if (!manager)
+ {
+ return NULL;
+ }
+ tokens = manager->create_token_enumerator(manager);
+ while (tokens->enumerate(tokens, &current, &slot))
+ {
+ mechs = current->create_mechanism_enumerator(current, slot);
+ while (mechs->enumerate(mechs, &type, NULL))
+ { /* we assume we can generate key pairs if the derive mechanism
+ * is supported */
+ if (type == this->mech_derive)
+ {
+ if (current->f->C_OpenSession(slot, CKF_SERIAL_SESSION,
+ NULL, NULL, session) == CKR_OK)
+ {
+ found = current;
+ break;
+ }
+ }
+ }
+ mechs->destroy(mechs);
+ if (found)
+ {
+ break;
+ }
+ }
+ tokens->destroy(tokens);
+ return found;
+}
+
+/**
+ * Generic internal constructor
+ */
+static private_pkcs11_dh_t *create_generic(diffie_hellman_group_t group,
+ CK_MECHANISM_TYPE key,
+ CK_MECHANISM_TYPE derive)
+{
+ private_pkcs11_dh_t *this;
+
+ INIT(this,
+ .public = {
+ .dh = {
+ .get_shared_secret = _get_shared_secret,
+ .set_other_public_value = _set_other_public_value,
+ .get_my_public_value = _get_my_public_value,
+ .get_dh_group = _get_dh_group,
+ .destroy = _destroy,
+ },
+ },
+ .group = group,
+ .mech_key = key,
+ .mech_derive = derive,
+ );
+
+ this->lib = find_token(this, &this->session);
+ if (!this->lib)
+ {
+ free(this);
+ return NULL;
+ }
+ return this;
+}
+
+static pkcs11_dh_t *create_ecp(diffie_hellman_group_t group, chunk_t ecparam)
+{
+ private_pkcs11_dh_t *this = create_generic(group, CKM_EC_KEY_PAIR_GEN,
+ CKM_ECDH1_DERIVE);
+
+ if (this)
+ {
+ if (generate_key_pair_ecp(this, ecparam))
+ {
+ chunk_free(&ecparam);
+ return &this->public;
+ }
+ chunk_free(&ecparam);
+ free(this);
+ }
+ return NULL;
+}
+
+/**
+ * Constructor for MODP DH
+ */
+static pkcs11_dh_t *create_modp(diffie_hellman_group_t group, size_t exp_len,
+ chunk_t g, chunk_t p)
+{
+ private_pkcs11_dh_t *this = create_generic(group, CKM_DH_PKCS_KEY_PAIR_GEN,
+ CKM_DH_PKCS_DERIVE);
+
+ if (this)
+ {
+ if (generate_key_pair_modp(this, exp_len, g, p))
+ {
+ return &this->public;
+ }
+ free(this);
+ }
+ return NULL;
+}
+
+/**
+ * Lookup the EC params for the given group.
+ */
+static chunk_t ecparams_lookup(diffie_hellman_group_t group)
+{
+ switch (group)
+ {
+ case ECP_192_BIT:
+ return asn1_build_known_oid(OID_PRIME192V1);
+ case ECP_224_BIT:
+ return asn1_build_known_oid(OID_SECT224R1);
+ case ECP_256_BIT:
+ return asn1_build_known_oid(OID_PRIME256V1);
+ case ECP_384_BIT:
+ return asn1_build_known_oid(OID_SECT384R1);
+ case ECP_521_BIT:
+ return asn1_build_known_oid(OID_SECT521R1);
+ default:
+ break;
+ }
+ return chunk_empty;
+}
+
+/**
+ * Described in header.
+ */
+pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group,
+ chunk_t g, chunk_t p)
+{
+ switch (group)
+ {
+ case MODP_CUSTOM:
+ {
+ return create_modp(group, p.len, g, p);
+ }
+ case ECP_192_BIT:
+ case ECP_224_BIT:
+ case ECP_256_BIT:
+ case ECP_384_BIT:
+ case ECP_521_BIT:
+ {
+ chunk_t params = ecparams_lookup(group);
+ if (params.ptr)
+ {
+ return create_ecp(group, params);
+ }
+ break;
+ }
+ default:
+ {
+ diffie_hellman_params_t *params = diffie_hellman_get_params(group);
+ if (params)
+ {
+ return create_modp(group, params->exp_len, params->generator,
+ params->prime);
+ }
+ break;
+ }
+ }
+ return NULL;
+}
+
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h
new file mode 100644
index 000000000..2654130c0
--- /dev/null
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 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 pkcs11_dh pkcs11_dh
+ * @{ @ingroup pkcs11
+ */
+
+#ifndef PKCS11_DH_H_
+#define PKCS11_DH_H_
+
+typedef struct pkcs11_dh_t pkcs11_dh_t;
+
+#include <library.h>
+
+/**
+ * Implementation of the Diffie-Hellman algorithm via PKCS#11.
+ */
+struct pkcs11_dh_t {
+
+ /**
+ * Implements diffie_hellman_t interface.
+ */
+ diffie_hellman_t dh;
+};
+
+/**
+ * Creates a new pkcs11_dh_t object.
+ *
+ * @param group Diffie Hellman group number to use
+ * @param g generator in case group is MODP_CUSTOM
+ * @param p prime in case group is MODP_CUSTOM
+ * @return pkcs11_dh_t object, NULL if not supported
+ */
+pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group,
+ chunk_t g, chunk_t p);
+
+#endif /** PKCS11_DH_H_ @}*/
+
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c b/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c
index 6d327be40..069fa98b6 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_hasher.c
@@ -260,7 +260,7 @@ static pkcs11_library_t* find_token(hash_algorithm_t algo,
{
return NULL;
}
- manager = pkcs11_manager_get();
+ manager = lib->get(lib, "pkcs11-manager");
if (!manager)
{
return NULL;
@@ -315,6 +315,7 @@ pkcs11_hasher_t *pkcs11_hasher_create(hash_algorithm_t algo)
this->lib = find_token(algo, &this->session, &this->mech, &this->size);
if (!this->lib)
{
+ this->mutex->destroy(this->mutex);
free(this);
return NULL;
}
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
index 6f7926808..97c3d2fcf 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2011 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -447,6 +450,123 @@ ENUM_NEXT(ck_mech_names, CKM_DSA_PARAMETER_GEN, CKM_X9_42_DH_PARAMETER_GEN,
"X9_42_DH_PARAMETER_GEN");
ENUM_END(ck_mech_names, CKM_X9_42_DH_PARAMETER_GEN);
+
+ENUM_BEGIN(ck_attr_names, CKA_CLASS, CKA_LABEL,
+ "CLASS",
+ "TOKEN",
+ "PRIVATE",
+ "LABEL");
+ENUM_NEXT(ck_attr_names, CKA_APPLICATION, CKA_OBJECT_ID, CKA_LABEL,
+ "APPLICATION",
+ "VALUE",
+ "OBJECT_ID");
+ENUM_NEXT(ck_attr_names, CKA_CERTIFICATE_TYPE, CKA_HASH_OF_ISSUER_PUBLIC_KEY,
+ CKA_OBJECT_ID,
+ "CERTIFICATE_TYPE",
+ "ISSUER",
+ "SERIAL_NUMBER",
+ "AC_ISSUER",
+ "OWNER",
+ "ATTR_TYPES",
+ "TRUSTED",
+ "CERTIFICATE_CATEGORY",
+ "JAVA_MIDP_SECURITY_DOMAIN",
+ "URL",
+ "HASH_OF_SUBJECT_PUBLIC_KEY",
+ "HASH_OF_ISSUER_PUBLIC_KEY");
+ENUM_NEXT(ck_attr_names, CKA_CHECK_VALUE, CKA_CHECK_VALUE,
+ CKA_HASH_OF_ISSUER_PUBLIC_KEY,
+ "CHECK_VALUE");
+ENUM_NEXT(ck_attr_names, CKA_KEY_TYPE, CKA_DERIVE, CKA_CHECK_VALUE,
+ "KEY_TYPE",
+ "SUBJECT",
+ "ID",
+ "SENSITIVE",
+ "ENCRYPT",
+ "DECRYPT",
+ "WRAP",
+ "UNWRAP",
+ "SIGN",
+ "SIGN_RECOVER",
+ "VERIFY",
+ "VERIFY_RECOVER",
+ "DERIVE");
+ENUM_NEXT(ck_attr_names, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE,
+ "START_DATE",
+ "END_DATE");
+ENUM_NEXT(ck_attr_names, CKA_MODULUS, CKA_COEFFICIENT, CKA_END_DATE,
+ "MODULUS",
+ "MODULUS_BITS",
+ "PUBLIC_EXPONENT",
+ "PRIVATE_EXPONENT",
+ "PRIME_1",
+ "PRIME_2",
+ "EXPONENT_1",
+ "EXPONENT_2",
+ "COEFFICIENT");
+ENUM_NEXT(ck_attr_names, CKA_PRIME, CKA_SUB_PRIME_BITS, CKA_COEFFICIENT,
+ "PRIME",
+ "SUBPRIME",
+ "BASE",
+ "PRIME_BITS",
+ "SUB_PRIME_BITS");
+ENUM_NEXT(ck_attr_names, CKA_VALUE_BITS, CKA_KEY_GEN_MECHANISM,
+ CKA_SUB_PRIME_BITS,
+ "VALUE_BITS",
+ "VALUE_LEN",
+ "EXTRACTABLE",
+ "LOCAL",
+ "NEVER_EXTRACTABLE",
+ "ALWAYS_SENSITIVE",
+ "KEY_GEN_MECHANISM");
+ENUM_NEXT(ck_attr_names, CKA_MODIFIABLE, CKA_MODIFIABLE, CKA_KEY_GEN_MECHANISM,
+ "MODIFIABLE");
+ENUM_NEXT(ck_attr_names, CKA_EC_PARAMS, CKA_EC_POINT, CKA_MODIFIABLE,
+ "EC_PARAMS",
+ "EC_POINT");
+ENUM_NEXT(ck_attr_names, CKA_SECONDARY_AUTH, CKA_ALWAYS_AUTHENTICATE,
+ CKA_EC_POINT,
+ "SECONDARY_AUTH",
+ "AUTH_PIN_FLAGS",
+ "ALWAYS_AUTHENTICATE");
+ENUM_NEXT(ck_attr_names, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_WITH_TRUSTED,
+ CKA_ALWAYS_AUTHENTICATE,
+ "WRAP_WITH_TRUSTED");
+ENUM_NEXT(ck_attr_names, CKA_HW_FEATURE_TYPE, CKA_HAS_RESET,
+ CKA_WRAP_WITH_TRUSTED,
+ "HW_FEATURE_TYPE",
+ "RESET_ON_INIT",
+ "HAS_RESET");
+ENUM_NEXT(ck_attr_names, CKA_PIXEL_X, CKA_BITS_PER_PIXEL, CKA_HAS_RESET,
+ "PIXEL_X",
+ "RESOLUTION",
+ "CHAR_ROWS",
+ "CHAR_COLUMNS",
+ "COLOR",
+ "BITS_PER_PIXEL");
+ENUM_NEXT(ck_attr_names, CKA_CHAR_SETS, CKA_MIME_TYPES, CKA_BITS_PER_PIXEL,
+ "CHAR_SETS",
+ "ENCODING_METHODS",
+ "MIME_TYPES");
+ENUM_NEXT(ck_attr_names, CKA_MECHANISM_TYPE, CKA_SUPPORTED_CMS_ATTRIBUTES,
+ CKA_MIME_TYPES,
+ "MECHANISM_TYPE",
+ "REQUIRED_CMS_ATTRIBUTES",
+ "DEFAULT_CMS_ATTRIBUTES",
+ "SUPPORTED_CMS_ATTRIBUTES");
+ENUM_NEXT(ck_attr_names, CKA_WRAP_TEMPLATE, CKA_UNWRAP_TEMPLATE,
+ CKA_SUPPORTED_CMS_ATTRIBUTES,
+ "WRAP_TEMPLATE",
+ "UNWRAP_TEMPLATE");
+ENUM_NEXT(ck_attr_names, CKA_ALLOWED_MECHANISMS, CKA_ALLOWED_MECHANISMS,
+ CKA_UNWRAP_TEMPLATE,
+ "ALLOWED_MECHANISMS");
+ENUM_END(ck_attr_names, CKA_ALLOWED_MECHANISMS);
+/* the values in an enum_name_t are stored as int, thus CKA_VENDOR_DEFINED
+ * will overflow and is thus not defined here */
+
+
+
/**
* Private data of an pkcs11_library_t object.
*/
@@ -495,10 +615,12 @@ typedef struct {
CK_SESSION_HANDLE session;
/* pkcs11 library */
pkcs11_library_t *lib;
- /* attributes to retreive */
+ /* attributes to retrieve */
CK_ATTRIBUTE_PTR attr;
/* number of attributes */
CK_ULONG count;
+ /* object handle in case of a single object */
+ CK_OBJECT_HANDLE object;
/* currently allocated attributes, to free */
linked_list_t *freelist;
} object_enumerator_t;
@@ -552,7 +674,7 @@ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
if (rv != CKR_OK)
{
free_attrs(this);
- DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv);
+ DBG1(DBG_CFG, "C_GetAttributeValue() error: %N", ck_rv_names, rv);
return FALSE;
}
return TRUE;
@@ -565,11 +687,19 @@ METHOD(enumerator_t, object_enumerate, bool,
CK_ULONG found;
CK_RV rv;
- rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found);
- if (rv != CKR_OK)
+ if (!this->object)
{
- DBG1(DBG_CFG, "C_FindObjects() failed: %N", ck_rv_names, rv);
- return FALSE;
+ rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found);
+ if (rv != CKR_OK)
+ {
+ DBG1(DBG_CFG, "C_FindObjects() failed: %N", ck_rv_names, rv);
+ return FALSE;
+ }
+ }
+ else
+ {
+ object = this->object;
+ found = 1;
}
if (found)
{
@@ -580,7 +710,10 @@ METHOD(enumerator_t, object_enumerate, bool,
return FALSE;
}
}
- *out = object;
+ if (out)
+ {
+ *out = object;
+ }
return TRUE;
}
return FALSE;
@@ -589,7 +722,10 @@ METHOD(enumerator_t, object_enumerate, bool,
METHOD(enumerator_t, object_destroy, void,
object_enumerator_t *this)
{
- this->lib->f->C_FindObjectsFinal(this->session);
+ if (!this->object)
+ {
+ this->lib->f->C_FindObjectsFinal(this->session);
+ }
free_attrs(this);
this->freelist->destroy(this->freelist);
free(this);
@@ -624,6 +760,27 @@ METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*,
return &enumerator->public;
}
+METHOD(pkcs11_library_t, create_object_attr_enumerator, enumerator_t*,
+ private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR attr, CK_ULONG count)
+{
+ object_enumerator_t *enumerator;
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)_object_enumerate,
+ .destroy = _object_destroy,
+ },
+ .session = session,
+ .lib = &this->public,
+ .attr = attr,
+ .count = count,
+ .object = object,
+ .freelist = linked_list_create(),
+ );
+ return &enumerator->public;
+}
+
/**
* Enumerator over mechanisms
*/
@@ -707,6 +864,32 @@ METHOD(pkcs11_library_t, create_mechanism_enumerator, enumerator_t*,
return &enumerator->public;
}
+METHOD(pkcs11_library_t, get_ck_attribute, bool,
+ private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_TYPE type, chunk_t *data)
+{
+ CK_ATTRIBUTE attr = { type, NULL, 0 };
+ CK_RV rv;
+ rv = this->public.f->C_GetAttributeValue(session, obj, &attr, 1);
+ if (rv != CKR_OK)
+ {
+ DBG1(DBG_CFG, "C_GetAttributeValue(%N) error: %N", ck_attr_names, type,
+ ck_rv_names, rv);
+ return FALSE;
+ }
+ *data = chunk_alloc(attr.ulValueLen);
+ attr.pValue = data->ptr;
+ rv = this->public.f->C_GetAttributeValue(session, obj, &attr, 1);
+ if (rv != CKR_OK)
+ {
+ DBG1(DBG_CFG, "C_GetAttributeValue(%N) error: %N", ck_attr_names, type,
+ ck_rv_names, rv);
+ chunk_free(data);
+ return FALSE;
+ }
+ return TRUE;
+}
+
METHOD(pkcs11_library_t, destroy, void,
private_pkcs11_library_t *this)
{
@@ -739,7 +922,7 @@ void pkcs11_library_trim(char *str, int len)
*/
static CK_RV CreateMutex(CK_VOID_PTR_PTR data)
{
- *data = mutex_create(MUTEX_TYPE_DEFAULT);
+ *data = mutex_create(MUTEX_TYPE_RECURSIVE);
return CKR_OK;
}
@@ -889,7 +1072,9 @@ pkcs11_library_t *pkcs11_library_create(char *name, char *file, bool os_locking)
.get_name = _get_name,
.get_features = _get_features,
.create_object_enumerator = _create_object_enumerator,
+ .create_object_attr_enumerator = _create_object_attr_enumerator,
.create_mechanism_enumerator = _create_mechanism_enumerator,
+ .get_ck_attribute = _get_ck_attribute,
.destroy = _destroy,
},
.name = name,
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.h b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h
index abe023448..e76e65e07 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.h
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2011 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -27,6 +30,7 @@ typedef struct pkcs11_library_t pkcs11_library_t;
#include "pkcs11.h"
#include <enum.h>
+#include <chunk.h>
#include <utils/enumerator.h>
/**
@@ -72,7 +76,7 @@ struct pkcs11_library_t {
*
* @param session session to use
* @param tmpl search template
- * @param tcount number of attributes in the search template
+ * @param tcount number of attributes in the search template
* @param attr attributes to read from object
* @param acount number of attributes to read
*/
@@ -81,6 +85,24 @@ struct pkcs11_library_t {
CK_ATTRIBUTE_PTR attr, CK_ULONG acount);
/**
+ * This is very similar to the object enumerator but is only used to
+ * easily retrieve multiple attributes from a single object for which
+ * a handle is already known.
+ *
+ * The given attribute array is automatically filled in with the
+ * associated attributes. If the value of an output attribute is NULL,
+ * the required memory gets allocated/freed during enumeration.
+ *
+ * @param session session to use
+ * @param object object handle
+ * @param attr attributes to read from object
+ * @param count number of attributes to read
+ */
+ enumerator_t* (*create_object_attr_enumerator)(pkcs11_library_t *this,
+ CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR attr, CK_ULONG count);
+
+ /**
* Create an enumerator over supported mechanisms of a token.
*
* The resulting enumerator enumerates over the mechanism type, and if
@@ -93,6 +115,21 @@ struct pkcs11_library_t {
CK_SLOT_ID slot);
/**
+ * Retrieve a single attribute from the given object.
+ *
+ * Memory for the data is allocated.
+ *
+ * @param session session with the PKCS#11 library
+ * @param obj object handle
+ * @param type attribute type to extract
+ * @param data extracted data
+ * @return TRUE if successful
+ */
+ bool (*get_ck_attribute)(pkcs11_library_t *this, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_TYPE type,
+ chunk_t *data);
+
+ /**
* Destroy a pkcs11_library_t.
*/
void (*destroy)(pkcs11_library_t *this);
@@ -109,7 +146,12 @@ extern enum_name_t *ck_rv_names;
extern enum_name_t *ck_mech_names;
/**
- * Trim/null terminate a string returned by the varius PKCS#11 functions.
+ * Enum names for CK_ATTRIBUTE_TYPE values
+ */
+extern enum_name_t *ck_attr_names;
+
+/**
+ * Trim/null terminate a string returned by the various PKCS#11 functions.
*
* @param str string to trim
* @param len max length of the string
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c
index 431cd6a2c..5b321b26e 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c
@@ -323,17 +323,11 @@ METHOD(pkcs11_manager_t, create_token_enumerator, enumerator_t*,
return &enumerator->public;
}
-/**
- * Singleton instance
- */
-static private_pkcs11_manager_t *singleton = NULL;
-
METHOD(pkcs11_manager_t, destroy, void,
private_pkcs11_manager_t *this)
{
this->libs->destroy_function(this->libs, (void*)lib_entry_destroy);
free(this);
- singleton = NULL;
}
/**
@@ -386,14 +380,12 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb,
}
enumerator->destroy(enumerator);
- singleton = this;
-
enumerator = this->libs->create_enumerator(this->libs);
while (enumerator->enumerate(enumerator, &entry))
{
query_slots(entry);
- entry->job = callback_job_create((void*)dispatch_slot_events,
- entry, (void*)end_dispatch, NULL);
+ entry->job = callback_job_create_with_prio((void*)dispatch_slot_events,
+ entry, (void*)end_dispatch, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)entry->job);
}
enumerator->destroy(enumerator);
@@ -401,10 +393,3 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb,
return &this->public;
}
-/**
- * See header
- */
-pkcs11_manager_t *pkcs11_manager_get()
-{
- return (pkcs11_manager_t*)singleton;
-}
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h
index b80d67324..2f51fb30e 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.h
@@ -32,7 +32,7 @@ typedef struct pkcs11_manager_t pkcs11_manager_t;
*
* @param data user supplied data, as passed to pkcs11_manager_create()
* @param p11 loaded PKCS#11 library token belongs to
- * @param slot slot number the event occured in
+ * @param slot slot number the event occurred in
* @param add TRUE if token was added to the slot, FALSE if removed
*/
typedef void (*pkcs11_manager_token_event_t)(void *data, pkcs11_library_t *p11,
@@ -67,12 +67,4 @@ struct pkcs11_manager_t {
pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb,
void *data);
-
-/**
- * Get the singleton instance of the manager
- *
- * @return instance, NULL if none available
- */
-pkcs11_manager_t *pkcs11_manager_get();
-
#endif /** PKCS11_MANAGER_H_ @}*/
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c b/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c
index 7b537cfa7..183fce53a 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2011 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -19,12 +22,15 @@
#include <debug.h>
#include <utils/linked_list.h>
#include <threading/mutex.h>
+#include <threading/rwlock.h>
#include "pkcs11_manager.h"
#include "pkcs11_creds.h"
#include "pkcs11_private_key.h"
#include "pkcs11_public_key.h"
#include "pkcs11_hasher.h"
+#include "pkcs11_rng.h"
+#include "pkcs11_dh.h"
typedef struct private_pkcs11_plugin_t private_pkcs11_plugin_t;
@@ -52,6 +58,16 @@ struct private_pkcs11_plugin_t {
* mutex to lock list
*/
mutex_t *mutex;
+
+ /**
+ * TRUE if events from tokens are to be handled
+ */
+ bool handle_events;
+
+ /**
+ * Lock for the above flag
+ */
+ rwlock_t *handle_events_lock;
};
/**
@@ -61,9 +77,10 @@ static void token_event_cb(private_pkcs11_plugin_t *this, pkcs11_library_t *p11,
CK_SLOT_ID slot, bool add)
{
enumerator_t *enumerator;
- pkcs11_creds_t *creds, *found = NULL;;
+ pkcs11_creds_t *creds, *found = NULL;
- if (add)
+ this->handle_events_lock->read_lock(this->handle_events_lock);
+ if (add && this->handle_events)
{
creds = pkcs11_creds_create(p11, slot);
if (creds)
@@ -74,7 +91,7 @@ static void token_event_cb(private_pkcs11_plugin_t *this, pkcs11_library_t *p11,
lib->credmgr->add_set(lib->credmgr, &creds->set);
}
}
- else
+ else if (this->handle_events)
{
this->mutex->lock(this->mutex);
enumerator = this->creds->create_enumerator(this->creds);
@@ -99,6 +116,7 @@ static void token_event_cb(private_pkcs11_plugin_t *this, pkcs11_library_t *p11,
lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
}
}
+ this->handle_events_lock->unlock(this->handle_events_lock);
}
METHOD(plugin_t, get_name, char*,
@@ -107,23 +125,158 @@ METHOD(plugin_t, get_name, char*,
return "pkcs11";
}
-METHOD(plugin_t, destroy, void,
- private_pkcs11_plugin_t *this)
+/**
+ * Load/unload certificates from tokens.
+ */
+static bool handle_certs(private_pkcs11_plugin_t *this,
+ plugin_feature_t *feature, bool reg, void *data)
{
- pkcs11_creds_t *creds;
+ this->handle_events_lock->write_lock(this->handle_events_lock);
+ this->handle_events = reg;
+ this->handle_events_lock->unlock(this->handle_events_lock);
+
+ if (reg)
+ {
+ enumerator_t *enumerator;
+ pkcs11_library_t *p11;
+ CK_SLOT_ID slot;
+
+ enumerator = this->manager->create_token_enumerator(this->manager);
+ while (enumerator->enumerate(enumerator, &p11, &slot))
+ {
+ token_event_cb(this, p11, slot, TRUE);
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ pkcs11_creds_t *creds;
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)pkcs11_private_key_connect);
- while (this->creds->remove_last(this->creds, (void**)&creds) == SUCCESS)
+ while (this->creds->remove_last(this->creds, (void**)&creds) == SUCCESS)
+ {
+ lib->credmgr->remove_set(lib->credmgr, &creds->set);
+ creds->destroy(creds);
+ }
+ }
+ return TRUE;
+}
+/**
+ * Add a set of features
+ */
+static inline void add_features(plugin_feature_t *f, plugin_feature_t *n,
+ int count, int *pos)
+{
+ int i;
+ for (i = 0; i < count; i++)
{
- lib->credmgr->remove_set(lib->credmgr, &creds->set);
- creds->destroy(creds);
+ f[(*pos)++] = n[i];
}
- lib->crypto->remove_hasher(lib->crypto,
- (hasher_constructor_t)pkcs11_hasher_create);
- this->creds->destroy(this->creds);
+}
+
+METHOD(plugin_t, get_features, int,
+ private_pkcs11_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f_hash[] = {
+ PLUGIN_REGISTER(HASHER, pkcs11_hasher_create),
+ PLUGIN_PROVIDE(HASHER, HASH_MD2),
+ PLUGIN_PROVIDE(HASHER, HASH_MD5),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA1),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA256),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA384),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA512),
+ };
+ static plugin_feature_t f_dh[] = {
+ PLUGIN_REGISTER(DH, pkcs11_dh_create),
+ PLUGIN_PROVIDE(DH, MODP_2048_BIT),
+ PLUGIN_PROVIDE(DH, MODP_2048_224),
+ PLUGIN_PROVIDE(DH, MODP_2048_256),
+ PLUGIN_PROVIDE(DH, MODP_1536_BIT),
+ PLUGIN_PROVIDE(DH, MODP_3072_BIT),
+ PLUGIN_PROVIDE(DH, MODP_4096_BIT),
+ PLUGIN_PROVIDE(DH, MODP_6144_BIT),
+ PLUGIN_PROVIDE(DH, MODP_8192_BIT),
+ PLUGIN_PROVIDE(DH, MODP_1024_BIT),
+ PLUGIN_PROVIDE(DH, MODP_1024_160),
+ PLUGIN_PROVIDE(DH, MODP_768_BIT),
+ PLUGIN_PROVIDE(DH, MODP_CUSTOM),
+ };
+ static plugin_feature_t f_ecdh[] = {
+ PLUGIN_REGISTER(DH, pkcs11_dh_create),
+ PLUGIN_PROVIDE(DH, ECP_192_BIT),
+ PLUGIN_PROVIDE(DH, ECP_224_BIT),
+ PLUGIN_PROVIDE(DH, ECP_256_BIT),
+ PLUGIN_PROVIDE(DH, ECP_384_BIT),
+ PLUGIN_PROVIDE(DH, ECP_521_BIT),
+ };
+ static plugin_feature_t f_rng[] = {
+ PLUGIN_REGISTER(RNG, pkcs11_rng_create),
+ PLUGIN_PROVIDE(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(RNG, RNG_TRUE),
+ };
+ static plugin_feature_t f_privkey[] = {
+ PLUGIN_REGISTER(PRIVKEY, pkcs11_private_key_connect, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
+ };
+ static plugin_feature_t f_pubkey[] = {
+ PLUGIN_REGISTER(PUBKEY, pkcs11_public_key_load, TRUE),
+ PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
+ PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
+ };
+ static plugin_feature_t f_manager[] = {
+ PLUGIN_CALLBACK((plugin_feature_callback_t)handle_certs, NULL),
+ PLUGIN_PROVIDE(CUSTOM, "pkcs11-certs"),
+ PLUGIN_DEPENDS(CERT_DECODE, CERT_X509),
+ };
+ static plugin_feature_t f[countof(f_hash) + countof(f_dh) + countof(f_rng) +
+ countof(f_ecdh) + countof(f_privkey) +
+ countof(f_pubkey) + countof(f_manager)] = {};
+ static int count = 0;
+
+ if (!count)
+ { /* initialize only once */
+ bool use_ecc = lib->settings->get_bool(lib->settings,
+ "libstrongswan.plugins.pkcs11.use_ecc", FALSE);
+ add_features(f, f_manager, countof(f_manager), &count);
+ /* private key handling for EC keys is not disabled by use_ecc */
+ add_features(f, f_privkey, countof(f_privkey), &count);
+ if (lib->settings->get_bool(lib->settings,
+ "libstrongswan.plugins.pkcs11.use_pubkey", FALSE))
+ {
+ add_features(f, f_pubkey, countof(f_pubkey) - (use_ecc ? 0 : 1),
+ &count);
+ }
+ if (lib->settings->get_bool(lib->settings,
+ "libstrongswan.plugins.pkcs11.use_hasher", FALSE))
+ {
+ add_features(f, f_hash, countof(f_hash), &count);
+ }
+ if (lib->settings->get_bool(lib->settings,
+ "libstrongswan.plugins.pkcs11.use_rng", FALSE))
+ {
+ add_features(f, f_rng, countof(f_rng), &count);
+ }
+ if (lib->settings->get_bool(lib->settings,
+ "libstrongswan.plugins.pkcs11.use_dh", FALSE))
+ {
+ add_features(f, f_dh, countof(f_dh), &count);
+ if (use_ecc)
+ {
+ add_features(f, f_ecdh, countof(f_ecdh), &count);
+ }
+ }
+ }
+ *features = f;
+ return count;
+}
+
+METHOD(plugin_t, destroy, void,
+ private_pkcs11_plugin_t *this)
+{
+ lib->set(lib, "pkcs11-manager", NULL);
this->manager->destroy(this->manager);
+ this->creds->destroy(this->creds);
this->mutex->destroy(this->mutex);
+ this->handle_events_lock->destroy(this->handle_events_lock);
free(this);
}
@@ -133,52 +286,22 @@ METHOD(plugin_t, destroy, void,
plugin_t *pkcs11_plugin_create()
{
private_pkcs11_plugin_t *this;
- enumerator_t *enumerator;
- pkcs11_library_t *p11;
- CK_SLOT_ID slot;
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
.creds = linked_list_create(),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .handle_events_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
);
this->manager = pkcs11_manager_create((void*)token_event_cb, this);
-
- if (lib->settings->get_bool(lib->settings,
- "libstrongswan.plugins.pkcs11.use_hasher", FALSE))
- {
- lib->crypto->add_hasher(lib->crypto, HASH_MD2, get_name(this),
- (hasher_constructor_t)pkcs11_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_MD5, get_name(this),
- (hasher_constructor_t)pkcs11_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA1, get_name(this),
- (hasher_constructor_t)pkcs11_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA256, get_name(this),
- (hasher_constructor_t)pkcs11_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA384, get_name(this),
- (hasher_constructor_t)pkcs11_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA512, get_name(this),
- (hasher_constructor_t)pkcs11_hasher_create);
- }
-
- lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY, FALSE,
- (builder_function_t)pkcs11_private_key_connect);
- lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, TRUE,
- (builder_function_t)pkcs11_public_key_load);
-
- enumerator = this->manager->create_token_enumerator(this->manager);
- while (enumerator->enumerate(enumerator, &p11, &slot))
- {
- token_event_cb(this, p11, slot, TRUE);
- }
- enumerator->destroy(enumerator);
+ lib->set(lib, "pkcs11-manager", this->manager);
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
index b4cc7a805..b616abc38 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2011 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -19,7 +22,6 @@
#include "pkcs11_manager.h"
#include <debug.h>
-#include <threading/mutex.h>
typedef struct private_pkcs11_private_key_t private_pkcs11_private_key_t;
@@ -39,14 +41,14 @@ struct private_pkcs11_private_key_t {
pkcs11_library_t *lib;
/**
- * Token session
+ * Slot the token is in
*/
- CK_SESSION_HANDLE session;
+ CK_SLOT_ID slot;
/**
- * Mutex to lock session
+ * Token session
*/
- mutex_t *mutex;
+ CK_SESSION_HANDLE session;
/**
* Key object on the token
@@ -72,12 +74,24 @@ struct private_pkcs11_private_key_t {
* References to this key
*/
refcount_t ref;
+
+ /**
+ * Type of this private key
+ */
+ key_type_t type;
};
+/**
+ * Implemented in pkcs11_public_key.c
+ */
+public_key_t *pkcs11_public_key_connect(pkcs11_library_t *p11,
+ int slot, key_type_t type, chunk_t keyid);
+
+
METHOD(private_key_t, get_type, key_type_t,
private_pkcs11_private_key_t *this)
{
- return this->pubkey->get_type(this->pubkey);
+ return this->type;
}
METHOD(private_key_t, get_keysize, int,
@@ -89,18 +103,45 @@ METHOD(private_key_t, get_keysize, int,
/**
* See header.
*/
-CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme)
+CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme,
+ key_type_t type, size_t keylen,
+ hash_algorithm_t *hash)
{
static struct {
signature_scheme_t scheme;
CK_MECHANISM mechanism;
+ key_type_t type;
+ size_t keylen;
+ hash_algorithm_t hash;
} mappings[] = {
- {SIGN_RSA_EMSA_PKCS1_NULL, {CKM_RSA_PKCS, NULL, 0}},
- {SIGN_RSA_EMSA_PKCS1_SHA1, {CKM_SHA1_RSA_PKCS, NULL, 0}},
- {SIGN_RSA_EMSA_PKCS1_SHA256, {CKM_SHA256_RSA_PKCS, NULL, 0}},
- {SIGN_RSA_EMSA_PKCS1_SHA384, {CKM_SHA384_RSA_PKCS, NULL, 0}},
- {SIGN_RSA_EMSA_PKCS1_SHA512, {CKM_SHA512_RSA_PKCS, NULL, 0}},
- {SIGN_RSA_EMSA_PKCS1_MD5, {CKM_MD5_RSA_PKCS, NULL, 0}},
+ {SIGN_RSA_EMSA_PKCS1_NULL, {CKM_RSA_PKCS, NULL, 0},
+ KEY_RSA, 0, HASH_UNKNOWN},
+ {SIGN_RSA_EMSA_PKCS1_SHA1, {CKM_SHA1_RSA_PKCS, NULL, 0},
+ KEY_RSA, 0, HASH_UNKNOWN},
+ {SIGN_RSA_EMSA_PKCS1_SHA256, {CKM_SHA256_RSA_PKCS, NULL, 0},
+ KEY_RSA, 0, HASH_UNKNOWN},
+ {SIGN_RSA_EMSA_PKCS1_SHA384, {CKM_SHA384_RSA_PKCS, NULL, 0},
+ KEY_RSA, 0, HASH_UNKNOWN},
+ {SIGN_RSA_EMSA_PKCS1_SHA512, {CKM_SHA512_RSA_PKCS, NULL, 0},
+ KEY_RSA, 0, HASH_UNKNOWN},
+ {SIGN_RSA_EMSA_PKCS1_MD5, {CKM_MD5_RSA_PKCS, NULL, 0},
+ KEY_RSA, 0, HASH_UNKNOWN},
+ {SIGN_ECDSA_WITH_NULL, {CKM_ECDSA, NULL, 0},
+ KEY_ECDSA, 0, HASH_UNKNOWN},
+ {SIGN_ECDSA_WITH_SHA1_DER, {CKM_ECDSA_SHA1, NULL, 0},
+ KEY_ECDSA, 0, HASH_UNKNOWN},
+ {SIGN_ECDSA_WITH_SHA256_DER, {CKM_ECDSA, NULL, 0},
+ KEY_ECDSA, 0, HASH_SHA256},
+ {SIGN_ECDSA_WITH_SHA384_DER, {CKM_ECDSA, NULL, 0},
+ KEY_ECDSA, 0, HASH_SHA384},
+ {SIGN_ECDSA_WITH_SHA512_DER, {CKM_ECDSA, NULL, 0},
+ KEY_ECDSA, 0, HASH_SHA512},
+ {SIGN_ECDSA_256, {CKM_ECDSA, NULL, 0},
+ KEY_ECDSA, 256, HASH_SHA256},
+ {SIGN_ECDSA_384, {CKM_ECDSA, NULL, 0},
+ KEY_ECDSA, 384, HASH_SHA384},
+ {SIGN_ECDSA_521, {CKM_ECDSA, NULL, 0},
+ KEY_ECDSA, 521, HASH_SHA512},
};
int i;
@@ -108,6 +149,15 @@ CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme)
{
if (mappings[i].scheme == scheme)
{
+ size_t len = mappings[i].keylen;
+ if (mappings[i].type != type || (len && keylen != len))
+ {
+ return NULL;
+ }
+ if (hash)
+ {
+ *hash = mappings[i].hash;
+ }
return &mappings[i].mechanism;
}
}
@@ -141,7 +191,8 @@ CK_MECHANISM_PTR pkcs11_encryption_scheme_to_mech(encryption_scheme_t scheme)
/**
* Reauthenticate to do a signature
*/
-static bool reauth(private_pkcs11_private_key_t *this)
+static bool reauth(private_pkcs11_private_key_t *this,
+ CK_SESSION_HANDLE session)
{
enumerator_t *enumerator;
shared_key_t *shared;
@@ -155,7 +206,7 @@ static bool reauth(private_pkcs11_private_key_t *this)
{
found = TRUE;
pin = shared->get_key(shared);
- rv = this->lib->f->C_Login(this->session, CKU_CONTEXT_SPECIFIC,
+ rv = this->lib->f->C_Login(session, CKU_CONTEXT_SPECIFIC,
pin.ptr, pin.len);
if (rv == CKR_OK)
{
@@ -179,33 +230,61 @@ METHOD(private_key_t, sign, bool,
chunk_t data, chunk_t *signature)
{
CK_MECHANISM_PTR mechanism;
+ CK_SESSION_HANDLE session;
CK_BYTE_PTR buf;
CK_ULONG len;
CK_RV rv;
+ hash_algorithm_t hash_alg;
+ chunk_t hash = chunk_empty;
- mechanism = pkcs11_signature_scheme_to_mech(scheme);
+ mechanism = pkcs11_signature_scheme_to_mech(scheme, this->type,
+ get_keysize(this), &hash_alg);
if (!mechanism)
{
DBG1(DBG_LIB, "signature scheme %N not supported",
signature_scheme_names, scheme);
return FALSE;
}
- this->mutex->lock(this->mutex);
- rv = this->lib->f->C_SignInit(this->session, mechanism, this->object);
- if (this->reauth && !reauth(this))
+ rv = this->lib->f->C_OpenSession(this->slot, CKF_SERIAL_SESSION, NULL, NULL,
+ &session);
+ if (rv != CKR_OK)
{
+ DBG1(DBG_CFG, "opening PKCS#11 session failed: %N", ck_rv_names, rv);
+ return FALSE;
+ }
+ rv = this->lib->f->C_SignInit(session, mechanism, this->object);
+ if (this->reauth && !reauth(this, session))
+ {
+ this->lib->f->C_CloseSession(session);
return FALSE;
}
if (rv != CKR_OK)
{
- this->mutex->unlock(this->mutex);
+ this->lib->f->C_CloseSession(session);
DBG1(DBG_LIB, "C_SignInit() failed: %N", ck_rv_names, rv);
return FALSE;
}
+ if (hash_alg != HASH_UNKNOWN)
+ {
+ hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
+ if (!hasher)
+ {
+ this->lib->f->C_CloseSession(session);
+ return FALSE;
+ }
+ hasher->allocate_hash(hasher, data, &hash);
+ hasher->destroy(hasher);
+ data = hash;
+ }
len = (get_keysize(this) + 7) / 8;
+ if (this->type == KEY_ECDSA)
+ { /* signature is twice the length of the base point order */
+ len *= 2;
+ }
buf = malloc(len);
- rv = this->lib->f->C_Sign(this->session, data.ptr, data.len, buf, &len);
- this->mutex->unlock(this->mutex);
+ rv = this->lib->f->C_Sign(session, data.ptr, data.len, buf, &len);
+ this->lib->f->C_CloseSession(session);
+ chunk_free(&hash);
if (rv != CKR_OK)
{
DBG1(DBG_LIB, "C_Sign() failed: %N", ck_rv_names, rv);
@@ -221,6 +300,7 @@ METHOD(private_key_t, decrypt, bool,
chunk_t crypt, chunk_t *plain)
{
CK_MECHANISM_PTR mechanism;
+ CK_SESSION_HANDLE session;
CK_BYTE_PTR buf;
CK_ULONG len;
CK_RV rv;
@@ -232,22 +312,29 @@ METHOD(private_key_t, decrypt, bool,
encryption_scheme_names, scheme);
return FALSE;
}
- this->mutex->lock(this->mutex);
- rv = this->lib->f->C_DecryptInit(this->session, mechanism, this->object);
- if (this->reauth && !reauth(this))
+ rv = this->lib->f->C_OpenSession(this->slot, CKF_SERIAL_SESSION, NULL, NULL,
+ &session);
+ if (rv != CKR_OK)
{
+ DBG1(DBG_CFG, "opening PKCS#11 session failed: %N", ck_rv_names, rv);
+ return FALSE;
+ }
+ rv = this->lib->f->C_DecryptInit(session, mechanism, this->object);
+ if (this->reauth && !reauth(this, session))
+ {
+ this->lib->f->C_CloseSession(session);
return FALSE;
}
if (rv != CKR_OK)
{
- this->mutex->unlock(this->mutex);
+ this->lib->f->C_CloseSession(session);
DBG1(DBG_LIB, "C_DecryptInit() failed: %N", ck_rv_names, rv);
return FALSE;
}
len = (get_keysize(this) + 7) / 8;
buf = malloc(len);
- rv = this->lib->f->C_Decrypt(this->session, crypt.ptr, crypt.len, buf, &len);
- this->mutex->unlock(this->mutex);
+ rv = this->lib->f->C_Decrypt(session, crypt.ptr, crypt.len, buf, &len);
+ this->lib->f->C_CloseSession(session);
if (rv != CKR_OK)
{
DBG1(DBG_LIB, "C_Decrypt() failed: %N", ck_rv_names, rv);
@@ -294,7 +381,6 @@ METHOD(private_key_t, destroy, void,
{
this->pubkey->destroy(this->pubkey);
}
- this->mutex->destroy(this->mutex);
this->keyid->destroy(this->keyid);
this->lib->f->C_CloseSession(this->session);
free(this);
@@ -311,7 +397,7 @@ static pkcs11_library_t* find_lib(char *module)
pkcs11_library_t *p11, *found = NULL;
CK_SLOT_ID slot;
- manager = pkcs11_manager_get();
+ manager = lib->get(lib, "pkcs11-manager");
if (!manager)
{
return NULL;
@@ -339,7 +425,7 @@ static pkcs11_library_t* find_lib_by_keyid(chunk_t keyid, int *slot)
pkcs11_library_t *p11, *found = NULL;
CK_SLOT_ID current;
- manager = pkcs11_manager_get();
+ manager = lib->get(lib, "pkcs11-manager");
if (!manager)
{
return NULL;
@@ -404,13 +490,11 @@ static bool find_key(private_pkcs11_private_key_t *this, chunk_t keyid)
CK_BBOOL reauth = FALSE;
CK_ATTRIBUTE attr[] = {
{CKA_KEY_TYPE, &type, sizeof(type)},
- {CKA_MODULUS, NULL, 0},
- {CKA_PUBLIC_EXPONENT, NULL, 0},
{CKA_ALWAYS_AUTHENTICATE, &reauth, sizeof(reauth)},
};
enumerator_t *enumerator;
- chunk_t modulus, pubexp;
int count = countof(attr);
+ bool found = FALSE;
/* do not use CKA_ALWAYS_AUTHENTICATE if not supported */
if (!(this->lib->get_features(this->lib) & PKCS11_ALWAYS_AUTH_KEYS))
@@ -421,26 +505,16 @@ static bool find_key(private_pkcs11_private_key_t *this, chunk_t keyid)
this->session, tmpl, countof(tmpl), attr, count);
if (enumerator->enumerate(enumerator, &object))
{
+ this->type = KEY_RSA;
switch (type)
{
+ case CKK_ECDSA:
+ this->type = KEY_ECDSA;
+ /* fall-through */
case CKK_RSA:
- if (attr[1].ulValueLen == -1 || attr[2].ulValueLen == -1)
- {
- DBG1(DBG_CFG, "reading modulus/exponent from PKCS#1 failed");
- break;
- }
- modulus = chunk_create(attr[1].pValue, attr[1].ulValueLen);
- pubexp = chunk_create(attr[2].pValue, attr[2].ulValueLen);
- this->pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
- KEY_RSA, BUILD_RSA_MODULUS, modulus,
- BUILD_RSA_PUB_EXP, pubexp, BUILD_END);
- if (!this->pubkey)
- {
- DBG1(DBG_CFG, "extracting public key from PKCS#11 RSA "
- "private key failed");
- }
this->reauth = reauth;
this->object = object;
+ found = TRUE;
break;
default:
DBG1(DBG_CFG, "PKCS#11 key type %d not supported", type);
@@ -448,7 +522,7 @@ static bool find_key(private_pkcs11_private_key_t *this, chunk_t keyid)
}
}
enumerator->destroy(enumerator);
- return this->pubkey != NULL;
+ return found;
}
/**
@@ -587,7 +661,7 @@ pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args)
return NULL;
}
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
+ this->slot = slot;
this->keyid = identification_create_from_encoding(ID_KEY_ID, keyid);
if (!login(this, slot))
@@ -602,5 +676,13 @@ pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args)
return NULL;
}
+ this->pubkey = pkcs11_public_key_connect(this->lib, slot, this->type,
+ keyid);
+ if (!this->pubkey)
+ {
+ destroy(this);
+ return NULL;
+ }
+
return &this->public;
}
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h
index 428913f0a..6d3a9556e 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.h
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2011 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -46,14 +49,23 @@ struct pkcs11_private_key_t {
*
* @param type type of the key
* @param args builder_part_t argument list
- * @return loaded key, NULL on failure
+ * @return loaded key, NULL on failure
*/
pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args);
/**
* Get the Cryptoki mechanism for a signature scheme.
+ *
+ * Verifies that the given key is usable for this scheme.
+ *
+ * @param scheme signature scheme
+ * @param type key type
+ * @param keylen key length in bits
+ * @param hash hash algorithm to apply first (HASH_UNKNOWN if none)
*/
-CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme);
+CK_MECHANISM_PTR pkcs11_signature_scheme_to_mech(signature_scheme_t scheme,
+ key_type_t type, size_t keylen,
+ hash_algorithm_t *hash);
/**
* Get the Cryptoki mechanism for a encryption scheme.
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
index 8d32d9a3f..d4ec9235d 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2011 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -19,8 +22,10 @@
#include "pkcs11_private_key.h"
#include "pkcs11_manager.h"
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
#include <debug.h>
-#include <threading/mutex.h>
typedef struct private_pkcs11_public_key_t private_pkcs11_public_key_t;
@@ -40,7 +45,7 @@ struct private_pkcs11_public_key_t {
key_type_t type;
/**
- * Key size in bytes
+ * Key size in bits
*/
size_t k;
@@ -65,16 +70,121 @@ struct private_pkcs11_public_key_t {
CK_OBJECT_HANDLE object;
/**
- * Mutex to lock session
- */
- mutex_t *mutex;
-
- /**
* References to this key
*/
refcount_t ref;
};
+/**
+ * Helper function that returns the base point order length in bits of the
+ * given named curve.
+ *
+ * Currently only a subset of defined curves is supported (namely the 5 curves
+ * over Fp recommended by NIST). IKEv2 only supports 3 out of these.
+ *
+ * 0 is returned if the given curve is not supported.
+ */
+static size_t basepoint_order_len(int oid)
+{
+ switch (oid)
+ {
+ case OID_PRIME192V1:
+ return 192;
+ case OID_SECT224R1:
+ return 224;
+ case OID_PRIME256V1:
+ return 256;
+ case OID_SECT384R1:
+ return 384;
+ case OID_SECT521R1:
+ return 521;
+ default:
+ return 0;
+ }
+}
+
+/**
+ * Parses the given ecParameters (ASN.1) and returns the key length.
+ */
+static bool keylen_from_ecparams(chunk_t ecparams, size_t *keylen)
+{
+ if (!asn1_parse_simple_object(&ecparams, ASN1_OID, 0, "named curve"))
+ {
+ return FALSE;
+ }
+ *keylen = basepoint_order_len(asn1_known_oid(ecparams));
+ return *keylen > 0;
+}
+
+/**
+ * ASN.1 definition of a subjectPublicKeyInfo structure when used with ECDSA
+ * we currently only support named curves.
+ */
+static const asn1Object_t pkinfoObjects[] = {
+ { 0, "subjectPublicKeyInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "algorithmIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "algorithm", ASN1_OID, ASN1_BODY }, /* 2 */
+ { 2, "namedCurve", ASN1_OID, ASN1_RAW }, /* 3 */
+ { 1, "subjectPublicKey", ASN1_BIT_STRING, ASN1_BODY }, /* 4 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM 2
+#define PKINFO_SUBJECT_PUBLIC_KEY_NAMEDCURVE 3
+#define PKINFO_SUBJECT_PUBLIC_KEY 4
+
+/**
+ * Extract the DER encoded Parameters and ECPoint from the given DER encoded
+ * subjectPublicKeyInfo.
+ */
+static bool parse_ecdsa_public_key(chunk_t blob, chunk_t *ecparams,
+ chunk_t *ecpoint, size_t *keylen)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+ bool success = FALSE;
+
+ parser = asn1_parser_create(pkinfoObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PKINFO_SUBJECT_PUBLIC_KEY_ALGORITHM:
+ {
+ if (asn1_known_oid(object) != OID_EC_PUBLICKEY)
+ {
+ goto end;
+ }
+ break;
+ }
+ case PKINFO_SUBJECT_PUBLIC_KEY_NAMEDCURVE:
+ {
+ *ecparams = object;
+ if (!keylen_from_ecparams(object, keylen))
+ {
+ goto end;
+ }
+ break;
+ }
+ case PKINFO_SUBJECT_PUBLIC_KEY:
+ {
+ if (object.len > 0 && *object.ptr == 0x00)
+ { /* skip initial bit string octet defining 0 unused bits */
+ object = chunk_skip(object, 1);
+ }
+ *ecpoint = object;
+ break;
+ }
+ }
+ }
+ success = parser->success(parser);
+end:
+ parser->destroy(parser);
+ return success;
+}
+
+
METHOD(public_key_t, get_type, key_type_t,
private_pkcs11_public_key_t *this)
{
@@ -84,7 +194,7 @@ METHOD(public_key_t, get_type, key_type_t,
METHOD(public_key_t, get_keysize, int,
private_pkcs11_public_key_t *this)
{
- return this->k * 8;
+ return this->k;
}
METHOD(public_key_t, verify, bool,
@@ -92,9 +202,13 @@ METHOD(public_key_t, verify, bool,
chunk_t data, chunk_t sig)
{
CK_MECHANISM_PTR mechanism;
+ CK_SESSION_HANDLE session;
CK_RV rv;
+ hash_algorithm_t hash_alg;
+ chunk_t hash = chunk_empty;
- mechanism = pkcs11_signature_scheme_to_mech(scheme);
+ mechanism = pkcs11_signature_scheme_to_mech(scheme, this->type, this->k,
+ &hash_alg);
if (!mechanism)
{
DBG1(DBG_LIB, "signature scheme %N not supported",
@@ -105,17 +219,35 @@ METHOD(public_key_t, verify, bool,
{ /* trim leading zero byte in sig */
sig = chunk_skip(sig, 1);
}
- this->mutex->lock(this->mutex);
- rv = this->lib->f->C_VerifyInit(this->session, mechanism, this->object);
+ rv = this->lib->f->C_OpenSession(this->slot, CKF_SERIAL_SESSION, NULL, NULL,
+ &session);
if (rv != CKR_OK)
{
- this->mutex->unlock(this->mutex);
+ DBG1(DBG_CFG, "opening PKCS#11 session failed: %N", ck_rv_names, rv);
+ return FALSE;
+ }
+ rv = this->lib->f->C_VerifyInit(session, mechanism, this->object);
+ if (rv != CKR_OK)
+ {
+ this->lib->f->C_CloseSession(session);
DBG1(DBG_LIB, "C_VerifyInit() failed: %N", ck_rv_names, rv);
return FALSE;
}
- rv = this->lib->f->C_Verify(this->session, data.ptr, data.len,
- sig.ptr, sig.len);
- this->mutex->unlock(this->mutex);
+ if (hash_alg != HASH_UNKNOWN)
+ {
+ hasher_t *hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
+ if (!hasher)
+ {
+ this->lib->f->C_CloseSession(session);
+ return FALSE;
+ }
+ hasher->allocate_hash(hasher, data, &hash);
+ hasher->destroy(hasher);
+ data = hash;
+ }
+ rv = this->lib->f->C_Verify(session, data.ptr, data.len, sig.ptr, sig.len);
+ this->lib->f->C_CloseSession(session);
+ chunk_free(&hash);
if (rv != CKR_OK)
{
DBG1(DBG_LIB, "C_Verify() failed: %N", ck_rv_names, rv);
@@ -129,6 +261,7 @@ METHOD(public_key_t, encrypt, bool,
chunk_t plain, chunk_t *crypt)
{
CK_MECHANISM_PTR mechanism;
+ CK_SESSION_HANDLE session;
CK_BYTE_PTR buf;
CK_ULONG len;
CK_RV rv;
@@ -140,18 +273,24 @@ METHOD(public_key_t, encrypt, bool,
encryption_scheme_names, scheme);
return FALSE;
}
- this->mutex->lock(this->mutex);
- rv = this->lib->f->C_EncryptInit(this->session, mechanism, this->object);
+ rv = this->lib->f->C_OpenSession(this->slot, CKF_SERIAL_SESSION, NULL, NULL,
+ &session);
if (rv != CKR_OK)
{
- this->mutex->unlock(this->mutex);
+ DBG1(DBG_CFG, "opening PKCS#11 session failed: %N", ck_rv_names, rv);
+ return FALSE;
+ }
+ rv = this->lib->f->C_EncryptInit(session, mechanism, this->object);
+ if (rv != CKR_OK)
+ {
+ this->lib->f->C_CloseSession(session);
DBG1(DBG_LIB, "C_EncryptInit() failed: %N", ck_rv_names, rv);
return FALSE;
}
len = (get_keysize(this) + 7) / 8;
buf = malloc(len);
- rv = this->lib->f->C_Encrypt(this->session, plain.ptr, plain.len, buf, &len);
- this->mutex->unlock(this->mutex);
+ rv = this->lib->f->C_Encrypt(session, plain.ptr, plain.len, buf, &len);
+ this->lib->f->C_CloseSession(session);
if (rv != CKR_OK)
{
DBG1(DBG_LIB, "C_Encrypt() failed: %N", ck_rv_names, rv);
@@ -163,40 +302,119 @@ METHOD(public_key_t, encrypt, bool,
}
/**
+ * Encode ECDSA key using a given encoding type
+ */
+static bool encode_ecdsa(private_pkcs11_public_key_t *this,
+ cred_encoding_type_t type, chunk_t *encoding)
+{
+ enumerator_t *enumerator;
+ bool success = FALSE;
+ CK_ATTRIBUTE attr[] = {
+ {CKA_EC_PARAMS, NULL, 0},
+ {CKA_EC_POINT, NULL, 0},
+ };
+
+ if (type != PUBKEY_SPKI_ASN1_DER && type != PUBKEY_PEM)
+ {
+ return FALSE;
+ }
+
+ enumerator = this->lib->create_object_attr_enumerator(this->lib,
+ this->session, this->object, attr, countof(attr));
+ if (enumerator && enumerator->enumerate(enumerator, NULL) &&
+ attr[0].ulValueLen > 0 && attr[1].ulValueLen > 0)
+ {
+ chunk_t ecparams, ecpoint;
+ ecparams = chunk_create(attr[0].pValue, attr[0].ulValueLen);
+ ecpoint = chunk_create(attr[1].pValue, attr[1].ulValueLen);
+ /* encode as subjectPublicKeyInfo */
+ *encoding = asn1_wrap(ASN1_SEQUENCE, "mm",
+ asn1_wrap(ASN1_SEQUENCE, "mc",
+ asn1_build_known_oid(OID_EC_PUBLICKEY), ecparams),
+ asn1_bitstring("c", ecpoint));
+ success = TRUE;
+ if (type == PUBKEY_PEM)
+ {
+ chunk_t asn1 = *encoding;
+ success = lib->encoding->encode(lib->encoding, PUBKEY_PEM,
+ NULL, encoding, CRED_PART_ECDSA_PUB_ASN1_DER,
+ asn1, CRED_PART_END);
+ chunk_clear(&asn1);
+ }
+ }
+ DESTROY_IF(enumerator);
+ return success;
+}
+
+/**
+ * Compute fingerprint of an ECDSA key
+ */
+static bool fingerprint_ecdsa(private_pkcs11_public_key_t *this,
+ cred_encoding_type_t type, chunk_t *fp)
+{
+ hasher_t *hasher;
+ chunk_t asn1;
+
+ switch (type)
+ {
+ case KEYID_PUBKEY_SHA1:
+ if (!this->lib->get_ck_attribute(this->lib, this->session,
+ this->object, CKA_EC_POINT, &asn1))
+ {
+ return FALSE;
+ }
+ break;
+ case KEYID_PUBKEY_INFO_SHA1:
+ if (!encode_ecdsa(this, PUBKEY_SPKI_ASN1_DER, &asn1))
+ {
+ return FALSE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (!hasher)
+ {
+ chunk_clear(&asn1);
+ return FALSE;
+ }
+ hasher->allocate_hash(hasher, asn1, fp);
+ hasher->destroy(hasher);
+ chunk_clear(&asn1);
+ lib->encoding->cache(lib->encoding, type, this, *fp);
+ return TRUE;
+}
+
+/**
* Encode RSA key using a given encoding type
*/
static bool encode_rsa(private_pkcs11_public_key_t *this,
cred_encoding_type_t type, void *cache, chunk_t *encoding)
{
- CK_RV rv;
+ enumerator_t *enumerator;
bool success = FALSE;
- chunk_t n, e;
CK_ATTRIBUTE attr[] = {
{CKA_MODULUS, NULL, 0},
{CKA_PUBLIC_EXPONENT, NULL, 0},
};
- rv = this->lib->f->C_GetAttributeValue(this->session, this->object,
- attr, countof(attr));
- if (rv != CKR_OK ||
- attr[0].ulValueLen == 0 || attr[0].ulValueLen == -1 ||
- attr[1].ulValueLen == 0 || attr[1].ulValueLen == -1)
- {
- return FALSE;
- }
- attr[0].pValue = malloc(attr[0].ulValueLen);
- attr[1].pValue = malloc(attr[1].ulValueLen);
- rv = this->lib->f->C_GetAttributeValue(this->session, this->object,
- attr, countof(attr));
- if (rv == CKR_OK)
+ enumerator = this->lib->create_object_attr_enumerator(this->lib,
+ this->session, this->object, attr, countof(attr));
+ if (enumerator && enumerator->enumerate(enumerator, NULL) &&
+ attr[0].ulValueLen > 0 && attr[1].ulValueLen > 0)
{
+ chunk_t n, e;
n = chunk_create(attr[0].pValue, attr[0].ulValueLen);
+ if (n.ptr[0] & 0x80)
+ { /* add leading 0x00, encoders expect it already like this */
+ n = chunk_cata("cc", chunk_from_chars(0x00), n);
+ }
e = chunk_create(attr[1].pValue, attr[1].ulValueLen);
success = lib->encoding->encode(lib->encoding, type, cache, encoding,
CRED_PART_RSA_MODULUS, n, CRED_PART_RSA_PUB_EXP, e, CRED_PART_END);
}
- free(attr[0].pValue);
- free(attr[1].pValue);
+ DESTROY_IF(enumerator);
return success;
}
@@ -208,6 +426,8 @@ METHOD(public_key_t, get_encoding, bool,
{
case KEY_RSA:
return encode_rsa(this, type, NULL, encoding);
+ case KEY_ECDSA:
+ return encode_ecdsa(this, type, encoding);
default:
return FALSE;
}
@@ -224,6 +444,8 @@ METHOD(public_key_t, get_fingerprint, bool,
{
case KEY_RSA:
return encode_rsa(this, type, this, fp);
+ case KEY_ECDSA:
+ return fingerprint_ecdsa(this, type, fp);
default:
return FALSE;
}
@@ -243,7 +465,6 @@ METHOD(public_key_t, destroy, void,
{
lib->encoding->clear_cache(lib->encoding, this);
this->lib->f->C_CloseSession(this->session);
- this->mutex->destroy(this->mutex);
free(this);
}
}
@@ -278,7 +499,6 @@ static private_pkcs11_public_key_t *create(key_type_t type, size_t k,
.slot = slot,
.session = session,
.object = object,
- .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.ref = 1,
);
@@ -288,7 +508,8 @@ static private_pkcs11_public_key_t *create(key_type_t type, size_t k,
/**
* Find a key object, including PKCS11 library and slot
*/
-static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e)
+static private_pkcs11_public_key_t* find_key(key_type_t type, size_t keylen,
+ CK_ATTRIBUTE_PTR tmpl, int count)
{
private_pkcs11_public_key_t *this = NULL;
pkcs11_manager_t *manager;
@@ -296,7 +517,7 @@ static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e)
pkcs11_library_t *p11;
CK_SLOT_ID slot;
- manager = pkcs11_manager_get();
+ manager = lib->get(lib, "pkcs11-manager");
if (!manager)
{
return NULL;
@@ -305,14 +526,6 @@ static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e)
enumerator = manager->create_token_enumerator(manager);
while (enumerator->enumerate(enumerator, &p11, &slot))
{
- CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
- CK_KEY_TYPE type = CKK_RSA;
- CK_ATTRIBUTE tmpl[] = {
- {CKA_CLASS, &class, sizeof(class)},
- {CKA_KEY_TYPE, &type, sizeof(type)},
- {CKA_MODULUS, n.ptr, n.len},
- {CKA_PUBLIC_EXPONENT, e.ptr, e.len},
- };
CK_OBJECT_HANDLE object;
CK_SESSION_HANDLE session;
CK_RV rv;
@@ -324,11 +537,11 @@ static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e)
DBG1(DBG_CFG, "opening PKCS#11 session failed: %N", ck_rv_names, rv);
continue;
}
- keys = p11->create_object_enumerator(p11, session,
- tmpl, countof(tmpl), NULL, 0);
+ keys = p11->create_object_enumerator(p11, session, tmpl, count,
+ NULL, 0);
if (keys->enumerate(keys, &object))
{
- this = create(KEY_RSA, n.len, p11, slot, session, object);
+ this = create(type, keylen, p11, slot, session, object);
keys->destroy(keys);
break;
}
@@ -340,9 +553,46 @@ static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e)
}
/**
+ * Find an RSA key object
+ */
+static private_pkcs11_public_key_t* find_rsa_key(chunk_t n, chunk_t e,
+ size_t keylen)
+{
+ CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
+ CK_KEY_TYPE type = CKK_RSA;
+ CK_ATTRIBUTE tmpl[] = {
+ {CKA_CLASS, &class, sizeof(class)},
+ {CKA_KEY_TYPE, &type, sizeof(type)},
+ {CKA_MODULUS, n.ptr, n.len},
+ {CKA_PUBLIC_EXPONENT, e.ptr, e.len},
+ };
+ return find_key(KEY_RSA, keylen, tmpl, countof(tmpl));
+}
+
+/**
+ * Find an ECDSA key object
+ */
+static private_pkcs11_public_key_t* find_ecdsa_key(chunk_t ecparams,
+ chunk_t ecpoint,
+ size_t keylen)
+{
+ CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
+ CK_KEY_TYPE type = CKK_ECDSA;
+ CK_ATTRIBUTE tmpl[] = {
+ {CKA_CLASS, &class, sizeof(class)},
+ {CKA_KEY_TYPE, &type, sizeof(type)},
+ {CKA_EC_PARAMS, ecparams.ptr, ecparams.len},
+ {CKA_EC_POINT, ecpoint.ptr, ecpoint.len},
+ };
+ return find_key(KEY_ECDSA, keylen, tmpl, countof(tmpl));
+}
+
+/**
* Create a key object in a suitable token session
*/
-static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e)
+static private_pkcs11_public_key_t* create_key(key_type_t type, size_t keylen,
+ CK_MECHANISM_TYPE_PTR mechanisms, int mcount,
+ CK_ATTRIBUTE_PTR tmpl, int count)
{
private_pkcs11_public_key_t *this = NULL;
pkcs11_manager_t *manager;
@@ -350,7 +600,7 @@ static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e)
pkcs11_library_t *p11;
CK_SLOT_ID slot;
- manager = pkcs11_manager_get();
+ manager = lib->get(lib, "pkcs11-manager");
if (!manager)
{
return NULL;
@@ -361,14 +611,6 @@ static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e)
{
CK_MECHANISM_TYPE mech;
CK_MECHANISM_INFO info;
- CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
- CK_KEY_TYPE type = CKK_RSA;
- CK_ATTRIBUTE tmpl[] = {
- {CKA_CLASS, &class, sizeof(class)},
- {CKA_KEY_TYPE, &type, sizeof(type)},
- {CKA_MODULUS, n.ptr, n.len},
- {CKA_PUBLIC_EXPONENT, e.ptr, e.len}
- };
CK_OBJECT_HANDLE object;
CK_SESSION_HANDLE session;
CK_RV rv;
@@ -376,21 +618,23 @@ static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e)
mechs = p11->create_mechanism_enumerator(p11, slot);
while (mechs->enumerate(mechs, &mech, &info))
{
+ bool found = FALSE;
+ int i;
if (!(info.flags & CKF_VERIFY))
{
continue;
}
- switch (mech)
+ for (i = 0; i < mcount; i++)
{
- case CKM_RSA_PKCS:
- case CKM_SHA1_RSA_PKCS:
- case CKM_SHA256_RSA_PKCS:
- case CKM_SHA384_RSA_PKCS:
- case CKM_SHA512_RSA_PKCS:
- case CKM_MD5_RSA_PKCS:
+ if (mechanisms[i] == mech)
+ {
+ found = TRUE;
break;
- default:
- continue;
+ }
+ }
+ if (!found)
+ {
+ continue;
}
rv = p11->f->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL,
&session);
@@ -400,20 +644,21 @@ static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e)
ck_rv_names, rv);
continue;
}
- rv = p11->f->C_CreateObject(session, tmpl, countof(tmpl), &object);
+ rv = p11->f->C_CreateObject(session, tmpl, count, &object);
if (rv == CKR_OK)
{
- this = create(KEY_RSA, n.len, p11, slot, session, object);
- DBG2(DBG_CFG, "created RSA public key on token '%s':%d ",
- p11->get_name(p11), slot);
- break;
+ this = create(type, keylen, p11, slot, session, object);
+ DBG2(DBG_CFG, "created %N public key on token '%s':%d ",
+ key_type_names, type, p11->get_name(p11), slot);
}
else
{
- DBG1(DBG_CFG, "creating RSA public key on token '%s':%d "
- "failed: %N", p11->get_name(p11), slot, ck_rv_names, rv);
+ DBG1(DBG_CFG, "creating %N public key on token '%s':%d "
+ "failed: %N", key_type_names, type, p11->get_name(p11),
+ slot, ck_rv_names, rv);
p11->f->C_CloseSession(session);
}
+ break;
}
mechs->destroy(mechs);
if (this)
@@ -426,18 +671,71 @@ static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e)
}
/**
+ * Create an RSA key object in a suitable token session
+ */
+static private_pkcs11_public_key_t* create_rsa_key(chunk_t n, chunk_t e,
+ size_t keylen)
+{
+ CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
+ CK_KEY_TYPE type = CKK_RSA;
+ CK_ATTRIBUTE tmpl[] = {
+ {CKA_CLASS, &class, sizeof(class)},
+ {CKA_KEY_TYPE, &type, sizeof(type)},
+ {CKA_MODULUS, n.ptr, n.len},
+ {CKA_PUBLIC_EXPONENT, e.ptr, e.len},
+ };
+ CK_MECHANISM_TYPE mechs[] = {
+ CKM_RSA_PKCS,
+ CKM_SHA1_RSA_PKCS,
+ CKM_SHA256_RSA_PKCS,
+ CKM_SHA384_RSA_PKCS,
+ CKM_SHA512_RSA_PKCS,
+ CKM_MD5_RSA_PKCS,
+ };
+ return create_key(KEY_RSA, keylen, mechs, countof(mechs), tmpl,
+ countof(tmpl));
+}
+
+/**
+ * Create an ECDSA key object in a suitable token session
+ */
+static private_pkcs11_public_key_t* create_ecdsa_key(chunk_t ecparams,
+ chunk_t ecpoint,
+ size_t keylen)
+{
+ CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
+ CK_KEY_TYPE type = CKK_ECDSA;
+ CK_ATTRIBUTE tmpl[] = {
+ {CKA_CLASS, &class, sizeof(class)},
+ {CKA_KEY_TYPE, &type, sizeof(type)},
+ {CKA_EC_PARAMS, ecparams.ptr, ecparams.len},
+ {CKA_EC_POINT, ecpoint.ptr, ecpoint.len},
+ };
+ CK_MECHANISM_TYPE mechs[] = {
+ CKM_ECDSA,
+ CKM_ECDSA_SHA1,
+ };
+ return create_key(KEY_ECDSA, keylen, mechs,
+ countof(mechs), tmpl, countof(tmpl));
+}
+
+/**
* See header
*/
pkcs11_public_key_t *pkcs11_public_key_load(key_type_t type, va_list args)
{
private_pkcs11_public_key_t *this;
- chunk_t n, e;
+ chunk_t n, e, blob;
+ size_t keylen = 0;
- n = e = chunk_empty;
+ n = e = blob = chunk_empty;
while (TRUE)
{
switch (va_arg(args, builder_part_t))
{
+ case BUILD_BLOB_ASN1_DER:
+ blob = va_arg(args, chunk_t);
+ continue;
case BUILD_RSA_MODULUS:
n = va_arg(args, chunk_t);
continue;
@@ -457,17 +755,152 @@ pkcs11_public_key_t *pkcs11_public_key_load(key_type_t type, va_list args)
{ /* trim leading zero byte in modulus */
n = chunk_skip(n, 1);
}
- this = find_rsa_key(n, e);
+ keylen = n.len * 8;
+ this = find_rsa_key(n, e, keylen);
if (this)
{
return &this->public;
}
- this = create_rsa_key(n, e);
+ this = create_rsa_key(n, e, keylen);
if (this)
{
return &this->public;
}
}
+ else if (type == KEY_ECDSA && blob.ptr)
+ {
+ chunk_t ecparams, ecpoint;
+ ecparams = ecpoint = chunk_empty;
+ if (parse_ecdsa_public_key(blob, &ecparams, &ecpoint, &keylen))
+ {
+ this = find_ecdsa_key(ecparams, ecpoint, keylen);
+ if (this)
+ {
+ return &this->public;
+ }
+ this = create_ecdsa_key(ecparams, ecpoint, keylen);
+ if (this)
+ {
+ return &this->public;
+ }
+ }
+ }
return NULL;
}
+static private_pkcs11_public_key_t *find_key_by_keyid(pkcs11_library_t *p11,
+ int slot, key_type_t key_type,
+ chunk_t keyid)
+{
+ CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
+ CK_KEY_TYPE type;
+ CK_ATTRIBUTE tmpl[] = {
+ {CKA_CLASS, &class, sizeof(class)},
+ {CKA_ID, keyid.ptr, keyid.len},
+ {CKA_KEY_TYPE, &type, sizeof(type)},
+ };
+ CK_OBJECT_HANDLE object;
+ CK_ATTRIBUTE attr[] = {
+ {CKA_KEY_TYPE, &type, sizeof(type)},
+ };
+ CK_SESSION_HANDLE session;
+ CK_RV rv;
+ enumerator_t *enumerator;
+ int count = countof(tmpl);
+ bool found = FALSE;
+ size_t keylen;
+
+ switch (key_type)
+ {
+ case KEY_RSA:
+ type = CKK_RSA;
+ break;
+ case KEY_ECDSA:
+ type = CKK_ECDSA;
+ break;
+ default:
+ /* don't specify key type on KEY_ANY */
+ count--;
+ break;
+ }
+
+ rv = p11->f->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL, &session);
+ if (rv != CKR_OK)
+ {
+ DBG1(DBG_CFG, "opening public key session on '%s':%d failed: %N",
+ p11->get_name(p11), slot, ck_rv_names, rv);
+ return NULL;
+ }
+
+ enumerator = p11->create_object_enumerator(p11, session, tmpl, count, attr,
+ countof(attr));
+ if (enumerator->enumerate(enumerator, &object))
+ {
+ switch (type)
+ {
+ case CKK_ECDSA:
+ {
+ chunk_t ecparams;
+ if (p11->get_ck_attribute(p11, session, object, CKA_EC_PARAMS,
+ &ecparams) &&
+ keylen_from_ecparams(ecparams, &keylen))
+ {
+ chunk_free(&ecparams);
+ key_type = KEY_ECDSA;
+ found = TRUE;
+ }
+ break;
+ }
+ case CKK_RSA:
+ {
+ chunk_t n;
+ if (p11->get_ck_attribute(p11, session, object, CKA_MODULUS,
+ &n) && n.len > 0)
+ {
+ keylen = n.len * 8;
+ chunk_free(&n);
+ key_type = KEY_RSA;
+ found = TRUE;
+ }
+ break;
+ }
+ default:
+ DBG1(DBG_CFG, "PKCS#11 key type %d not supported", type);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (found)
+ {
+ return create(key_type, keylen, p11, slot, session, object);
+ }
+ p11->f->C_CloseSession(session);
+ return NULL;
+}
+
+/**
+ * Find a public key on the given token with a specific keyid.
+ *
+ * Used by pkcs11_private_key_t.
+ *
+ * TODO: if no public key is found, we should perhaps search for a certificate
+ * with the given keyid and extract the key from there
+ *
+ * @param p11 PKCS#11 module
+ * @param slot slot id
+ * @param type type of the key
+ * @param keyid key id
+ */
+pkcs11_public_key_t *pkcs11_public_key_connect(pkcs11_library_t *p11,
+ int slot, key_type_t type, chunk_t keyid)
+{
+ private_pkcs11_public_key_t *this;
+
+ this = find_key_by_keyid(p11, slot, type, keyid);
+ if (!this)
+ {
+ return NULL;
+ }
+ return &this->public;
+}
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h
index 4fd94620e..b3ea725a2 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.h
@@ -42,7 +42,7 @@ struct pkcs11_public_key_t {
*
* @param type type of the key
* @param args builder_part_t argument list
- * @return loaded key, NULL on failure
+ * @return loaded key, NULL on failure
*/
pkcs11_public_key_t *pkcs11_public_key_load(key_type_t type, va_list args);
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c
new file mode 100644
index 000000000..45cf0b7c2
--- /dev/null
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2011 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 "pkcs11_rng.h"
+
+#include <debug.h>
+
+#include "pkcs11_manager.h"
+
+typedef struct private_pkcs11_rng_t private_pkcs11_rng_t;
+
+/**
+ * Private data of an pkcs11_rng_t object.
+ */
+struct private_pkcs11_rng_t {
+
+ /**
+ * Public interface.
+ */
+ pkcs11_rng_t public;
+
+ /**
+ * PKCS#11 library
+ */
+ pkcs11_library_t *lib;
+
+ /**
+ * Mechanism for this rng
+ */
+ CK_SESSION_HANDLE session;
+
+};
+
+METHOD(rng_t, get_bytes, void,
+ private_pkcs11_rng_t *this, size_t bytes, u_int8_t *buffer)
+{
+ CK_RV rv;
+ rv = this->lib->f->C_GenerateRandom(this->session, buffer, bytes);
+ if (rv != CKR_OK)
+ {
+ DBG1(DBG_CFG, "C_GenerateRandom() failed: %N", ck_rv_names, rv);
+ abort();
+ }
+}
+
+METHOD(rng_t, allocate_bytes, void,
+ private_pkcs11_rng_t *this, size_t bytes, chunk_t *chunk)
+{
+ *chunk = chunk_alloc(bytes);
+ get_bytes(this, chunk->len, chunk->ptr);
+}
+
+METHOD(rng_t, destroy, void,
+ private_pkcs11_rng_t *this)
+{
+ this->lib->f->C_CloseSession(this->session);
+ free(this);
+}
+
+/**
+ * Find a token with its own RNG
+ */
+static pkcs11_library_t *find_token(CK_SESSION_HANDLE *session)
+{
+ enumerator_t *tokens;
+ pkcs11_manager_t *manager;
+ pkcs11_library_t *current, *found = NULL;
+ CK_SLOT_ID slot;
+
+ manager = lib->get(lib, "pkcs11-manager");
+ if (!manager)
+ {
+ return NULL;
+ }
+ tokens = manager->create_token_enumerator(manager);
+ while (tokens->enumerate(tokens, &current, &slot))
+ {
+ CK_TOKEN_INFO info;
+ CK_RV rv;
+ rv = current->f->C_GetTokenInfo(slot, &info);
+ if (rv != CKR_OK)
+ {
+ continue;
+ }
+ if (info.flags & CKF_RNG)
+ {
+ if (current->f->C_OpenSession(slot, CKF_SERIAL_SESSION,
+ NULL, NULL, session) == CKR_OK)
+ {
+ found = current;
+ break;
+ }
+ }
+ }
+ tokens->destroy(tokens);
+ return found;
+}
+
+/*
+ * Described in header.
+ */
+pkcs11_rng_t *pkcs11_rng_create(rng_quality_t quality)
+{
+ private_pkcs11_rng_t *this;
+
+ INIT(this,
+ .public = {
+ .rng = {
+ .get_bytes = _get_bytes,
+ .allocate_bytes = _allocate_bytes,
+ .destroy = _destroy,
+ },
+ },
+ );
+
+ this->lib = find_token(&this->session);
+ if (!this->lib)
+ {
+ free(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_rng.h b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.h
new file mode 100644
index 000000000..998631f7e
--- /dev/null
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 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 pkcs11_rng pkcs11_rng
+ * @{ @ingroup pkcs11
+ */
+
+#ifndef PKCS11_RNG_H_
+#define PKCS11_RNG_H_
+
+typedef struct pkcs11_rng_t pkcs11_rng_t;
+
+#include <library.h>
+
+/**
+ * rng_t implementation via PKCS#11
+ */
+struct pkcs11_rng_t {
+
+ /**
+ * Implements rng_t.
+ */
+ rng_t rng;
+};
+
+/**
+ * Creates a pkcs11_rng_t instance.
+ *
+ * @param quality required quality of randomness
+ * @return created pkcs11_rng_t
+ */
+pkcs11_rng_t *pkcs11_rng_create(rng_quality_t quality);
+
+#endif /** PKCS11_RNG_H_ @} */
diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.am b/src/libstrongswan/plugins/pkcs8/Makefile.am
new file mode 100644
index 000000000..bcaf2c6a5
--- /dev/null
+++ b/src/libstrongswan/plugins/pkcs8/Makefile.am
@@ -0,0 +1,16 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-pkcs8.la
+else
+plugin_LTLIBRARIES = libstrongswan-pkcs8.la
+endif
+
+libstrongswan_pkcs8_la_SOURCES = \
+ pkcs8_plugin.h pkcs8_plugin.c \
+ pkcs8_builder.h pkcs8_builder.c
+
+libstrongswan_pkcs8_la_LDFLAGS = -module -avoid-version
diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.in b/src/libstrongswan/plugins/pkcs8/Makefile.in
new file mode 100644
index 000000000..2b9c6cf95
--- /dev/null
+++ b/src/libstrongswan/plugins/pkcs8/Makefile.in
@@ -0,0 +1,611 @@
+# 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/libstrongswan/plugins/pkcs8
+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_pkcs8_la_LIBADD =
+am_libstrongswan_pkcs8_la_OBJECTS = pkcs8_plugin.lo pkcs8_builder.lo
+libstrongswan_pkcs8_la_OBJECTS = $(am_libstrongswan_pkcs8_la_OBJECTS)
+libstrongswan_pkcs8_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libstrongswan_pkcs8_la_LDFLAGS) $(LDFLAGS) -o $@
+@MONOLITHIC_FALSE@am_libstrongswan_pkcs8_la_rpath = -rpath \
+@MONOLITHIC_FALSE@ $(plugindir)
+@MONOLITHIC_TRUE@am_libstrongswan_pkcs8_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_pkcs8_la_SOURCES)
+DIST_SOURCES = $(libstrongswan_pkcs8_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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
+AM_CFLAGS = -rdynamic
+@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-pkcs8.la
+@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-pkcs8.la
+libstrongswan_pkcs8_la_SOURCES = \
+ pkcs8_plugin.h pkcs8_plugin.c \
+ pkcs8_builder.h pkcs8_builder.c
+
+libstrongswan_pkcs8_la_LDFLAGS = -module -avoid-version
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/pkcs8/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libstrongswan/plugins/pkcs8/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-pkcs8.la: $(libstrongswan_pkcs8_la_OBJECTS) $(libstrongswan_pkcs8_la_DEPENDENCIES)
+ $(libstrongswan_pkcs8_la_LINK) $(am_libstrongswan_pkcs8_la_rpath) $(libstrongswan_pkcs8_la_OBJECTS) $(libstrongswan_pkcs8_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs8_builder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs8_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/libstrongswan/plugins/pkcs8/pkcs8_builder.c b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c
new file mode 100644
index 000000000..346240ae1
--- /dev/null
+++ b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.c
@@ -0,0 +1,632 @@
+/*
+ * Copyright (C) 2012 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 "pkcs8_builder.h"
+
+#include <debug.h>
+#include <asn1/oid.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <credentials/keys/private_key.h>
+
+/**
+ * ASN.1 definition of a privateKeyInfo structure
+ */
+static const asn1Object_t pkinfoObjects[] = {
+ { 0, "privateKeyInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
+ { 1, "privateKeyAlgorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
+ { 1, "privateKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
+ { 1, "attributes", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 5 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PKINFO_PRIVATE_KEY_ALGORITHM 2
+#define PKINFO_PRIVATE_KEY 3
+
+/**
+ * Load a generic private key from an ASN.1 encoded blob
+ */
+static private_key_t *parse_private_key(chunk_t blob)
+{
+ asn1_parser_t *parser;
+ chunk_t object, params = chunk_empty;
+ int objectID;
+ private_key_t *key = NULL;
+ key_type_t type = KEY_ANY;
+
+ parser = asn1_parser_create(pkinfoObjects, blob);
+ parser->set_flags(parser, FALSE, TRUE);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PKINFO_PRIVATE_KEY_ALGORITHM:
+ {
+ int oid = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser) + 1, &params);
+
+ switch (oid)
+ {
+ case OID_RSA_ENCRYPTION:
+ type = KEY_RSA;
+ break;
+ case OID_EC_PUBLICKEY:
+ type = KEY_ECDSA;
+ break;
+ default:
+ /* key type not supported */
+ goto end;
+ }
+ break;
+ }
+ case PKINFO_PRIVATE_KEY:
+ {
+ DBG2(DBG_ASN, "-- > --");
+ if (params.ptr)
+ {
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
+ type, BUILD_BLOB_ALGID_PARAMS,
+ params, BUILD_BLOB_ASN1_DER,
+ object, BUILD_END);
+ }
+ else
+ {
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
+ type, BUILD_BLOB_ASN1_DER, object,
+ BUILD_END);
+ }
+ DBG2(DBG_ASN, "-- < --");
+ break;
+ }
+ }
+ }
+
+end:
+ parser->destroy(parser);
+ return key;
+}
+
+/**
+ * Verify padding of decrypted blob.
+ * Length of blob is adjusted accordingly.
+ */
+static bool verify_padding(chunk_t *blob)
+{
+ u_int8_t padding, count;
+
+ padding = count = blob->ptr[blob->len - 1];
+ if (padding > 8)
+ {
+ return FALSE;
+ }
+ for (; blob->len && count; --blob->len, --count)
+ {
+ if (blob->ptr[blob->len - 1] != padding)
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Prototype for key derivation functions.
+ */
+typedef void (*kdf_t)(void *generator, chunk_t password, chunk_t salt,
+ u_int64_t iterations, chunk_t key);
+
+/**
+ * Try to decrypt the given blob with multiple passwords using the given
+ * key derivation function. keymat is where the kdf function writes the key
+ * to, key and iv point to the actual keys and initialization vectors resp.
+ */
+static private_key_t *decrypt_private_key(chunk_t blob,
+ encryption_algorithm_t encr, size_t key_len, kdf_t kdf,
+ void *generator, chunk_t salt, u_int64_t iterations,
+ chunk_t keymat, chunk_t key, chunk_t iv)
+{
+ enumerator_t *enumerator;
+ shared_key_t *shared;
+ crypter_t *crypter;
+ private_key_t *private_key = NULL;
+
+ crypter = lib->crypto->create_crypter(lib->crypto, encr, key_len);
+ if (!crypter)
+ {
+ DBG1(DBG_ASN, " %N encryption algorithm not available",
+ encryption_algorithm_names, encr);
+ return NULL;
+ }
+ if (blob.len % crypter->get_block_size(crypter))
+ {
+ DBG1(DBG_ASN, " data size is not a multiple of block size");
+ crypter->destroy(crypter);
+ return NULL;
+ }
+
+ enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
+ SHARED_PRIVATE_KEY_PASS, NULL, NULL);
+ while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
+ {
+ chunk_t decrypted;
+
+ kdf(generator, shared->get_key(shared), salt, iterations, keymat);
+
+ crypter->set_key(crypter, key);
+ crypter->decrypt(crypter, blob, iv, &decrypted);
+ if (verify_padding(&decrypted))
+ {
+ private_key = parse_private_key(decrypted);
+ if (private_key)
+ {
+ chunk_clear(&decrypted);
+ break;
+ }
+ }
+ chunk_free(&decrypted);
+ }
+ enumerator->destroy(enumerator);
+ crypter->destroy(crypter);
+
+ return private_key;
+}
+
+/**
+ * Function F of PBKDF2
+ */
+static void pbkdf2_f(chunk_t block, prf_t *prf, chunk_t seed,
+ u_int64_t iterations)
+{
+ chunk_t u;
+ u_int64_t i;
+
+ u = chunk_alloca(prf->get_block_size(prf));
+ prf->get_bytes(prf, seed, u.ptr);
+ memcpy(block.ptr, u.ptr, block.len);
+
+ for (i = 1; i < iterations; i++)
+ {
+ prf->get_bytes(prf, u, u.ptr);
+ memxor(block.ptr, u.ptr, block.len);
+ }
+}
+
+/**
+ * PBKDF2 key derivation function
+ */
+static void pbkdf2(prf_t *prf, chunk_t password, chunk_t salt,
+ u_int64_t iterations, chunk_t key)
+{
+ chunk_t keymat, block, seed;
+ size_t blocks;
+ u_int32_t i = 0, *ni;
+
+ prf->set_key(prf, password);
+
+ block.len = prf->get_block_size(prf);
+ blocks = (key.len - 1) / block.len + 1;
+ keymat = chunk_alloca(blocks * block.len);
+
+ seed = chunk_cata("cc", salt, chunk_from_thing(i));
+ ni = (u_int32_t*)(seed.ptr + salt.len);
+
+ for (; i < blocks; i++)
+ {
+ *ni = htonl(i + 1);
+ block.ptr = keymat.ptr + (i * block.len);
+ pbkdf2_f(block, prf, seed, iterations);
+ }
+
+ memcpy(key.ptr, keymat.ptr, key.len);
+}
+
+/**
+ * Decrypt an encrypted PKCS#8 encoded private key according to PBES2
+ */
+static private_key_t *decrypt_private_key_pbes2(chunk_t blob,
+ encryption_algorithm_t encr, size_t key_len,
+ chunk_t iv, pseudo_random_function_t prf_func,
+ chunk_t salt, u_int64_t iterations)
+{
+ private_key_t *private_key;
+ prf_t *prf;
+ chunk_t key;
+
+ prf = lib->crypto->create_prf(lib->crypto, prf_func);
+ if (!prf)
+ {
+ DBG1(DBG_ASN, " %N prf algorithm not available",
+ pseudo_random_function_names, prf_func);
+ return NULL;
+ }
+
+ key = chunk_alloca(key_len);
+
+ private_key = decrypt_private_key(blob, encr, key_len, (kdf_t)pbkdf2, prf,
+ salt, iterations, key, key, iv);
+
+ prf->destroy(prf);
+ return private_key;
+}
+
+/**
+ * PBKDF1 key derivation function
+ */
+static void pbkdf1(hasher_t *hasher, chunk_t password, chunk_t salt,
+ u_int64_t iterations, chunk_t key)
+{
+ chunk_t hash;
+ u_int64_t i;
+
+ hash = chunk_alloca(hasher->get_hash_size(hasher));
+ hasher->get_hash(hasher, password, NULL);
+ hasher->get_hash(hasher, salt, hash.ptr);
+
+ for (i = 1; i < iterations; i++)
+ {
+ hasher->get_hash(hasher, hash, hash.ptr);
+ }
+
+ memcpy(key.ptr, hash.ptr, key.len);
+}
+
+/**
+ * Decrypt an encrypted PKCS#8 encoded private key according to PBES1
+ */
+static private_key_t *decrypt_private_key_pbes1(chunk_t blob,
+ encryption_algorithm_t encr, size_t key_len,
+ hash_algorithm_t hash, chunk_t salt,
+ u_int64_t iterations)
+{
+ private_key_t *private_key = NULL;
+ hasher_t *hasher = NULL;
+ chunk_t keymat, key, iv;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, hash);
+ if (!hasher)
+ {
+ DBG1(DBG_ASN, " %N hash algorithm not available",
+ hash_algorithm_names, hash);
+ goto end;
+ }
+ if (hasher->get_hash_size(hasher) < key_len)
+ {
+ goto end;
+ }
+
+ keymat = chunk_alloca(key_len * 2);
+ key.len = key_len;
+ key.ptr = keymat.ptr;
+ iv.len = key_len;
+ iv.ptr = keymat.ptr + key_len;
+
+ private_key = decrypt_private_key(blob, encr, key_len, (kdf_t)pbkdf1,
+ hasher, salt, iterations, keymat,
+ key, iv);
+
+end:
+ DESTROY_IF(hasher);
+ return private_key;
+}
+
+/**
+ * Parse an ASN1_INTEGER to a u_int64_t.
+ */
+static u_int64_t parse_asn1_integer_uint64(chunk_t blob)
+{
+ u_int64_t val = 0;
+ int i;
+
+ for (i = 0; i < blob.len; i++)
+ { /* if it is longer than 8 bytes, we just use the 8 LSBs */
+ val <<= 8;
+ val |= (u_int64_t)blob.ptr[i];
+ }
+ return val;
+}
+
+/**
+ * ASN.1 definition of a PBKDF2-params structure
+ * The salt is actually a CHOICE and could be an AlgorithmIdentifier from
+ * PBKDF2-SaltSources (but as per RFC 2898 that's for future versions).
+ */
+static const asn1Object_t pbkdf2ParamsObjects[] = {
+ { 0, "PBKDF2-params", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "salt", ASN1_OCTET_STRING, ASN1_BODY }, /* 1 */
+ { 1, "iterationCount",ASN1_INTEGER, ASN1_BODY }, /* 2 */
+ { 1, "keyLength", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 3 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
+ { 1, "prf", ASN1_EOC, ASN1_DEF|ASN1_RAW }, /* 5 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PBKDF2_SALT 1
+#define PBKDF2_ITERATION_COUNT 2
+#define PBKDF2_KEY_LENGTH 3
+#define PBKDF2_PRF 5
+
+/**
+ * Parse a PBKDF2-params structure
+ */
+static void parse_pbkdf2_params(chunk_t blob, chunk_t *salt,
+ u_int64_t *iterations, size_t *key_len,
+ pseudo_random_function_t *prf)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+
+ parser = asn1_parser_create(pbkdf2ParamsObjects, blob);
+
+ *key_len = 0; /* key_len is optional */
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PBKDF2_SALT:
+ {
+ *salt = object;
+ break;
+ }
+ case PBKDF2_ITERATION_COUNT:
+ {
+ *iterations = parse_asn1_integer_uint64(object);
+ break;
+ }
+ case PBKDF2_KEY_LENGTH:
+ {
+ *key_len = (size_t)parse_asn1_integer_uint64(object);
+ break;
+ }
+ case PBKDF2_PRF:
+ { /* defaults to id-hmacWithSHA1 */
+ *prf = PRF_HMAC_SHA1;
+ break;
+ }
+ }
+ }
+
+ parser->destroy(parser);
+}
+
+/**
+ * ASN.1 definition of a PBES2-params structure
+ */
+static const asn1Object_t pbes2ParamsObjects[] = {
+ { 0, "PBES2-params", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "keyDerivationFunc", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 1, "encryptionScheme", ASN1_EOC, ASN1_RAW }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PBES2PARAMS_KEY_DERIVATION_FUNC 1
+#define PBES2PARAMS_ENCRYPTION_SCHEME 2
+
+/**
+ * Parse a PBES2-params structure
+ */
+static void parse_pbes2_params(chunk_t blob, chunk_t *salt,
+ u_int64_t *iterations, size_t *key_len,
+ pseudo_random_function_t *prf,
+ encryption_algorithm_t *encr, chunk_t *iv)
+{
+ asn1_parser_t *parser;
+ chunk_t object, params;
+ int objectID;
+
+ parser = asn1_parser_create(pbes2ParamsObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PBES2PARAMS_KEY_DERIVATION_FUNC:
+ {
+ int oid = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser) + 1, &params);
+ if (oid != OID_PBKDF2)
+ { /* unsupported key derivation function */
+ goto end;
+ }
+ parse_pbkdf2_params(params, salt, iterations, key_len, prf);
+ break;
+ }
+ case PBES2PARAMS_ENCRYPTION_SCHEME:
+ {
+ int oid = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser) + 1, &params);
+ if (oid != OID_3DES_EDE_CBC)
+ { /* unsupported encryption scheme */
+ goto end;
+ }
+ if (*key_len <= 0)
+ { /* default key len for DES-EDE3-CBC-Pad */
+ *key_len = 24;
+ }
+ if (!asn1_parse_simple_object(&params, ASN1_OCTET_STRING,
+ parser->get_level(parser) + 1, "IV"))
+ {
+ goto end;
+ }
+ *encr = ENCR_3DES;
+ *iv = params;
+ break;
+ }
+ }
+ }
+
+end:
+ parser->destroy(parser);
+}
+
+/**
+ * ASN.1 definition of a PBEParameter structure
+ */
+static const asn1Object_t pbeParameterObjects[] = {
+ { 0, "PBEParameter", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "salt", ASN1_OCTET_STRING, ASN1_BODY }, /* 1 */
+ { 1, "iterationCount", ASN1_INTEGER, ASN1_BODY }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define PBEPARAM_SALT 1
+#define PBEPARAM_ITERATION_COUNT 2
+
+/**
+ * Parse a PBEParameter structure
+ */
+static void parse_pbe_parameters(chunk_t blob, chunk_t *salt,
+ u_int64_t *iterations)
+{
+ asn1_parser_t *parser;
+ chunk_t object;
+ int objectID;
+
+ parser = asn1_parser_create(pbeParameterObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case PBEPARAM_SALT:
+ {
+ *salt = object;
+ break;
+ }
+ case PBEPARAM_ITERATION_COUNT:
+ {
+ *iterations = parse_asn1_integer_uint64(object);
+ break;
+ }
+ }
+ }
+
+ parser->destroy(parser);
+}
+
+/**
+ * ASN.1 definition of an encryptedPrivateKeyInfo structure
+ */
+static const asn1Object_t encryptedPKIObjects[] = {
+ { 0, "encryptedPrivateKeyInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "encryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 1, "encryptedData", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define EPKINFO_ENCRYPTION_ALGORITHM 1
+#define EPKINFO_ENCRYPTED_DATA 2
+
+/**
+ * Load an encrypted private key from an ASN.1 encoded blob
+ * Schemes per PKCS#5 (RFC 2898)
+ */
+static private_key_t *parse_encrypted_private_key(chunk_t blob)
+{
+ asn1_parser_t *parser;
+ chunk_t object, params, salt, iv;
+ u_int64_t iterations = 0;
+ int objectID;
+ encryption_algorithm_t encr = ENCR_UNDEFINED;
+ hash_algorithm_t hash = HASH_UNKNOWN;
+ pseudo_random_function_t prf = PRF_UNDEFINED;
+ private_key_t *key = NULL;
+ size_t key_len = 8;
+
+ parser = asn1_parser_create(encryptedPKIObjects, blob);
+
+ while (parser->iterate(parser, &objectID, &object))
+ {
+ switch (objectID)
+ {
+ case EPKINFO_ENCRYPTION_ALGORITHM:
+ {
+ int oid = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser) + 1, &params);
+
+ switch (oid)
+ {
+ case OID_PBE_MD5_DES_CBC:
+ encr = ENCR_DES;
+ hash = HASH_MD5;
+ parse_pbe_parameters(params, &salt, &iterations);
+ break;
+ case OID_PBE_SHA1_DES_CBC:
+ encr = ENCR_DES;
+ hash = HASH_SHA1;
+ parse_pbe_parameters(params, &salt, &iterations);
+ break;
+ case OID_PBES2:
+ parse_pbes2_params(params, &salt, &iterations,
+ &key_len, &prf, &encr, &iv);
+ break;
+ default:
+ /* encryption scheme not supported */
+ goto end;
+ }
+ break;
+ }
+ case EPKINFO_ENCRYPTED_DATA:
+ {
+ if (prf != PRF_UNDEFINED)
+ {
+ key = decrypt_private_key_pbes2(object, encr, key_len, iv,
+ prf, salt, iterations);
+ }
+ else
+ {
+ key = decrypt_private_key_pbes1(object, encr, key_len, hash,
+ salt, iterations);
+ }
+ break;
+ }
+ }
+ }
+
+end:
+ parser->destroy(parser);
+ return key;
+}
+
+/**
+ * See header.
+ */
+private_key_t *pkcs8_private_key_load(key_type_t type, va_list args)
+{
+ chunk_t blob = chunk_empty;
+ private_key_t *key;
+
+ while (TRUE)
+ {
+ switch (va_arg(args, builder_part_t))
+ {
+ case BUILD_BLOB_ASN1_DER:
+ blob = va_arg(args, chunk_t);
+ continue;
+ case BUILD_END:
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ }
+ /* we don't know whether it is encrypted or not, try both ways */
+ key = parse_encrypted_private_key(blob);
+ if (!key)
+ {
+ key = parse_private_key(blob);
+ }
+ return key;
+}
+
diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_builder.h b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.h
new file mode 100644
index 000000000..b07f2d927
--- /dev/null
+++ b/src/libstrongswan/plugins/pkcs8/pkcs8_builder.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 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 pkcs8_builder pkcs8_builder
+ * @{ @ingroup pkcs8
+ */
+
+#ifndef PKCS8_BUILDER_H_
+#define PKCS8_BUILDER_H_
+
+#include <credentials/builder.h>
+#include <credentials/keys/private_key.h>
+
+/**
+ * Load an RSA or ECDSA private key from PKCS#8 data.
+ *
+ * @param type type of the key, KEY_RSA or KEY_ECDSA
+ * @param args builder_part_t argument list
+ * @return private key, NULL on failure
+ */
+private_key_t *pkcs8_private_key_load(key_type_t type, va_list args);
+
+#endif /** PKCS8_BUILDER_H_ @}*/
diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c
new file mode 100644
index 000000000..f78c83054
--- /dev/null
+++ b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 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 "pkcs8_plugin.h"
+
+#include <library.h>
+
+#include "pkcs8_builder.h"
+
+typedef struct private_pkcs8_plugin_t private_pkcs8_plugin_t;
+
+/**
+ * private data of pkcs8_plugin
+ */
+struct private_pkcs8_plugin_t {
+
+ /**
+ * public functions
+ */
+ pkcs8_plugin_t public;
+};
+
+METHOD(plugin_t, get_name, char*,
+ private_pkcs8_plugin_t *this)
+{
+ return "pkcs8";
+}
+
+METHOD(plugin_t, get_features, int,
+ private_pkcs8_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(PRIVKEY, pkcs8_private_key_load, FALSE),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
+ PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA),
+ };
+ *features = f;
+ return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+ private_pkcs8_plugin_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *pkcs8_plugin_create()
+{
+ private_pkcs8_plugin_t *this;
+
+ INIT(this,
+ .public = {
+ .plugin = {
+ .get_name = _get_name,
+ .get_features = _get_features,
+ .destroy = _destroy,
+ },
+ },
+ );
+
+ return &this->public.plugin;
+}
+
diff --git a/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.h b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.h
new file mode 100644
index 000000000..03ca950a3
--- /dev/null
+++ b/src/libstrongswan/plugins/pkcs8/pkcs8_plugin.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 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 PURPSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup pkcs8 pkcs8
+ * @ingroup plugins
+ *
+ * @defgroup pkcs8_plugin pkcs8_plugin
+ * @{ @ingroup pkcs8
+ */
+
+#ifndef PKCS8_PLUGIN_H_
+#define PKCS8_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct pkcs8_plugin_t pkcs8_plugin_t;
+
+/**
+ * Plugin providing PKCS#8 private key decoding functions
+ */
+struct pkcs8_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** PKCS8_PLUGIN_H_ @}*/
diff --git a/src/libstrongswan/plugins/plugin.h b/src/libstrongswan/plugins/plugin.h
index 5c92fd1d8..7bfbdf1d4 100644
--- a/src/libstrongswan/plugins/plugin.h
+++ b/src/libstrongswan/plugins/plugin.h
@@ -21,10 +21,11 @@
#ifndef PLUGIN_H_
#define PLUGIN_H_
-#include <utils.h>
-
typedef struct plugin_t plugin_t;
+#include <library.h>
+#include <plugins/plugin_feature.h>
+
/**
* Interface definition of a plugin.
*/
@@ -38,6 +39,17 @@ struct plugin_t {
char* (*get_name)(plugin_t *this);
/**
+ * Get plugin features with dependencies.
+ *
+ * The returned array contains features provided by the plugin and
+ * dependencies for that feature. See plugin_feature_t for details.
+ *
+ * @param features pointer receiving plugin features
+ * @return number of features
+ */
+ int (*get_features)(plugin_t *this, plugin_feature_t *features[]);
+
+ /**
* Try to reload plugin configuration.
*
* @return TRUE if reloaded, FALSE if reloading not supporty by plugin
@@ -52,7 +64,7 @@ struct plugin_t {
/**
- * Plugin constructor function definiton.
+ * Plugin constructor function definition.
*
* Each plugin has a constructor function. This function is called on daemon
* startup to initialize each plugin.
diff --git a/src/libstrongswan/plugins/plugin_feature.c b/src/libstrongswan/plugins/plugin_feature.c
new file mode 100644
index 000000000..2a97205bb
--- /dev/null
+++ b/src/libstrongswan/plugins/plugin_feature.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+
+#include "plugin_feature.h"
+
+#include <debug.h>
+
+ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM,
+ "NONE",
+ "CRYPTER",
+ "AEAD",
+ "SIGNER",
+ "HASHER",
+ "PRF",
+ "DH",
+ "RNG",
+ "PRIVKEY",
+ "PRIVKEY_GEN",
+ "PRIVKEY_SIGN",
+ "PRIVKEY_DECRYPT",
+ "PUBKEY",
+ "PUBKEY_VERIFY",
+ "PUBKEY_ENCRYPT",
+ "CERT_DECODE",
+ "CERT_ENCODE",
+ "EAP_SERVER",
+ "EAP_CLIENT",
+ "DATABASE",
+ "FETCHER",
+ "CUSTOM",
+);
+
+/**
+ * See header.
+ */
+bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b)
+{
+ if (a->type == b->type)
+ {
+ switch (a->type)
+ {
+ case FEATURE_NONE:
+ return FALSE;
+ case FEATURE_CRYPTER:
+ return a->arg.crypter.alg == b->arg.crypter.alg &&
+ a->arg.crypter.key_size == b->arg.crypter.key_size;
+ case FEATURE_AEAD:
+ return a->arg.aead.alg == b->arg.aead.alg &&
+ a->arg.aead.key_size == b->arg.aead.key_size;
+ case FEATURE_SIGNER:
+ return a->arg.signer == b->arg.signer;
+ case FEATURE_HASHER:
+ return a->arg.hasher == b->arg.hasher;
+ case FEATURE_PRF:
+ return a->arg.prf == b->arg.prf;
+ case FEATURE_DH:
+ return a->arg.dh_group == b->arg.dh_group;
+ case FEATURE_RNG:
+ return a->arg.rng_quality <= b->arg.rng_quality;
+ case FEATURE_PRIVKEY:
+ case FEATURE_PRIVKEY_GEN:
+ case FEATURE_PUBKEY:
+ return a->arg.privkey == b->arg.privkey;
+ case FEATURE_PRIVKEY_SIGN:
+ case FEATURE_PUBKEY_VERIFY:
+ return a->arg.privkey_sign == b->arg.privkey_sign;
+ case FEATURE_PRIVKEY_DECRYPT:
+ case FEATURE_PUBKEY_ENCRYPT:
+ return a->arg.privkey_decrypt == b->arg.privkey_decrypt;
+ case FEATURE_CERT_DECODE:
+ case FEATURE_CERT_ENCODE:
+ return a->arg.cert == b->arg.cert;
+ case FEATURE_EAP_SERVER:
+ case FEATURE_EAP_PEER:
+ return a->arg.eap == b->arg.eap;
+ case FEATURE_DATABASE:
+ return a->arg.database == DB_ANY ||
+ a->arg.database == b->arg.database;
+ case FEATURE_FETCHER:
+ return a->arg.fetcher == NULL ||
+ streq(a->arg.fetcher, b->arg.fetcher);
+ case FEATURE_CUSTOM:
+ return streq(a->arg.custom, b->arg.custom);
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * See header.
+ */
+char* plugin_feature_get_string(plugin_feature_t *feature)
+{
+ char *str = NULL;
+
+ if (feature->kind == FEATURE_REGISTER)
+ {
+ return strdup("(register function)");
+ }
+ switch (feature->type)
+ {
+ case FEATURE_NONE:
+ return strdup("NONE");
+ case FEATURE_CRYPTER:
+ if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type,
+ encryption_algorithm_names, feature->arg.crypter.alg,
+ feature->arg.crypter.key_size) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_AEAD:
+ if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type,
+ encryption_algorithm_names, feature->arg.aead.alg,
+ feature->arg.aead.key_size) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_SIGNER:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ integrity_algorithm_names, feature->arg.signer) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_HASHER:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ hash_algorithm_names, feature->arg.hasher) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_PRF:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ pseudo_random_function_names, feature->arg.prf) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_DH:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ diffie_hellman_group_names, feature->arg.dh_group) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_RNG:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ rng_quality_names, feature->arg.rng_quality) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_PRIVKEY:
+ case FEATURE_PRIVKEY_GEN:
+ case FEATURE_PUBKEY:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ key_type_names, feature->arg.privkey) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_PRIVKEY_SIGN:
+ case FEATURE_PUBKEY_VERIFY:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ signature_scheme_names, feature->arg.privkey_sign) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_PRIVKEY_DECRYPT:
+ case FEATURE_PUBKEY_ENCRYPT:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ encryption_scheme_names, feature->arg.privkey_decrypt) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_CERT_DECODE:
+ case FEATURE_CERT_ENCODE:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ certificate_type_names, feature->arg.cert) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_EAP_SERVER:
+ case FEATURE_EAP_PEER:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ eap_type_short_names, feature->arg.eap) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_DATABASE:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ db_driver_names, feature->arg.database) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_FETCHER:
+ if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
+ feature->arg.fetcher) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_CUSTOM:
+ if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
+ feature->arg.custom) > 0)
+ {
+ return str;
+ }
+ break;
+ }
+ if (!str)
+ {
+ str = strdup("(invalid)");
+ }
+ return str;
+}
+
+/**
+ * See header.
+ */
+bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
+ plugin_feature_t *reg)
+{
+ char *name;
+
+ if (!reg)
+ { /* noting to do for this feature */
+ return TRUE;
+ }
+ if (reg->kind == FEATURE_CALLBACK)
+ {
+ if (reg->arg.cb.f(plugin, feature, TRUE, reg->arg.cb.data))
+ {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ name = plugin->get_name(plugin);
+ switch (feature->type)
+ {
+ case FEATURE_CRYPTER:
+ lib->crypto->add_crypter(lib->crypto, feature->arg.crypter.alg,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_AEAD:
+ lib->crypto->add_aead(lib->crypto, feature->arg.aead.alg,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_SIGNER:
+ lib->crypto->add_signer(lib->crypto, feature->arg.signer,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_HASHER:
+ lib->crypto->add_hasher(lib->crypto, feature->arg.hasher,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_PRF:
+ lib->crypto->add_prf(lib->crypto, feature->arg.prf,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_DH:
+ lib->crypto->add_dh(lib->crypto, feature->arg.dh_group,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_RNG:
+ lib->crypto->add_rng(lib->crypto, feature->arg.rng_quality,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_PRIVKEY:
+ case FEATURE_PRIVKEY_GEN:
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY,
+ feature->arg.privkey, reg->arg.reg.final,
+ reg->arg.reg.f);
+ break;
+ case FEATURE_PUBKEY:
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY,
+ feature->arg.pubkey, reg->arg.reg.final,
+ reg->arg.reg.f);
+ break;
+ case FEATURE_CERT_DECODE:
+ case FEATURE_CERT_ENCODE:
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE,
+ feature->arg.cert, reg->arg.reg.final,
+ reg->arg.reg.f);
+ break;
+ case FEATURE_DATABASE:
+ lib->db->add_database(lib->db, reg->arg.reg.f);
+ break;
+ case FEATURE_FETCHER:
+ lib->fetcher->add_fetcher(lib->fetcher, reg->arg.reg.f,
+ feature->arg.fetcher);
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+/**
+ * See header.
+ */
+bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
+ plugin_feature_t *reg)
+{
+ if (!reg)
+ { /* noting to do for this feature */
+ return TRUE;
+ }
+ if (reg->kind == FEATURE_CALLBACK)
+ {
+ if (reg->arg.cb.f(plugin, feature, FALSE, reg->arg.cb.data))
+ {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ switch (feature->type)
+ {
+ case FEATURE_CRYPTER:
+ lib->crypto->remove_crypter(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_AEAD:
+ lib->crypto->remove_aead(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_SIGNER:
+ lib->crypto->remove_signer(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_HASHER:
+ lib->crypto->remove_hasher(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_PRF:
+ lib->crypto->remove_prf(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_DH:
+ lib->crypto->remove_dh(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_RNG:
+ lib->crypto->remove_rng(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_PRIVKEY:
+ case FEATURE_PRIVKEY_GEN:
+ lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
+ break;
+ case FEATURE_PUBKEY:
+ lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
+ break;
+ case FEATURE_CERT_DECODE:
+ case FEATURE_CERT_ENCODE:
+ lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
+ break;
+ case FEATURE_DATABASE:
+ lib->db->remove_database(lib->db, reg->arg.reg.f);
+ break;
+ case FEATURE_FETCHER:
+ lib->fetcher->remove_fetcher(lib->fetcher, reg->arg.reg.f);
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
diff --git a/src/libstrongswan/plugins/plugin_feature.h b/src/libstrongswan/plugins/plugin_feature.h
new file mode 100644
index 000000000..b1500feba
--- /dev/null
+++ b/src/libstrongswan/plugins/plugin_feature.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 plugin_feature plugin_feature
+ * @{ @ingroup plugins
+ */
+
+#ifndef PLUGIN_FEATURE_H_
+#define PLUGIN_FEATURE_H_
+
+typedef struct plugin_feature_t plugin_feature_t;
+
+#include <library.h>
+#include <eap/eap.h>
+#include <plugins/plugin.h>
+
+/**
+ * Callback function of a plugin to (un-)register a specified feature.
+ *
+ * @param plugin plugin instance
+ * @param feature feature to register
+ * @param reg TRUE to register, FALSE to unregister
+ * @param cb_data user data passed with callback function
+ * @return TRUE if registered successfully
+ */
+typedef bool (*plugin_feature_callback_t)(plugin_t *plugin,
+ plugin_feature_t *feature,
+ bool reg,void *cb_data);
+
+/**
+ * Feature a plugin provides or depends on, including registration functions.
+ *
+ * Each plugin returns a list of plugin features, allowing the plugin loader
+ * to resolve dependencies and register the feature. FEATURE_PROVIDE defines
+ * features provided by the plugin, hard (DEPENDS) or soft (SDEPEND) dependency
+ * specified is related to the previously defined PROVIDE feature.
+ * If a plugin feature requires to hook in functionality into the library
+ * or a daemon, it can use REGISTER or CALLBACK entries. Each PROVIDED feature
+ * uses the REGISTER/CALLBACK entry defined previously. The REGISTER entry
+ * defines a common feature registration function directly passed to the
+ * associated manager or factory (crypto/credential factory etc.). A callback
+ * function is more generic allows the loader to invoke a callback to do
+ * the registration.
+ *
+ * To conviently create feature lists, use the four macros PLUGIN_REGISTER,
+ * PLUGIN_CALLBACK, PLUGIN_PROVIDE, PLUGIN_DEPENDS and PLUGIN_SDEPEND. Use
+ * identation to show how the registration functions and dependencies are
+ * related to a provided feature, such as:
+ *
+ * @verbatim
+ // two features, one with two dependencies, both use a callback to register
+ PLUGIN_CALLBACK(...),
+ PLUGIN_PROVIDE(...),
+ PLUGIN_DEPENDS(...),
+ PLUGIN_SDEPEND(...),
+ PLUGIN_PROVIDE(...),
+ // common constructor to register for a feature with one dependency
+ PLUGIN_REGISTER(...),
+ PLUGIN_PROVIDE(...),
+ PLUGIN_DEPENDS(...),
+ // feature that does not use a registration function
+ PLUGIN_PROVIDE(...),
+ @endverbatim
+ */
+struct plugin_feature_t {
+ /** kind of entry */
+ enum {
+ /* plugin provides this feature */
+ FEATURE_PROVIDE,
+ /* a feature depends on this feature, hard dependency */
+ FEATURE_DEPENDS,
+ /* a feature can optionally use this feature, soft dependency */
+ FEATURE_SDEPEND,
+ /* register the specified function for all following features */
+ FEATURE_REGISTER,
+ /* use a callback to register all following features */
+ FEATURE_CALLBACK,
+ } kind;
+ /* type of feature */
+ enum {
+ /** not a feature */
+ FEATURE_NONE,
+ /** crypter_t */
+ FEATURE_CRYPTER,
+ /** aead_t */
+ FEATURE_AEAD,
+ /** signer_t */
+ FEATURE_SIGNER,
+ /** hasher_t */
+ FEATURE_HASHER,
+ /** prf_t */
+ FEATURE_PRF,
+ /** diffie_hellman_t */
+ FEATURE_DH,
+ /** rng_t */
+ FEATURE_RNG,
+ /** generic private key support */
+ FEATURE_PRIVKEY,
+ /** generating new private keys */
+ FEATURE_PRIVKEY_GEN,
+ /** private_key_t->sign() */
+ FEATURE_PRIVKEY_SIGN,
+ /** private_key_t->decrypt() */
+ FEATURE_PRIVKEY_DECRYPT,
+ /** generic public key support */
+ FEATURE_PUBKEY,
+ /** public_key_t->verify() */
+ FEATURE_PUBKEY_VERIFY,
+ /** public_key_t->encrypt() */
+ FEATURE_PUBKEY_ENCRYPT,
+ /** parsing certificates */
+ FEATURE_CERT_DECODE,
+ /** generating certificates */
+ FEATURE_CERT_ENCODE,
+ /** EAP server implementation */
+ FEATURE_EAP_SERVER,
+ /** EAP peer implementation */
+ FEATURE_EAP_PEER,
+ /** database_t */
+ FEATURE_DATABASE,
+ /** fetcher_t */
+ FEATURE_FETCHER,
+ /** custom feature, described with a string */
+ FEATURE_CUSTOM,
+ } type;
+ /** More specific data for each type */
+ union {
+ /** FEATURE_CRYPTER */
+ struct {
+ encryption_algorithm_t alg;
+ size_t key_size;
+ } crypter;
+ /** FEATURE_AEAD */
+ struct {
+ encryption_algorithm_t alg;
+ size_t key_size;
+ } aead;
+ /** FEATURE_SIGNER */
+ integrity_algorithm_t signer;
+ /** FEATURE_PRF */
+ pseudo_random_function_t prf;
+ /** FEATURE_HASHER */
+ hash_algorithm_t hasher;
+ /** FEATURE_DH */
+ diffie_hellman_group_t dh_group;
+ /** FEATURE_RNG */
+ rng_quality_t rng_quality;
+ /** FEATURE_PRIVKEY */
+ key_type_t privkey;
+ /** FEATURE_PRIVKEY_GEN */
+ key_type_t privkey_gen;
+ /** FEATURE_PRIVKEY_SIGN */
+ signature_scheme_t privkey_sign;
+ /** FEATURE_PRIVKEY_DECRYPT */
+ encryption_scheme_t privkey_decrypt;
+ /** FEATURE_PUBKEY */
+ key_type_t pubkey;
+ /** FEATURE_PUBKEY_VERIFY */
+ signature_scheme_t pubkey_verify;
+ /** FEATURE_PUBKEY_ENCRYPT */
+ encryption_scheme_t pubkey_encrypt;
+ /** FEATURE_CERT_DECODE/ENCODE */
+ certificate_type_t cert;
+ /** FEATURE_EAP_SERVER/CLIENT */
+ eap_type_t eap;
+ /** FEATURE_DATABASE */
+ db_driver_t database;
+ /** FEATURE_FETCHER */
+ char *fetcher;
+ /** FEATURE_CUSTOM */
+ char *custom;
+
+ /** FEATURE_REGISTER */
+ struct {
+ /** final flag to pass for builder_function_t */
+ bool final;
+ /** feature specific function to register for this type */
+ void *f;
+ } reg;
+
+ /** FEATURE_CALLBACK */
+ struct {
+ /** callback function to invoke for registration */
+ plugin_feature_callback_t f;
+ /** data to pass to callback */
+ void *data;
+ } cb;
+ } arg;
+};
+
+#define FEATURE(kind, type, ...) _PLUGIN_FEATURE_##type(kind, __VA_ARGS__)
+
+/**
+ * Define function to register directly for all upcoming features.
+ *
+ * @param type feature type to register
+ * @param f type specific function to register
+ * @param ... type specific additional arguments
+ */
+#define PLUGIN_REGISTER(type, f, ...) _PLUGIN_FEATURE_REGISTER_##type(type, f, ##__VA_ARGS__)
+
+/**
+ * Define a callback to invoke for registering all upcoming features.
+ *
+ * @param cb type specific callback function to register
+ * @param data data pointer to pass to callback
+ */
+#define PLUGIN_CALLBACK(cb, data) _PLUGIN_FEATURE_CALLBACK(cb, data)
+
+/**
+ * Define a feature the plugin provides.
+ *
+ * @param type feature type to provide
+ * @param ... type specific arguments
+ */
+#define PLUGIN_PROVIDE(type, ...) _PLUGIN_FEATURE_##type(PROVIDE, __VA_ARGS__)
+
+/**
+ * Define a hard dependency for the previously defined feature.
+ *
+ * @param type feature type to provide
+ * @param ... type specific arguments
+ */
+#define PLUGIN_DEPENDS(type, ...) _PLUGIN_FEATURE_##type(DEPENDS, __VA_ARGS__)
+
+/**
+ * Define a soft dependency for the previously defined feature.
+ *
+ * @param type feature type to provide
+ * @param ... type specific arguments
+ */
+#define PLUGIN_SDEPEND(type, ...) _PLUGIN_FEATURE_##type(SDEPEND, __VA_ARGS__)
+
+#define __PLUGIN_FEATURE(kind, type, ...) (plugin_feature_t){ FEATURE_##kind, FEATURE_##type, { __VA_ARGS__ }}
+#define _PLUGIN_FEATURE_CRYPTER(kind, alg, size) __PLUGIN_FEATURE(kind, CRYPTER, .crypter = { alg, size })
+#define _PLUGIN_FEATURE_AEAD(kind, alg, size) __PLUGIN_FEATURE(kind, AEAD, .aead = { alg, size })
+#define _PLUGIN_FEATURE_SIGNER(kind, alg) __PLUGIN_FEATURE(kind, SIGNER, .signer = alg)
+#define _PLUGIN_FEATURE_HASHER(kind, alg) __PLUGIN_FEATURE(kind, HASHER, .hasher = alg)
+#define _PLUGIN_FEATURE_PRF(kind, alg) __PLUGIN_FEATURE(kind, PRF, .prf = alg)
+#define _PLUGIN_FEATURE_DH(kind, group) __PLUGIN_FEATURE(kind, DH, .dh_group = group)
+#define _PLUGIN_FEATURE_RNG(kind, quality) __PLUGIN_FEATURE(kind, RNG, .rng_quality = quality)
+#define _PLUGIN_FEATURE_PRIVKEY(kind, type) __PLUGIN_FEATURE(kind, PRIVKEY, .privkey = type)
+#define _PLUGIN_FEATURE_PRIVKEY_GEN(kind, type) __PLUGIN_FEATURE(kind, PRIVKEY_GEN, .privkey_gen = type)
+#define _PLUGIN_FEATURE_PRIVKEY_SIGN(kind, scheme) __PLUGIN_FEATURE(kind, PRIVKEY_SIGN, .privkey_sign = scheme)
+#define _PLUGIN_FEATURE_PRIVKEY_DECRYPT(kind, scheme) __PLUGIN_FEATURE(kind, PRIVKEY_DECRYPT, .privkey_decrypt = scheme)
+#define _PLUGIN_FEATURE_PUBKEY(kind, type) __PLUGIN_FEATURE(kind, PUBKEY, .pubkey = type)
+#define _PLUGIN_FEATURE_PUBKEY_VERIFY(kind, scheme) __PLUGIN_FEATURE(kind, PUBKEY_VERIFY, .pubkey_verify = scheme)
+#define _PLUGIN_FEATURE_PUBKEY_ENCRYPT(kind, scheme) __PLUGIN_FEATURE(kind, PUBKEY_ENCRYPT, .pubkey_encrypt = scheme)
+#define _PLUGIN_FEATURE_CERT_DECODE(kind, type) __PLUGIN_FEATURE(kind, CERT_DECODE, .cert = type)
+#define _PLUGIN_FEATURE_CERT_ENCODE(kind, type) __PLUGIN_FEATURE(kind, CERT_ENCODE, .cert = type)
+#define _PLUGIN_FEATURE_EAP_SERVER(kind, type) __PLUGIN_FEATURE(kind, EAP_SERVER, .eap = type)
+#define _PLUGIN_FEATURE_EAP_PEER(kind, type) __PLUGIN_FEATURE(kind, EAP_PEER, .eap = type)
+#define _PLUGIN_FEATURE_DATABASE(kind, type) __PLUGIN_FEATURE(kind, DATABASE, .database = type)
+#define _PLUGIN_FEATURE_FETCHER(kind, type) __PLUGIN_FEATURE(kind, FETCHER, .fetcher = type)
+#define _PLUGIN_FEATURE_CUSTOM(kind, name) __PLUGIN_FEATURE(kind, CUSTOM, .custom = name)
+
+#define __PLUGIN_FEATURE_REGISTER(type, _f) (plugin_feature_t){ FEATURE_REGISTER, FEATURE_##type, .arg.reg.f = _f }
+#define __PLUGIN_FEATURE_REGISTER_BUILDER(type, _f, _final) (plugin_feature_t){ FEATURE_REGISTER, FEATURE_##type, .arg.reg = {.f = _f, .final = _final, }}
+#define _PLUGIN_FEATURE_REGISTER_CRYPTER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
+#define _PLUGIN_FEATURE_REGISTER_AEAD(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
+#define _PLUGIN_FEATURE_REGISTER_SIGNER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
+#define _PLUGIN_FEATURE_REGISTER_HASHER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
+#define _PLUGIN_FEATURE_REGISTER_PRF(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
+#define _PLUGIN_FEATURE_REGISTER_DH(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
+#define _PLUGIN_FEATURE_REGISTER_RNG(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
+#define _PLUGIN_FEATURE_REGISTER_PRIVKEY(type, f, final) __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
+#define _PLUGIN_FEATURE_REGISTER_PRIVKEY_GEN(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
+#define _PLUGIN_FEATURE_REGISTER_PUBKEY(type, f, final) __PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
+#define _PLUGIN_FEATURE_REGISTER_CERT_DECODE(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
+#define _PLUGIN_FEATURE_REGISTER_CERT_ENCODE(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
+#define _PLUGIN_FEATURE_REGISTER_DATABASE(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
+#define _PLUGIN_FEATURE_REGISTER_FETCHER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
+
+#define _PLUGIN_FEATURE_CALLBACK(_cb, _data) (plugin_feature_t){ FEATURE_CALLBACK, FEATURE_NONE, .arg.cb = { .f = _cb, .data = _data } }
+
+/**
+ * Names for plugin_feature_t types.
+ */
+extern enum_name_t *plugin_feature_names;
+
+/**
+ * Check if feature a matches to feature b.
+ *
+ * @param a feature to check
+ * @param b feature to match against
+ * @return TRUE if a matches b
+ */
+bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b);
+
+/**
+ * Get a string describing feature.
+ *
+ * @param feature feature to describe
+ * @return allocated string describing feature
+ */
+char* plugin_feature_get_string(plugin_feature_t *feature);
+
+/**
+ * Load a plugin feature using a REGISTER/CALLBACK feature entry.
+ *
+ * @param plugin plugin providing feature
+ * @param feature feature to load
+ * @param reg REGISTER/CALLBACK feature entry to use for registration
+ */
+bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
+ plugin_feature_t *reg);
+
+/**
+ * Unload a plugin feature using a REGISTER/CALLBACK feature entry.
+ *
+ * @param plugin plugin providing feature
+ * @param feature feature to unload
+ * @param reg REGISTER/CALLBACK feature entry to use for deregistration
+ */
+bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
+ plugin_feature_t *reg);
+
+#endif /** PLUGIN_FEATURE_H_ @}*/
diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c
index b4d7bf7c7..f97cbb31f 100644
--- a/src/libstrongswan/plugins/plugin_loader.c
+++ b/src/libstrongswan/plugins/plugin_loader.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Tobias Brunner
+ * Copyright (C) 2010-2012 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -23,11 +23,13 @@
#include <stdio.h>
#include <debug.h>
+#include <library.h>
#include <integrity_checker.h>
#include <utils/linked_list.h>
#include <plugins/plugin.h>
typedef struct private_plugin_loader_t private_plugin_loader_t;
+typedef struct plugin_entry_t plugin_entry_t;
/**
* private data of plugin_loader
@@ -40,20 +42,67 @@ struct private_plugin_loader_t {
plugin_loader_t public;
/**
- * list of loaded plugins
+ * List of plugins, as plugin_entry_t
*/
linked_list_t *plugins;
+
+ /**
+ * List of names of loaded plugins
+ */
+ char *loaded_plugins;
+};
+
+/**
+ * Entry for a plugin
+ */
+struct plugin_entry_t {
+
+ /**
+ * Plugin instance
+ */
+ plugin_t *plugin;
+
+ /**
+ * dlopen handle, if in separate lib
+ */
+ void *handle;
+
+ /**
+ * List of loaded features
+ */
+ linked_list_t *loaded;
+
+ /**
+ * List features failed to load
+ */
+ linked_list_t *failed;
};
/**
+ * Destroy a plugin entry
+ */
+static void plugin_entry_destroy(plugin_entry_t *entry)
+{
+ DESTROY_IF(entry->plugin);
+ if (entry->handle)
+ {
+ dlclose(entry->handle);
+ }
+ entry->loaded->destroy(entry->loaded);
+ entry->failed->destroy(entry->failed);
+ free(entry);
+}
+
+/**
* create a plugin
* returns: NOT_FOUND, if the constructor was not found
* FAILED, if the plugin could not be constructed
*/
static status_t create_plugin(private_plugin_loader_t *this, void *handle,
- char *name, bool integrity, plugin_t **plugin)
+ char *name, bool integrity, plugin_entry_t **entry)
{
char create[128];
+ plugin_t *plugin;
plugin_constructor_t constructor;
if (snprintf(create, sizeof(create), "%s_plugin_create",
@@ -77,13 +126,18 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle,
DBG1(DBG_LIB, "plugin '%s': passed file and segment integrity tests",
name);
}
- *plugin = constructor();
- if (*plugin == NULL)
+ plugin = constructor();
+ if (plugin == NULL)
{
DBG1(DBG_LIB, "plugin '%s': failed to load - %s returned NULL", name,
create);
return FAILED;
}
+ INIT(*entry,
+ .plugin = plugin,
+ .loaded = linked_list_create(),
+ .failed = linked_list_create(),
+ );
DBG2(DBG_LIB, "plugin '%s': loaded successfully", name);
return SUCCESS;
}
@@ -91,28 +145,21 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle,
/**
* load a single plugin
*/
-static plugin_t* load_plugin(private_plugin_loader_t *this,
- char *path, char *name)
+static bool load_plugin(private_plugin_loader_t *this, char *name, char *file)
{
- char file[PATH_MAX];
+ plugin_entry_t *entry;
void *handle;
- plugin_t *plugin;
- switch (create_plugin(this, RTLD_DEFAULT, name, FALSE, &plugin))
+ switch (create_plugin(this, RTLD_DEFAULT, name, FALSE, &entry))
{
case SUCCESS:
- return plugin;
+ this->plugins->insert_last(this->plugins, entry);
+ return TRUE;
case NOT_FOUND:
/* try to load the plugin from a file */
break;
default:
- return NULL;
- }
-
- if (snprintf(file, sizeof(file), "%s/libstrongswan-%s.so", path,
- name) >= sizeof(file))
- {
- return NULL;
+ return FALSE;
}
if (lib->integrity)
{
@@ -120,26 +167,80 @@ static plugin_t* load_plugin(private_plugin_loader_t *this,
{
DBG1(DBG_LIB, "plugin '%s': failed file integrity test of '%s'",
name, file);
- return NULL;
+ return FALSE;
}
}
handle = dlopen(file, RTLD_LAZY);
if (handle == NULL)
{
DBG1(DBG_LIB, "plugin '%s' failed to load: %s", name, dlerror());
- return NULL;
+ return FALSE;
}
- if (create_plugin(this, handle, name, TRUE, &plugin) != SUCCESS)
+ if (create_plugin(this, handle, name, TRUE, &entry) != SUCCESS)
{
dlclose(handle);
- return NULL;
+ return FALSE;
}
- /* we do not store or free dlopen() handles, leak_detective requires
- * the modules to keep loaded until leak report */
- return plugin;
+ entry->handle = handle;
+ this->plugins->insert_last(this->plugins, entry);
+ return TRUE;
}
/**
+ * Convert enumerated entries to plugin_t
+ */
+static bool plugin_filter(void *null, plugin_entry_t **entry, plugin_t **plugin,
+ void *in, linked_list_t **list)
+{
+ *plugin = (*entry)->plugin;
+ if (list)
+ {
+ *list = (*entry)->loaded;
+ }
+ return TRUE;
+}
+
+METHOD(plugin_loader_t, create_plugin_enumerator, enumerator_t*,
+ private_plugin_loader_t *this)
+{
+ return enumerator_create_filter(
+ this->plugins->create_enumerator(this->plugins),
+ (void*)plugin_filter, NULL, NULL);
+}
+
+/**
+ * Create a list of the names of all loaded plugins
+ */
+static char* loaded_plugins_list(private_plugin_loader_t *this)
+{
+ int buf_len = 128, len = 0;
+ char *buf, *name;
+ enumerator_t *enumerator;
+ plugin_t *plugin;
+
+ buf = malloc(buf_len);
+ buf[0] = '\0';
+ enumerator = create_plugin_enumerator(this);
+ while (enumerator->enumerate(enumerator, &plugin, NULL))
+ {
+ name = plugin->get_name(plugin);
+ if (len + (strlen(name) + 1) >= buf_len)
+ {
+ buf_len <<= 1;
+ buf = realloc(buf, buf_len);
+ }
+ len += snprintf(&buf[len], buf_len - len, "%s ", name);
+ }
+ enumerator->destroy(enumerator);
+ if (len > 0 && buf[len - 1] == ' ')
+ {
+ buf[len - 1] = '\0';
+ }
+ return buf;
+}
+
+
+/**
* Check if a plugin is already loaded
*/
static bool plugin_loaded(private_plugin_loader_t *this, char *name)
@@ -148,8 +249,8 @@ static bool plugin_loaded(private_plugin_loader_t *this, char *name)
bool found = FALSE;
plugin_t *plugin;
- enumerator = this->plugins->create_enumerator(this->plugins);
- while (enumerator->enumerate(enumerator, &plugin))
+ enumerator = create_plugin_enumerator(this);
+ while (enumerator->enumerate(enumerator, &plugin, NULL))
{
if (streq(plugin->get_name(plugin), name))
{
@@ -161,6 +262,235 @@ static bool plugin_loaded(private_plugin_loader_t *this, char *name)
return found;
}
+/**
+ * Check if a feature of a plugin is already loaded
+ */
+static bool feature_loaded(private_plugin_loader_t *this, plugin_entry_t *entry,
+ plugin_feature_t *feature)
+{
+ return entry->loaded->find_first(entry->loaded, NULL,
+ (void**)&feature) == SUCCESS;
+}
+
+/**
+ * Check if loading a feature of a plugin failed
+ */
+static bool feature_failed(private_plugin_loader_t *this, plugin_entry_t *entry,
+ plugin_feature_t *feature)
+{
+ return entry->failed->find_first(entry->failed, NULL,
+ (void**)&feature) == SUCCESS;
+}
+
+/**
+ * Check if dependencies are satisfied
+ */
+static bool dependencies_satisfied(private_plugin_loader_t *this,
+ plugin_entry_t *entry, bool soft, bool report,
+ plugin_feature_t *features, int count)
+{
+ int i;
+
+ /* first entry is provided feature, followed by dependencies */
+ for (i = 1; i < count; i++)
+ {
+ enumerator_t *entries, *loaded;
+ plugin_feature_t *feature;
+ plugin_entry_t *current;
+ bool found = FALSE;
+
+ if (features[i].kind != FEATURE_DEPENDS &&
+ features[i].kind != FEATURE_SDEPEND)
+ { /* end of dependencies */
+ break;
+ }
+ entries = this->plugins->create_enumerator(this->plugins);
+ while (entries->enumerate(entries, &current))
+ {
+ loaded = current->loaded->create_enumerator(current->loaded);
+ while (loaded->enumerate(loaded, &feature))
+ {
+ if (plugin_feature_matches(&features[i], feature))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ loaded->destroy(loaded);
+ }
+ entries->destroy(entries);
+
+ if (!found && (features[i].kind != FEATURE_SDEPEND || soft))
+ {
+ if (report)
+ {
+ char *provide, *depend, *name;
+
+ name = entry->plugin->get_name(entry->plugin);
+ provide = plugin_feature_get_string(&features[0]);
+ depend = plugin_feature_get_string(&features[i]);
+ DBG2(DBG_LIB, "feature %s in '%s' plugin has unsatisfied "
+ "dependency: %s", provide, name, depend);
+ free(provide);
+ free(depend);
+ }
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ * Check if a given feature is still required as dependency
+ */
+static bool dependency_required(private_plugin_loader_t *this,
+ plugin_feature_t *dep)
+{
+ enumerator_t *enumerator;
+ plugin_feature_t *features;
+ plugin_entry_t *entry;
+ int count, i;
+
+ enumerator = this->plugins->create_enumerator(this->plugins);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (!entry->plugin->get_features)
+ { /* features not supported */
+ continue;
+ }
+ count = entry->plugin->get_features(entry->plugin, &features);
+ for (i = 0; i < count; i++)
+ {
+ if (feature_loaded(this, entry, &features[i]))
+ {
+ while (++i < count && (features[i].kind == FEATURE_DEPENDS ||
+ features[i].kind == FEATURE_SDEPEND))
+ {
+ if (plugin_feature_matches(&features[i], dep))
+ {
+ enumerator->destroy(enumerator);
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ return FALSE;
+}
+
+/**
+ * Load plugin features in correct order
+ */
+static int load_features(private_plugin_loader_t *this, bool soft, bool report)
+{
+ enumerator_t *enumerator;
+ plugin_feature_t *feature, *reg;
+ plugin_entry_t *entry;
+ int count, i, loaded = 0;
+
+ enumerator = this->plugins->create_enumerator(this->plugins);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (!entry->plugin->get_features)
+ { /* feature interface not supported */
+ continue;
+ }
+ reg = NULL;
+ count = entry->plugin->get_features(entry->plugin, &feature);
+ for (i = 0; i < count; i++)
+ {
+ switch (feature->kind)
+ {
+ case FEATURE_PROVIDE:
+ if (!feature_loaded(this, entry, feature) &&
+ !feature_failed(this, entry, feature) &&
+ dependencies_satisfied(this, entry, soft, report,
+ feature, count - i))
+ {
+ if (plugin_feature_load(entry->plugin, feature, reg))
+ {
+ entry->loaded->insert_last(entry->loaded, feature);
+ loaded++;
+ }
+ else
+ {
+ entry->failed->insert_last(entry->failed, feature);
+ }
+ }
+ break;
+ case FEATURE_REGISTER:
+ case FEATURE_CALLBACK:
+ reg = feature;
+ break;
+ default:
+ break;
+ }
+ feature++;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return loaded;
+}
+
+/**
+ * Try to unload plugin features on which is not depended anymore
+ */
+static int unload_features(private_plugin_loader_t *this, plugin_entry_t *entry)
+{
+ plugin_feature_t *feature, *reg = NULL;
+ int count, i, unloaded = 0;
+
+ count = entry->plugin->get_features(entry->plugin, &feature);
+ for (i = 0; i < count; i++)
+ {
+ switch (feature->kind)
+ {
+ case FEATURE_PROVIDE:
+ if (feature_loaded(this, entry, feature) &&
+ !dependency_required(this, feature) &&
+ plugin_feature_unload(entry->plugin, feature, reg))
+ {
+ entry->loaded->remove(entry->loaded, feature, NULL);
+ unloaded++;
+ }
+ break;
+ case FEATURE_REGISTER:
+ case FEATURE_CALLBACK:
+ reg = feature;
+ break;
+ default:
+ break;
+ }
+ feature++;
+ }
+ return unloaded;
+}
+
+/**
+ * Remove plugins that we were not able to load any features from.
+ */
+static void purge_plugins(private_plugin_loader_t *this)
+{
+ enumerator_t *enumerator;
+ plugin_entry_t *entry;
+
+ enumerator = this->plugins->create_enumerator(this->plugins);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (!entry->plugin->get_features)
+ { /* feature interface not supported */
+ continue;
+ }
+ if (!entry->loaded->get_count(entry->loaded))
+ {
+ this->plugins->remove_at(this->plugins, enumerator);
+ plugin_entry_destroy(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
METHOD(plugin_loader_t, load_plugins, bool,
private_plugin_loader_t *this, char *path, char *list)
{
@@ -176,8 +506,8 @@ METHOD(plugin_loader_t, load_plugins, bool,
enumerator = enumerator_create_token(list, " ", " ");
while (!critical_failed && enumerator->enumerate(enumerator, &token))
{
- plugin_t *plugin;
bool critical = FALSE;
+ char file[PATH_MAX];
int len;
token = strdup(token);
@@ -192,42 +522,86 @@ METHOD(plugin_loader_t, load_plugins, bool,
free(token);
continue;
}
- plugin = load_plugin(this, path, token);
- if (plugin)
+ if (snprintf(file, sizeof(file), "%s/libstrongswan-%s.so",
+ path, token) >= sizeof(file))
{
- this->plugins->insert_last(this->plugins, plugin);
+ return FALSE;
}
- else
+ if (!load_plugin(this, token, file) && critical)
{
- if (critical)
- {
- critical_failed = TRUE;
- DBG1(DBG_LIB, "loading critical plugin '%s' failed", token);
- }
+ critical_failed = TRUE;
+ DBG1(DBG_LIB, "loading critical plugin '%s' failed", token);
}
free(token);
+ /* TODO: we currently load features after each plugin is loaded. This
+ * will not be necessary once we have features support in all plugins.
+ */
+ while (load_features(this, TRUE, FALSE))
+ {
+ /* try load new features until we don't get new ones */
+ }
}
enumerator->destroy(enumerator);
+ if (!critical_failed)
+ {
+ while (load_features(this, FALSE, FALSE))
+ {
+ /* enforce loading features, ignoring soft dependencies */
+ }
+ /* report missing dependencies */
+ load_features(this, FALSE, TRUE);
+ /* unload plugins that we were not able to load any features for */
+ purge_plugins(this);
+ }
+ if (!critical_failed)
+ {
+ free(this->loaded_plugins);
+ this->loaded_plugins = loaded_plugins_list(this);
+ }
return !critical_failed;
}
METHOD(plugin_loader_t, unload, void,
private_plugin_loader_t *this)
{
- plugin_t *plugin;
+ enumerator_t *enumerator;
+ plugin_entry_t *entry;
+ linked_list_t *list;
- /* unload plugins in reverse order */
- while (this->plugins->remove_last(this->plugins,
- (void**)&plugin) == SUCCESS)
+ /* unload plugins in reverse order, for those not supporting features */
+ list = linked_list_create();
+ while (this->plugins->remove_last(this->plugins, (void**)&entry) == SUCCESS)
{
- plugin->destroy(plugin);
+ list->insert_last(list, entry);
}
-}
-
-METHOD(plugin_loader_t, create_plugin_enumerator, enumerator_t*,
- private_plugin_loader_t *this)
-{
- return this->plugins->create_enumerator(this->plugins);
+ while (list->remove_last(list, (void**)&entry) == SUCCESS)
+ {
+ this->plugins->insert_first(this->plugins, entry);
+ }
+ list->destroy(list);
+ while (this->plugins->get_count(this->plugins))
+ {
+ enumerator = this->plugins->create_enumerator(this->plugins);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->plugin->get_features)
+ { /* supports features */
+ while (unload_features(this, entry));
+ }
+ if (entry->loaded->get_count(entry->loaded) == 0)
+ {
+ if (lib->leak_detective)
+ { /* keep handle to report leaks properly */
+ entry->handle = NULL;
+ }
+ this->plugins->remove_at(this->plugins, enumerator);
+ plugin_entry_destroy(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ free(this->loaded_plugins);
+ this->loaded_plugins = NULL;
}
/**
@@ -240,11 +614,11 @@ static u_int reload_by_name(private_plugin_loader_t *this, char *name)
plugin_t *plugin;
enumerator = create_plugin_enumerator(this);
- while (enumerator->enumerate(enumerator, &plugin))
+ while (enumerator->enumerate(enumerator, &plugin, NULL))
{
if (name == NULL || streq(name, plugin->get_name(plugin)))
{
- if (plugin->reload(plugin))
+ if (plugin->reload && plugin->reload(plugin))
{
DBG2(DBG_LIB, "reloaded configuration of '%s' plugin",
plugin->get_name(plugin));
@@ -276,10 +650,18 @@ METHOD(plugin_loader_t, reload, u_int,
return reloaded;
}
+METHOD(plugin_loader_t, loaded_plugins, char*,
+ private_plugin_loader_t *this)
+{
+ return this->loaded_plugins ?: "";
+}
+
METHOD(plugin_loader_t, destroy, void,
private_plugin_loader_t *this)
{
- this->plugins->destroy_offset(this->plugins, offsetof(plugin_t, destroy));
+ unload(this);
+ this->plugins->destroy(this->plugins);
+ free(this->loaded_plugins);
free(this);
}
@@ -296,6 +678,7 @@ plugin_loader_t *plugin_loader_create()
.reload = _reload,
.unload = _unload,
.create_plugin_enumerator = _create_plugin_enumerator,
+ .loaded_plugins = _loaded_plugins,
.destroy = _destroy,
},
.plugins = linked_list_create(),
diff --git a/src/libstrongswan/plugins/plugin_loader.h b/src/libstrongswan/plugins/plugin_loader.h
index e03da4543..7fd07044d 100644
--- a/src/libstrongswan/plugins/plugin_loader.h
+++ b/src/libstrongswan/plugins/plugin_loader.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -15,7 +16,7 @@
/**
* @defgroup plugin_loader plugin_loader
- * @{ @ingroup plugin
+ * @{ @ingroup plugins
*/
#ifndef PLUGIN_LOADER_H_
@@ -59,11 +60,24 @@ struct plugin_loader_t {
/**
* Create an enumerator over all loaded plugins.
*
- * @return enumerator over plugin_t*
+ * In addition to the plugin, the enumerator returns a list of pointers to
+ * plugin features currently loaded (if the argument is not NULL).
+ * This list is to be read only.
+ *
+ * @return enumerator over plugin_t*, linked_list_t*
*/
enumerator_t* (*create_plugin_enumerator)(plugin_loader_t *this);
/**
+ * Get a simple list the names of all loaded plugins.
+ *
+ * The function returns internal data, do not free.
+ *
+ * @return list of the names of all loaded plugins
+ */
+ char* (*loaded_plugins)(plugin_loader_t *this);
+
+ /**
* Unload loaded plugins, destroy plugin_loader instance.
*/
void (*destroy)(plugin_loader_t *this);
diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in
index 97fba22fc..0de048791 100644
--- a/src/libstrongswan/plugins/pubkey/Makefile.in
+++ b/src/libstrongswan/plugins/pubkey/Makefile.in
@@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -201,6 +204,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -217,11 +221,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_cert.c b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
index c50189a8b..67240fe0c 100644
--- a/src/libstrongswan/plugins/pubkey/pubkey_cert.c
+++ b/src/libstrongswan/plugins/pubkey/pubkey_cert.c
@@ -15,6 +15,8 @@
#include "pubkey_cert.h"
+#include <time.h>
+
#include <debug.h>
typedef struct private_pubkey_cert_t private_pubkey_cert_t;
@@ -45,40 +47,41 @@ struct private_pubkey_cert_t {
identification_t *subject;
/**
+ * key inception time
+ */
+ time_t notBefore;
+
+ /**
+ * key expiration time
+ */
+ time_t notAfter;
+
+ /**
* reference count
*/
refcount_t ref;
};
-/**
- * Implementation of certificate_t.get_type
- */
-static certificate_type_t get_type(private_pubkey_cert_t *this)
+METHOD(certificate_t, get_type, certificate_type_t,
+ private_pubkey_cert_t *this)
{
return CERT_TRUSTED_PUBKEY;
}
-/**
- * Implementation of certificate_t.get_subject
- */
-static identification_t* get_subject(private_pubkey_cert_t *this)
+METHOD(certificate_t, get_subject, identification_t*,
+ private_pubkey_cert_t *this)
{
return this->subject;
}
-/**
- * Implementation of certificate_t.get_issuer
- */
-static identification_t* get_issuer(private_pubkey_cert_t *this)
+METHOD(certificate_t, get_issuer, identification_t*,
+ private_pubkey_cert_t *this)
{
return this->issuer;
}
-/**
- * Implementation of certificate_t.has_subject.
- */
-static id_match_t has_subject(private_pubkey_cert_t *this,
- identification_t *subject)
+METHOD(certificate_t, has_subject, id_match_t,
+ private_pubkey_cert_t *this, identification_t *subject)
{
if (subject->get_type(subject) == ID_KEY_ID)
{
@@ -94,22 +97,18 @@ static id_match_t has_subject(private_pubkey_cert_t *this,
}
}
}
- return ID_MATCH_NONE;
+
+ return this->subject->matches(this->subject, subject);
}
-/**
- * Implementation of certificate_t.has_subject.
- */
-static id_match_t has_issuer(private_pubkey_cert_t *this,
- identification_t *issuer)
+METHOD(certificate_t, has_issuer, id_match_t,
+ private_pubkey_cert_t *this, identification_t *issuer)
{
return ID_MATCH_NONE;
}
-/**
- * Implementation of certificate_t.equals.
- */
-static bool equals(private_pubkey_cert_t *this, certificate_t *other)
+METHOD(certificate_t, equals, bool,
+ private_pubkey_cert_t *this, certificate_t *other)
{
public_key_t *other_key;
@@ -126,62 +125,52 @@ static bool equals(private_pubkey_cert_t *this, certificate_t *other)
return FALSE;
}
-/**
- * Implementation of certificate_t.issued_by
- */
-static bool issued_by(private_pubkey_cert_t *this, certificate_t *issuer)
+METHOD(certificate_t, issued_by, bool,
+ private_pubkey_cert_t *this, certificate_t *issuer)
{
return equals(this, issuer);
}
-/**
- * Implementation of certificate_t.get_public_key
- */
-static public_key_t* get_public_key(private_pubkey_cert_t *this)
+METHOD(certificate_t, get_public_key, public_key_t*,
+ private_pubkey_cert_t *this)
{
this->key->get_ref(this->key);
return this->key;
}
-/**
- * Implementation of certificate_t.get_validity.
- */
-static bool get_validity(private_pubkey_cert_t *this, time_t *when,
- time_t *not_before, time_t *not_after)
+METHOD(certificate_t, get_validity, bool,
+ private_pubkey_cert_t *this, time_t *when, time_t *not_before,
+ time_t *not_after)
{
+ time_t t = when ? *when : time(NULL);
+
if (not_before)
{
- *not_before = 0;
+ *not_before = this->notBefore;
}
if (not_after)
{
- *not_after = ~0;
+ *not_after = this->notAfter;
}
- return TRUE;
+ return ((this->notBefore == UNDEFINED_TIME || t >= this->notBefore) &&
+ (this->notAfter == UNDEFINED_TIME || t <= this->notAfter));
}
-/**
- * Implementation of certificate_t.get_encoding.
- */
-static bool get_encoding(private_pubkey_cert_t *this, cred_encoding_type_t type,
- chunk_t *encoding)
+METHOD(certificate_t, get_encoding, bool,
+ private_pubkey_cert_t *this, cred_encoding_type_t type, chunk_t *encoding)
{
- return this->key->get_encoding(this->key, PUBKEY_ASN1_DER, encoding);
+ return this->key->get_encoding(this->key, type, encoding);
}
-/**
- * Implementation of certificate_t.get_ref
- */
-static private_pubkey_cert_t* get_ref(private_pubkey_cert_t *this)
+METHOD(certificate_t, get_ref, certificate_t*,
+ private_pubkey_cert_t *this)
{
ref_get(&this->ref);
- return this;
+ return &this->public.interface;
}
-/**
- * Implementation of pubkey_cert_t.destroy
- */
-static void destroy(private_pubkey_cert_t *this)
+METHOD(certificate_t, destroy, void,
+ private_pubkey_cert_t *this)
{
if (ref_put(&this->ref))
{
@@ -195,28 +184,42 @@ static void destroy(private_pubkey_cert_t *this)
/*
* see header file
*/
-static pubkey_cert_t *pubkey_cert_create(public_key_t *key)
+static pubkey_cert_t *pubkey_cert_create(public_key_t *key,
+ time_t notBefore, time_t notAfter,
+ identification_t *subject)
{
- private_pubkey_cert_t *this = malloc_thing(private_pubkey_cert_t);
+ private_pubkey_cert_t *this;
chunk_t fingerprint;
- this->public.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
- this->public.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
- this->public.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
- this->public.interface.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_subject;
- this->public.interface.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
- this->public.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
- this->public.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
- this->public.interface.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
- this->public.interface.get_encoding = (bool (*)(certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding;
- this->public.interface.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
- this->public.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
- this->public.interface.destroy = (void (*)(certificate_t *this))destroy;
-
- this->ref = 1;
- this->key = key;
- this->issuer = identification_create_from_encoding(ID_ANY, chunk_empty);
- if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &fingerprint))
+ INIT(this,
+ .public = {
+ .interface = {
+ .get_type = _get_type,
+ .get_subject = _get_subject,
+ .get_issuer = _get_issuer,
+ .has_subject = _has_subject,
+ .has_issuer = _has_issuer,
+ .issued_by = _issued_by,
+ .get_public_key = _get_public_key,
+ .get_validity = _get_validity,
+ .get_encoding = _get_encoding,
+ .equals = _equals,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ .ref = 1,
+ .key = key,
+ .notBefore = notBefore,
+ .notAfter = notAfter,
+ .issuer = identification_create_from_encoding(ID_ANY, chunk_empty),
+ );
+
+ if (subject)
+ {
+ this->subject = subject->clone(subject);
+ }
+ else if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &fingerprint))
{
this->subject = identification_create_from_encoding(ID_KEY_ID, fingerprint);
}
@@ -235,6 +238,8 @@ pubkey_cert_t *pubkey_cert_wrap(certificate_type_t type, va_list args)
{
public_key_t *key = NULL;
chunk_t blob = chunk_empty;
+ identification_t *subject = NULL;
+ time_t notBefore = UNDEFINED_TIME, notAfter = UNDEFINED_TIME;
while (TRUE)
{
@@ -246,6 +251,15 @@ pubkey_cert_t *pubkey_cert_wrap(certificate_type_t type, va_list args)
case BUILD_PUBLIC_KEY:
key = va_arg(args, public_key_t*);
continue;
+ case BUILD_NOT_BEFORE_TIME:
+ notBefore = va_arg(args, time_t);
+ continue;
+ case BUILD_NOT_AFTER_TIME:
+ notAfter = va_arg(args, time_t);
+ continue;
+ case BUILD_SUBJECT:
+ subject = va_arg(args, identification_t*);
+ continue;
case BUILD_END:
break;
default:
@@ -264,7 +278,7 @@ pubkey_cert_t *pubkey_cert_wrap(certificate_type_t type, va_list args)
}
if (key)
{
- return pubkey_cert_create(key);
+ return pubkey_cert_create(key, notBefore, notAfter, subject);
}
return NULL;
}
diff --git a/src/libstrongswan/plugins/pubkey/pubkey_plugin.c b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c
index ae6607e5a..92bfc2e63 100644
--- a/src/libstrongswan/plugins/pubkey/pubkey_plugin.c
+++ b/src/libstrongswan/plugins/pubkey/pubkey_plugin.c
@@ -37,11 +37,19 @@ METHOD(plugin_t, get_name, char*,
return "pubkey";
}
+METHOD(plugin_t, get_features, int,
+ private_pubkey_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(CERT_ENCODE, pubkey_cert_wrap, FALSE),
+ PLUGIN_PROVIDE(CERT_ENCODE, CERT_TRUSTED_PUBKEY),
+ };
+ *features = f;
+ return countof(f);
+}
METHOD(plugin_t, destroy, void,
private_pubkey_plugin_t *this)
{
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)pubkey_cert_wrap);
free(this);
}
@@ -56,15 +64,12 @@ plugin_t *pubkey_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_TRUSTED_PUBKEY, FALSE,
- (builder_function_t)pubkey_cert_wrap);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in
index 761d2c96e..9b549b071 100644
--- a/src/libstrongswan/plugins/random/Makefile.in
+++ b/src/libstrongswan/plugins/random/Makefile.in
@@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -201,6 +204,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -217,11 +221,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/random/random_plugin.c b/src/libstrongswan/plugins/random/random_plugin.c
index 00202a5a6..7f81e2622 100644
--- a/src/libstrongswan/plugins/random/random_plugin.c
+++ b/src/libstrongswan/plugins/random/random_plugin.c
@@ -37,11 +37,21 @@ METHOD(plugin_t, get_name, char*,
return "random";
}
+METHOD(plugin_t, get_features, int,
+ private_random_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(RNG, random_rng_create),
+ PLUGIN_PROVIDE(RNG, RNG_STRONG),
+ PLUGIN_PROVIDE(RNG, RNG_TRUE),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_random_plugin_t *this)
{
- lib->crypto->remove_rng(lib->crypto,
- (rng_constructor_t)random_rng_create);
free(this);
}
@@ -56,17 +66,12 @@ plugin_t *random_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->crypto->add_rng(lib->crypto, RNG_STRONG, get_name(this),
- (rng_constructor_t)random_rng_create);
- lib->crypto->add_rng(lib->crypto, RNG_TRUE, get_name(this),
- (rng_constructor_t)random_rng_create);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/revocation/Makefile.in b/src/libstrongswan/plugins/revocation/Makefile.in
index e8856b7d7..a78762c82 100644
--- a/src/libstrongswan/plugins/revocation/Makefile.in
+++ b/src/libstrongswan/plugins/revocation/Makefile.in
@@ -195,6 +195,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -203,6 +206,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -219,11 +223,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -267,6 +273,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/revocation/revocation_validator.c b/src/libstrongswan/plugins/revocation/revocation_validator.c
index def169275..34f347d1a 100644
--- a/src/libstrongswan/plugins/revocation/revocation_validator.c
+++ b/src/libstrongswan/plugins/revocation/revocation_validator.c
@@ -404,7 +404,15 @@ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best,
{
DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
&revocation, TRUE, crl_reason_names, reason);
- *valid = VALIDATION_REVOKED;
+ if (reason != CRL_REASON_CERTIFICATE_HOLD)
+ {
+ *valid = VALIDATION_REVOKED;
+ }
+ else
+ {
+ /* if the cert is on hold, a newer CRL might not contain it */
+ *valid = VALIDATION_ON_HOLD;
+ }
enumerator->destroy(enumerator);
DESTROY_IF(best);
return cand;
@@ -681,6 +689,7 @@ METHOD(cert_validator_t, validate, bool,
DBG1(DBG_CFG, "certificate status is good");
return TRUE;
case VALIDATION_REVOKED:
+ case VALIDATION_ON_HOLD:
/* has already been logged */
return FALSE;
case VALIDATION_SKIPPED:
@@ -700,6 +709,7 @@ METHOD(cert_validator_t, validate, bool,
DBG1(DBG_CFG, "certificate status is good");
return TRUE;
case VALIDATION_REVOKED:
+ case VALIDATION_ON_HOLD:
/* has already been logged */
return FALSE;
case VALIDATION_FAILED:
diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in
index b4b275648..f59c7516d 100644
--- a/src/libstrongswan/plugins/sha1/Makefile.in
+++ b/src/libstrongswan/plugins/sha1/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/sha1/sha1_hasher.c b/src/libstrongswan/plugins/sha1/sha1_hasher.c
index 85bc89f37..4d69ad5a4 100644
--- a/src/libstrongswan/plugins/sha1/sha1_hasher.c
+++ b/src/libstrongswan/plugins/sha1/sha1_hasher.c
@@ -175,10 +175,8 @@ static void SHA1Final(private_sha1_hasher_t *this, u_int8_t *digest)
}
}
-/**
- * Implementation of hasher_t.reset.
- */
-static void reset(private_sha1_hasher_t *this)
+METHOD(hasher_t, reset, void,
+ private_sha1_hasher_t *this)
{
this->state[0] = 0x67452301;
this->state[1] = 0xEFCDAB89;
@@ -189,10 +187,8 @@ static void reset(private_sha1_hasher_t *this)
this->count[1] = 0;
}
-/**
- * Implementation of hasher_t.get_hash.
- */
-static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
+METHOD(hasher_t, get_hash, void,
+ private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
SHA1Update(this, chunk.ptr, chunk.len);
if (buffer != NULL)
@@ -202,10 +198,8 @@ static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffe
}
}
-/**
- * Implementation of hasher_t.allocate_hash.
- */
-static void allocate_hash(private_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash)
+METHOD(hasher_t, allocate_hash, void,
+ private_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash)
{
SHA1Update(this, chunk.ptr, chunk.len);
if (hash != NULL)
@@ -218,18 +212,14 @@ static void allocate_hash(private_sha1_hasher_t *this, chunk_t chunk, chunk_t *h
}
}
-/**
- * Implementation of hasher_t.get_hash_size.
- */
-static size_t get_hash_size(private_sha1_hasher_t *this)
+METHOD(hasher_t, get_hash_size, size_t,
+ private_sha1_hasher_t *this)
{
return HASH_SIZE_SHA1;
}
-/**
- * Implementation of hasher_t.destroy.
- */
-static void destroy(private_sha1_hasher_t *this)
+METHOD(hasher_t, destroy, void,
+ private_sha1_hasher_t *this)
{
free(this);
}
@@ -240,16 +230,23 @@ static void destroy(private_sha1_hasher_t *this)
sha1_hasher_t *sha1_hasher_create(hash_algorithm_t algo)
{
private_sha1_hasher_t *this;
+
if (algo != HASH_SHA1)
{
return NULL;
}
- this = malloc_thing(private_sha1_hasher_t);
- this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
- this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
- this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
- this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
- this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
+
+ INIT(this,
+ .public = {
+ .hasher_interface = {
+ .get_hash = _get_hash,
+ .allocate_hash = _allocate_hash,
+ .get_hash_size = _get_hash_size,
+ .reset = _reset,
+ .destroy = _destroy,
+ },
+ },
+ );
/* initialize */
reset(this);
diff --git a/src/libstrongswan/plugins/sha1/sha1_plugin.c b/src/libstrongswan/plugins/sha1/sha1_plugin.c
index a9b84e790..66c80b292 100644
--- a/src/libstrongswan/plugins/sha1/sha1_plugin.c
+++ b/src/libstrongswan/plugins/sha1/sha1_plugin.c
@@ -38,13 +38,22 @@ METHOD(plugin_t, get_name, char*,
return "sha1";
}
+METHOD(plugin_t, get_features, int,
+ private_sha1_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(HASHER, sha1_hasher_create),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA1),
+ PLUGIN_REGISTER(PRF, sha1_prf_create),
+ PLUGIN_PROVIDE(PRF, PRF_KEYED_SHA1),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_sha1_plugin_t *this)
{
- lib->crypto->remove_hasher(lib->crypto,
- (hasher_constructor_t)sha1_hasher_create);
- lib->crypto->remove_prf(lib->crypto,
- (prf_constructor_t)sha1_prf_create);
free(this);
}
@@ -59,17 +68,12 @@ plugin_t *sha1_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA1, get_name(this),
- (hasher_constructor_t)sha1_hasher_create);
- lib->crypto->add_prf(lib->crypto, PRF_KEYED_SHA1, get_name(this),
- (prf_constructor_t)sha1_prf_create);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/sha1/sha1_prf.c b/src/libstrongswan/plugins/sha1/sha1_prf.c
index a68779d37..11f588c9d 100644
--- a/src/libstrongswan/plugins/sha1/sha1_prf.c
+++ b/src/libstrongswan/plugins/sha1/sha1_prf.c
@@ -59,10 +59,8 @@ struct private_sha1_prf_t {
*/
extern void SHA1Update(private_sha1_hasher_t* this, u_int8_t *data, u_int32_t len);
-/**
- * Implementation of prf_t.get_bytes.
- */
-static void get_bytes(private_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes)
+METHOD(prf_t, get_bytes, void,
+ private_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes)
{
u_int32_t *hash = (u_int32_t*)bytes;
@@ -75,35 +73,27 @@ static void get_bytes(private_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes)
hash[4] = htonl(this->hasher->state[4]);
}
-/**
- * Implementation of prf_t.get_block_size.
- */
-static size_t get_block_size(private_sha1_prf_t *this)
+METHOD(prf_t, get_block_size, size_t,
+ private_sha1_prf_t *this)
{
return HASH_SIZE_SHA1;
}
-/**
- * Implementation of prf_t.allocate_bytes.
- */
-static void allocate_bytes(private_sha1_prf_t *this, chunk_t seed, chunk_t *chunk)
+METHOD(prf_t, allocate_bytes, void,
+ private_sha1_prf_t *this, chunk_t seed, chunk_t *chunk)
{
*chunk = chunk_alloc(HASH_SIZE_SHA1);
get_bytes(this, seed, chunk->ptr);
}
-/**
- * Implementation of prf_t.get_key_size.
- */
-static size_t get_key_size(private_sha1_prf_t *this)
+METHOD(prf_t, get_key_size, size_t,
+ private_sha1_prf_t *this)
{
return sizeof(this->hasher->state);
}
-/**
- * Implementation of prf_t.set_key.
- */
-static void set_key(private_sha1_prf_t *this, chunk_t key)
+METHOD(prf_t, set_key, void,
+ private_sha1_prf_t *this, chunk_t key)
{
int i, rounds;
u_int32_t *iv = (u_int32_t*)key.ptr;
@@ -116,10 +106,8 @@ static void set_key(private_sha1_prf_t *this, chunk_t key)
}
}
-/**
- * Implementation of prf_t.destroy.
- */
-static void destroy(private_sha1_prf_t *this)
+METHOD(prf_t, destroy, void,
+ private_sha1_prf_t *this)
{
this->hasher->public.hasher_interface.destroy(&this->hasher->public.hasher_interface);
free(this);
@@ -131,19 +119,25 @@ static void destroy(private_sha1_prf_t *this)
sha1_prf_t *sha1_prf_create(pseudo_random_function_t algo)
{
private_sha1_prf_t *this;
+
if (algo != PRF_KEYED_SHA1)
{
return NULL;
}
- this = malloc_thing(private_sha1_prf_t);
- this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
- this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
- this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
- this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
- this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
- this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
-
- this->hasher = (private_sha1_hasher_t*)sha1_hasher_create(HASH_SHA1);
+
+ INIT(this,
+ .public = {
+ .prf_interface = {
+ .get_bytes = _get_bytes,
+ .allocate_bytes = _allocate_bytes,
+ .get_block_size = _get_block_size,
+ .get_key_size = _get_key_size,
+ .set_key = _set_key,
+ .destroy = _destroy,
+ },
+ },
+ .hasher = (private_sha1_hasher_t*)sha1_hasher_create(HASH_SHA1),
+ );
return &this->public;
}
diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in
index bdc235555..c99f30e43 100644
--- a/src/libstrongswan/plugins/sha2/Makefile.in
+++ b/src/libstrongswan/plugins/sha2/Makefile.in
@@ -191,6 +191,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -199,6 +202,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -215,11 +219,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -263,6 +269,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/sha2/sha2_hasher.c b/src/libstrongswan/plugins/sha2/sha2_hasher.c
index d407fad1b..60fe4bd20 100644
--- a/src/libstrongswan/plugins/sha2/sha2_hasher.c
+++ b/src/libstrongswan/plugins/sha2/sha2_hasher.c
@@ -426,71 +426,90 @@ static void sha512_final(private_sha512_hasher_t *ctx)
} while(++j < 8);
}
-/**
- * Implementation of hasher_t.get_hash for SHA224.
- */
-static void get_hash224(private_sha256_hasher_t *this,
- chunk_t chunk, u_int8_t *buffer)
+METHOD(hasher_t, reset224, void,
+ private_sha256_hasher_t *this)
+{
+ memcpy(&this->sha_H[0], &sha224_hashInit[0], sizeof(this->sha_H));
+ this->sha_blocks = 0;
+ this->sha_bufCnt = 0;
+}
+
+METHOD(hasher_t, reset256, void,
+ private_sha256_hasher_t *this)
+{
+ memcpy(&this->sha_H[0], &sha256_hashInit[0], sizeof(this->sha_H));
+ this->sha_blocks = 0;
+ this->sha_bufCnt = 0;
+}
+
+METHOD(hasher_t, reset384, void,
+ private_sha512_hasher_t *this)
+{
+ memcpy(&this->sha_H[0], &sha384_hashInit[0], sizeof(this->sha_H));
+ this->sha_blocks = 0;
+ this->sha_blocksMSB = 0;
+ this->sha_bufCnt = 0;
+}
+
+METHOD(hasher_t, reset512, void,
+ private_sha512_hasher_t *this)
+{
+ memcpy(&this->sha_H[0], &sha512_hashInit[0], sizeof(this->sha_H));
+ this->sha_blocks = 0;
+ this->sha_blocksMSB = 0;
+ this->sha_bufCnt = 0;
+}
+
+METHOD(hasher_t, get_hash224, void,
+ private_sha256_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
sha256_write(this, chunk.ptr, chunk.len);
if (buffer != NULL)
{
sha256_final(this);
memcpy(buffer, this->sha_out, HASH_SIZE_SHA224);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ reset224(this);
}
}
-/**
- * Implementation of hasher_t.get_hash for SHA256.
- */
-static void get_hash256(private_sha256_hasher_t *this,
- chunk_t chunk, u_int8_t *buffer)
+METHOD(hasher_t, get_hash256, void,
+ private_sha256_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
sha256_write(this, chunk.ptr, chunk.len);
if (buffer != NULL)
{
sha256_final(this);
memcpy(buffer, this->sha_out, HASH_SIZE_SHA256);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ reset256(this);
}
}
-/**
- * Implementation of hasher_t.get_hash for SHA384.
- */
-static void get_hash384(private_sha512_hasher_t *this,
- chunk_t chunk, u_int8_t *buffer)
+METHOD(hasher_t, get_hash384, void,
+ private_sha512_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
sha512_write(this, chunk.ptr, chunk.len);
if (buffer != NULL)
{
sha512_final(this);
memcpy(buffer, this->sha_out, HASH_SIZE_SHA384);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ reset384(this);
}
}
-/**
- * Implementation of hasher_t.get_hash for SHA512.
- */
-static void get_hash512(private_sha512_hasher_t *this,
- chunk_t chunk, u_int8_t *buffer)
+METHOD(hasher_t, get_hash512, void,
+ private_sha512_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
{
sha512_write(this, chunk.ptr, chunk.len);
if (buffer != NULL)
{
sha512_final(this);
memcpy(buffer, this->sha_out, HASH_SIZE_SHA512);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ reset512(this);
}
}
-/**
- * Implementation of hasher_t.allocate_hash for SHA224.
- */
-static void allocate_hash224(private_sha256_hasher_t *this,
- chunk_t chunk, chunk_t *hash)
+METHOD(hasher_t, allocate_hash224, void,
+ private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash)
{
chunk_t allocated_hash;
@@ -500,16 +519,13 @@ static void allocate_hash224(private_sha256_hasher_t *this,
sha256_final(this);
allocated_hash = chunk_alloc(HASH_SIZE_SHA224);
memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA224);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ reset224(this);
*hash = allocated_hash;
}
}
-/**
- * Implementation of hasher_t.allocate_hash for SHA256.
- */
-static void allocate_hash256(private_sha256_hasher_t *this,
- chunk_t chunk, chunk_t *hash)
+METHOD(hasher_t, allocate_hash256, void,
+ private_sha256_hasher_t *this, chunk_t chunk, chunk_t *hash)
{
chunk_t allocated_hash;
@@ -519,16 +535,13 @@ static void allocate_hash256(private_sha256_hasher_t *this,
sha256_final(this);
allocated_hash = chunk_alloc(HASH_SIZE_SHA256);
memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA256);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ reset256(this);
*hash = allocated_hash;
}
}
-/**
- * Implementation of hasher_t.allocate_hash for SHA384.
- */
-static void allocate_hash384(private_sha512_hasher_t *this,
- chunk_t chunk, chunk_t *hash)
+METHOD(hasher_t, allocate_hash384, void,
+ private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash)
{
chunk_t allocated_hash;
@@ -538,16 +551,13 @@ static void allocate_hash384(private_sha512_hasher_t *this,
sha512_final(this);
allocated_hash = chunk_alloc(HASH_SIZE_SHA384);
memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA384);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ reset384(this);
*hash = allocated_hash;
}
}
-/**
- * Implementation of hasher_t.allocate_hash for SHA512.
- */
-static void allocate_hash512(private_sha512_hasher_t *this,
- chunk_t chunk, chunk_t *hash)
+METHOD(hasher_t, allocate_hash512, void,
+ private_sha512_hasher_t *this, chunk_t chunk, chunk_t *hash)
{
chunk_t allocated_hash;
@@ -557,89 +567,37 @@ static void allocate_hash512(private_sha512_hasher_t *this,
sha512_final(this);
allocated_hash = chunk_alloc(HASH_SIZE_SHA512);
memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA512);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
+ reset512(this);
*hash = allocated_hash;
}
}
-/**
- * Implementation of hasher_t.get_hash_size for SHA224.
- */
-static size_t get_hash_size224(private_sha256_hasher_t *this)
+METHOD(hasher_t, get_hash_size224, size_t,
+ private_sha256_hasher_t *this)
{
return HASH_SIZE_SHA224;
}
-/**
- * Implementation of hasher_t.get_hash_size for SHA256.
- */
-static size_t get_hash_size256(private_sha256_hasher_t *this)
+METHOD(hasher_t, get_hash_size256, size_t,
+ private_sha256_hasher_t *this)
{
return HASH_SIZE_SHA256;
}
-/**
- * Implementation of hasher_t.get_hash_size for SHA384.
- */
-static size_t get_hash_size384(private_sha512_hasher_t *this)
+METHOD(hasher_t, get_hash_size384, size_t,
+ private_sha512_hasher_t *this)
{
return HASH_SIZE_SHA384;
}
-/**
- * Implementation of hasher_t.get_hash_size for SHA512.
- */
-static size_t get_hash_size512(private_sha512_hasher_t *this)
+METHOD(hasher_t, get_hash_size512, size_t,
+ private_sha512_hasher_t *this)
{
return HASH_SIZE_SHA512;
}
-/**
- * Implementation of hasher_t.reset for SHA224
- */
-static void reset224(private_sha256_hasher_t *ctx)
-{
- memcpy(&ctx->sha_H[0], &sha224_hashInit[0], sizeof(ctx->sha_H));
- ctx->sha_blocks = 0;
- ctx->sha_bufCnt = 0;
-}
-
-/**
- * Implementation of hasher_t.reset for SHA256
- */
-static void reset256(private_sha256_hasher_t *ctx)
-{
- memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H));
- ctx->sha_blocks = 0;
- ctx->sha_bufCnt = 0;
-}
-
-/**
- * Implementation of hasher_t.reset for SHA384
- */
-static void reset384(private_sha512_hasher_t *ctx)
-{
- memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H));
- ctx->sha_blocks = 0;
- ctx->sha_blocksMSB = 0;
- ctx->sha_bufCnt = 0;
-}
-
-/**
- * Implementation of hasher_t.reset for SHA512
- */
-static void reset512(private_sha512_hasher_t *ctx)
-{
- memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H));
- ctx->sha_blocks = 0;
- ctx->sha_blocksMSB = 0;
- ctx->sha_bufCnt = 0;
-}
-
-/**
- * Implementation of hasher_t.destroy.
- */
-static void destroy(sha2_hasher_t *this)
+METHOD(hasher_t, destroy, void,
+ sha2_hasher_t *this)
{
free(this);
}
@@ -649,46 +607,81 @@ static void destroy(sha2_hasher_t *this)
*/
sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
{
- sha2_hasher_t *this;
-
switch (algorithm)
{
case HASH_SHA224:
- this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
- this->hasher_interface.reset = (void(*)(hasher_t*))reset224;
- this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size224;
- this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash224;
- this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash224;
- break;
+ {
+ private_sha256_hasher_t *this;
+
+ INIT(this,
+ .public = {
+ .hasher_interface = {
+ .reset = _reset224,
+ .get_hash_size = _get_hash_size224,
+ .get_hash = _get_hash224,
+ .allocate_hash = _allocate_hash224,
+ .destroy = _destroy,
+ },
+ },
+ );
+ reset224(this);
+ return &this->public;
+ }
case HASH_SHA256:
- this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
- this->hasher_interface.reset = (void(*)(hasher_t*))reset256;
- this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size256;
- this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash256;
- this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash256;
- break;
+ {
+ private_sha256_hasher_t *this;
+
+ INIT(this,
+ .public = {
+ .hasher_interface = {
+ .reset = _reset256,
+ .get_hash_size = _get_hash_size256,
+ .get_hash = _get_hash256,
+ .allocate_hash = _allocate_hash256,
+ .destroy = _destroy,
+ },
+ },
+ );
+ reset256(this);
+ return &this->public;
+ }
case HASH_SHA384:
- /* uses SHA512 data structure */
- this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
- this->hasher_interface.reset = (void(*)(hasher_t*))reset384;
- this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size384;
- this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash384;
- this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash384;
- break;
+ {
+ private_sha512_hasher_t *this;
+
+ INIT(this,
+ .public = {
+ .hasher_interface = {
+ .reset = _reset384,
+ .get_hash_size = _get_hash_size384,
+ .get_hash = _get_hash384,
+ .allocate_hash = _allocate_hash384,
+ .destroy = _destroy,
+ },
+ },
+ );
+ reset384(this);
+ return &this->public;
+ }
case HASH_SHA512:
- this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
- this->hasher_interface.reset = (void(*)(hasher_t*))reset512;
- this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size512;
- this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash512;
- this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash512;
- break;
+ {
+ private_sha512_hasher_t *this;
+
+ INIT(this,
+ .public = {
+ .hasher_interface = {
+ .reset = _reset512,
+ .get_hash_size = _get_hash_size512,
+ .get_hash = _get_hash512,
+ .allocate_hash = _allocate_hash512,
+ .destroy = _destroy,
+ },
+ },
+ );
+ reset512(this);
+ return &this->public;
+ }
default:
return NULL;
}
- this->hasher_interface.destroy = (void(*)(hasher_t*))destroy;
-
- /* initialize */
- this->hasher_interface.reset(&this->hasher_interface);
-
- return this;
}
diff --git a/src/libstrongswan/plugins/sha2/sha2_plugin.c b/src/libstrongswan/plugins/sha2/sha2_plugin.c
index 4ec03a268..94a7ccd61 100644
--- a/src/libstrongswan/plugins/sha2/sha2_plugin.c
+++ b/src/libstrongswan/plugins/sha2/sha2_plugin.c
@@ -37,11 +37,23 @@ METHOD(plugin_t, get_name, char*,
return "sha2";
}
+METHOD(plugin_t, get_features, int,
+ private_sha2_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(HASHER, sha2_hasher_create),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA224),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA256),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA384),
+ PLUGIN_PROVIDE(HASHER, HASH_SHA512),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_sha2_plugin_t *this)
{
- lib->crypto->remove_hasher(lib->crypto,
- (hasher_constructor_t)sha2_hasher_create);
free(this);
}
@@ -56,21 +68,12 @@ plugin_t *sha2_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA224, get_name(this),
- (hasher_constructor_t)sha2_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA256, get_name(this),
- (hasher_constructor_t)sha2_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA384, get_name(this),
- (hasher_constructor_t)sha2_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA512, get_name(this),
- (hasher_constructor_t)sha2_hasher_create);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/soup/Makefile.in b/src/libstrongswan/plugins/soup/Makefile.in
index ec370d38c..ce4b07769 100644
--- a/src/libstrongswan/plugins/soup/Makefile.in
+++ b/src/libstrongswan/plugins/soup/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/soup/soup_plugin.c b/src/libstrongswan/plugins/soup/soup_plugin.c
index 22c8762e0..b21b28b9f 100644
--- a/src/libstrongswan/plugins/soup/soup_plugin.c
+++ b/src/libstrongswan/plugins/soup/soup_plugin.c
@@ -40,11 +40,21 @@ METHOD(plugin_t, get_name, char*,
return "soup";
}
+METHOD(plugin_t, get_features, int,
+ private_soup_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(FETCHER, soup_fetcher_create),
+ PLUGIN_PROVIDE(FETCHER, "http://"),
+ PLUGIN_PROVIDE(FETCHER, "https://"),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_soup_plugin_t *this)
{
- lib->fetcher->remove_fetcher(lib->fetcher,
- (fetcher_constructor_t)soup_fetcher_create);
free(this);
}
@@ -65,16 +75,11 @@ plugin_t *soup_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->fetcher->add_fetcher(lib->fetcher,
- (fetcher_constructor_t)soup_fetcher_create, "http://");
- lib->fetcher->add_fetcher(lib->fetcher,
- (fetcher_constructor_t)soup_fetcher_create, "https://");
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in
index e2ec799a9..391827724 100644
--- a/src/libstrongswan/plugins/sqlite/Makefile.in
+++ b/src/libstrongswan/plugins/sqlite/Makefile.in
@@ -194,6 +194,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -202,6 +205,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -218,11 +222,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -266,6 +272,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/sqlite/sqlite_plugin.c b/src/libstrongswan/plugins/sqlite/sqlite_plugin.c
index d8c6a560c..f554a9e4f 100644
--- a/src/libstrongswan/plugins/sqlite/sqlite_plugin.c
+++ b/src/libstrongswan/plugins/sqlite/sqlite_plugin.c
@@ -37,11 +37,20 @@ METHOD(plugin_t, get_name, char*,
return "sqlite";
}
+METHOD(plugin_t, get_features, int,
+ private_sqlite_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(DATABASE, sqlite_database_create),
+ PLUGIN_PROVIDE(DATABASE, DB_SQLITE),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_sqlite_plugin_t *this)
{
- lib->db->remove_database(lib->db,
- (database_constructor_t)sqlite_database_create);
free(this);
}
@@ -56,15 +65,12 @@ plugin_t *sqlite_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->db->add_database(lib->db,
- (database_constructor_t)sqlite_database_create);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.am b/src/libstrongswan/plugins/test_vectors/Makefile.am
index 049301977..5280300a8 100644
--- a/src/libstrongswan/plugins/test_vectors/Makefile.am
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.am
@@ -15,6 +15,7 @@ libstrongswan_test_vectors_la_SOURCES = \
test_vectors/aes_cbc.c \
test_vectors/aes_ctr.c \
test_vectors/aes_xcbc.c \
+ test_vectors/aes_cmac.c \
test_vectors/aes_ccm.c \
test_vectors/aes_gcm.c \
test_vectors/blowfish.c \
diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in
index 70cdfd600..7e0271b13 100644
--- a/src/libstrongswan/plugins/test_vectors/Makefile.in
+++ b/src/libstrongswan/plugins/test_vectors/Makefile.in
@@ -76,11 +76,12 @@ am__installdirs = "$(DESTDIR)$(plugindir)"
LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES)
libstrongswan_test_vectors_la_LIBADD =
am_libstrongswan_test_vectors_la_OBJECTS = test_vectors_plugin.lo \
- 3des_cbc.lo aes_cbc.lo aes_ctr.lo aes_xcbc.lo aes_ccm.lo \
- aes_gcm.lo blowfish.lo camellia_cbc.lo camellia_ctr.lo \
- camellia_xcbc.lo cast.lo des.lo idea.lo null.lo rc5.lo \
- serpent_cbc.lo twofish_cbc.lo md2.lo md4.lo md5.lo md5_hmac.lo \
- sha1.lo sha1_hmac.lo sha2.lo sha2_hmac.lo fips_prf.lo rng.lo
+ 3des_cbc.lo aes_cbc.lo aes_ctr.lo aes_xcbc.lo aes_cmac.lo \
+ aes_ccm.lo aes_gcm.lo blowfish.lo camellia_cbc.lo \
+ camellia_ctr.lo camellia_xcbc.lo cast.lo des.lo idea.lo \
+ null.lo rc5.lo serpent_cbc.lo twofish_cbc.lo md2.lo md4.lo \
+ md5.lo md5_hmac.lo sha1.lo sha1_hmac.lo sha2.lo sha2_hmac.lo \
+ fips_prf.lo rng.lo
libstrongswan_test_vectors_la_OBJECTS = \
$(am_libstrongswan_test_vectors_la_OBJECTS)
libstrongswan_test_vectors_la_LINK = $(LIBTOOL) --tag=CC \
@@ -199,6 +200,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -207,6 +211,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -223,11 +228,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -271,6 +278,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -291,6 +299,7 @@ libstrongswan_test_vectors_la_SOURCES = \
test_vectors/aes_cbc.c \
test_vectors/aes_ctr.c \
test_vectors/aes_xcbc.c \
+ test_vectors/aes_cmac.c \
test_vectors/aes_ccm.c \
test_vectors/aes_gcm.c \
test_vectors/blowfish.c \
@@ -402,6 +411,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/3des_cbc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_cbc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_ccm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_cmac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_ctr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_gcm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aes_xcbc.Plo@am__quote@
@@ -477,6 +487,13 @@ aes_xcbc.lo: test_vectors/aes_xcbc.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 aes_xcbc.lo `test -f 'test_vectors/aes_xcbc.c' || echo '$(srcdir)/'`test_vectors/aes_xcbc.c
+aes_cmac.lo: test_vectors/aes_cmac.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_cmac.lo -MD -MP -MF $(DEPDIR)/aes_cmac.Tpo -c -o aes_cmac.lo `test -f 'test_vectors/aes_cmac.c' || echo '$(srcdir)/'`test_vectors/aes_cmac.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/aes_cmac.Tpo $(DEPDIR)/aes_cmac.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='test_vectors/aes_cmac.c' object='aes_cmac.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 aes_cmac.lo `test -f 'test_vectors/aes_cmac.c' || echo '$(srcdir)/'`test_vectors/aes_cmac.c
+
aes_ccm.lo: test_vectors/aes_ccm.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT aes_ccm.lo -MD -MP -MF $(DEPDIR)/aes_ccm.Tpo -c -o aes_ccm.lo `test -f 'test_vectors/aes_ccm.c' || echo '$(srcdir)/'`test_vectors/aes_ccm.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/aes_ccm.Tpo $(DEPDIR)/aes_ccm.Plo
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors.h b/src/libstrongswan/plugins/test_vectors/test_vectors.h
index ab4689c1c..40fb51da6 100644
--- a/src/libstrongswan/plugins/test_vectors/test_vectors.h
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors.h
@@ -91,6 +91,10 @@ TEST_VECTOR_SIGNER(aes_xcbc_s2)
TEST_VECTOR_SIGNER(aes_xcbc_s3)
TEST_VECTOR_SIGNER(aes_xcbc_s4)
TEST_VECTOR_SIGNER(aes_xcbc_s5)
+TEST_VECTOR_SIGNER(aes_cmac_s1)
+TEST_VECTOR_SIGNER(aes_cmac_s2)
+TEST_VECTOR_SIGNER(aes_cmac_s3)
+TEST_VECTOR_SIGNER(aes_cmac_s4)
TEST_VECTOR_SIGNER(camellia_xcbc_s1)
TEST_VECTOR_SIGNER(md5_hmac_s1)
TEST_VECTOR_SIGNER(md5_hmac_s2)
@@ -156,6 +160,13 @@ TEST_VECTOR_PRF(aes_xcbc_p4)
TEST_VECTOR_PRF(aes_xcbc_p5)
TEST_VECTOR_PRF(aes_xcbc_p6)
TEST_VECTOR_PRF(aes_xcbc_p7)
+TEST_VECTOR_PRF(aes_cmac_p1)
+TEST_VECTOR_PRF(aes_cmac_p2)
+TEST_VECTOR_PRF(aes_cmac_p3)
+TEST_VECTOR_PRF(aes_cmac_p4)
+TEST_VECTOR_PRF(aes_cmac_p5)
+TEST_VECTOR_PRF(aes_cmac_p6)
+TEST_VECTOR_PRF(aes_cmac_p7)
TEST_VECTOR_PRF(camellia_xcbc_p1)
TEST_VECTOR_PRF(camellia_xcbc_p2)
TEST_VECTOR_PRF(camellia_xcbc_p3)
diff --git a/src/libstrongswan/plugins/test_vectors/test_vectors/aes_cmac.c b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_cmac.c
new file mode 100644
index 000000000..cc4121424
--- /dev/null
+++ b/src/libstrongswan/plugins/test_vectors/test_vectors/aes_cmac.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2012 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 Licenseor (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 usefulbut
+ * 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 <crypto/crypto_tester.h>
+
+/**
+ * RFC 4493 Example #1: AES-CMAC with 0-byte input
+ */
+prf_test_vector_t aes_cmac_p1 = {
+ .alg = PRF_AES128_CMAC, .key_size = 16, .len = 0,
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .seed = "",
+ .out = "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f\xa3\x7d\x12\x9b\x75\x67\x46"
+};
+
+/**
+ * RFC 4493 Example #2: AES-CMAC with 16-byte input
+ */
+prf_test_vector_t aes_cmac_p2 = {
+ .alg = PRF_AES128_CMAC, .key_size = 16, .len = 16,
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .seed = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ .out = "\x07\x0a\x16\xb4\x6b\x4d\x41\x44\xf7\x9b\xdd\x9d\xd0\x4a\x28\x7c"
+};
+
+/**
+ * RFC 4493 Example #3: AES-CMAC with 40-byte input
+ */
+prf_test_vector_t aes_cmac_p3 = {
+ .alg = PRF_AES128_CMAC, .key_size = 16, .len = 40,
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .seed = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11",
+ .out = "\xdf\xa6\x67\x47\xde\x9a\xe6\x30\x30\xca\x32\x61\x14\x97\xc8\x27"
+};
+
+/**
+ * RFC 4493 Example #4: AES-CMAC with 64-byte input
+ */
+prf_test_vector_t aes_cmac_p4 = {
+ .alg = PRF_AES128_CMAC, .key_size = 16, .len = 64,
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .seed = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .out = "\x51\xf0\xbe\xbf\x7e\x3b\x9d\x92\xfc\x49\x74\x17\x79\x36\x3c\xfe"
+};
+
+/**
+ * RFC 4615 Test Case #1: AES-CMAC with 20-byte input, 18-byte key
+ */
+prf_test_vector_t aes_cmac_p5 = {
+ .alg = PRF_AES128_CMAC, .key_size = 18, .len = 20,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\xed\xcb",
+ .seed = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13",
+ .out = "\x84\xa3\x48\xa4\xa4\x5d\x23\x5b\xab\xff\xfc\x0d\x2b\x4d\xa0\x9a"
+};
+
+/**
+ * RFC 4615 Test Case #2: AES-CMAC with 20-byte input, 16-byte key
+ */
+prf_test_vector_t aes_cmac_p6 = {
+ .alg = PRF_AES128_CMAC, .key_size = 16, .len = 20,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .seed = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13",
+ .out = "\x98\x0a\xe8\x7b\x5f\x4c\x9c\x52\x14\xf5\xb6\xa8\x45\x5e\x4c\x2d"
+};
+
+/**
+ * RFC 4615 Test Case #3: AES-CMAC with 20-byte input, 10-byte key
+ */
+prf_test_vector_t aes_cmac_p7 = {
+ .alg = PRF_AES128_CMAC, .key_size = 10, .len = 20,
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09",
+ .seed = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13",
+ .out = "\x29\x0d\x9e\x11\x2e\xdb\x09\xee\x14\x1f\xcf\x64\xc0\xb7\x2f\x3d"
+};
+
+/**
+ * RFC 4494 Test Case #1: AES-CMAC-96 with 0-byte input
+ */
+signer_test_vector_t aes_cmac_s1 = {
+ .alg = AUTH_AES_CMAC_96, .len = 0,
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .data = "",
+ .mac = "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f\xa3\x7d\x12"
+};
+
+
+/**
+ * RFC 4494 Test Case #2: AES-CMAC-96 with 16-byte input
+ */
+signer_test_vector_t aes_cmac_s2 = {
+ .alg = AUTH_AES_CMAC_96, .len = 16,
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .data = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ .mac = "\x07\x0a\x16\xb4\x6b\x4d\x41\x44\xf7\x9b\xdd\x9d"
+};
+
+/**
+ * RFC 4494 Test Case #3: AES-CMAC-96 with 40-byte input
+ */
+signer_test_vector_t aes_cmac_s3 = {
+ .alg = AUTH_AES_CMAC_96, .len = 40,
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .data = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11",
+ .mac = "\xdf\xa6\x67\x47\xde\x9a\xe6\x30\x30\xca\x32\x61"
+};
+
+/**
+ * RFC 4494 Test Case #4: AES-CMAC-96 with 64-byte input
+ */
+signer_test_vector_t aes_cmac_s4 = {
+ .alg = AUTH_AES_CMAC_96, .len = 64,
+ .key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ .data = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ .mac = "\x51\xf0\xbe\xbf\x7e\x3b\x9d\x92\xfc\x49\x74\x17"
+};
diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in
index 58cdf2c7c..8c05cb22d 100644
--- a/src/libstrongswan/plugins/x509/Makefile.in
+++ b/src/libstrongswan/plugins/x509/Makefile.in
@@ -193,6 +193,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -201,6 +204,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -217,11 +221,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -265,6 +271,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c
index ba0357cc4..a2cb589e0 100644
--- a/src/libstrongswan/plugins/x509/x509_ac.c
+++ b/src/libstrongswan/plugins/x509/x509_ac.c
@@ -179,11 +179,11 @@ static bool parse_directoryName(chunk_t blob, int level, bool implicit, identifi
if (has_directoryName)
{
- iterator_t *iterator = list->create_iterator(list, TRUE);
+ enumerator_t *enumerator = list->create_enumerator(list);
identification_t *directoryName;
bool first = TRUE;
- while (iterator->iterate(iterator, (void**)&directoryName))
+ while (enumerator->enumerate(enumerator, (void**)&directoryName))
{
if (first)
{
@@ -192,15 +192,15 @@ static bool parse_directoryName(chunk_t blob, int level, bool implicit, identifi
}
else
{
- DBG1(DBG_LIB, "more than one directory name - first selected");
+ DBG1(DBG_ASN, "more than one directory name - first selected");
directoryName->destroy(directoryName);
}
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
}
else
{
- DBG1(DBG_LIB, "no directoryName found");
+ DBG1(DBG_ASN, "no directoryName found");
}
list->destroy(list);
@@ -359,10 +359,10 @@ static bool parse_certificate(private_x509_ac_t *this)
break;
case AC_OBJ_VERSION:
this->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
- DBG2(DBG_LIB, " v%d", this->version);
+ DBG2(DBG_ASN, " v%d", this->version);
if (this->version != 2)
{
- DBG1(DBG_LIB, "v%d attribute certificates are not "
+ DBG1(DBG_ASN, "v%d attribute certificates are not "
"supported", this->version);
goto end;
}
@@ -408,20 +408,20 @@ static bool parse_certificate(private_x509_ac_t *this)
switch (type)
{
case OID_AUTHENTICATION_INFO:
- DBG2(DBG_LIB, " need to parse authenticationInfo");
+ DBG2(DBG_ASN, " need to parse authenticationInfo");
break;
case OID_ACCESS_IDENTITY:
- DBG2(DBG_LIB, " need to parse accessIdentity");
+ DBG2(DBG_ASN, " need to parse accessIdentity");
break;
case OID_CHARGING_IDENTITY:
- DBG2(DBG_LIB, "-- > --");
+ DBG2(DBG_ASN, "-- > --");
this->charging = ietf_attributes_create_from_encoding(object);
- DBG2(DBG_LIB, "-- < --");
+ DBG2(DBG_ASN, "-- < --");
break;
case OID_GROUP:
- DBG2(DBG_LIB, "-- > --");
+ DBG2(DBG_ASN, "-- > --");
this->groups = ietf_attributes_create_from_encoding(object);
- DBG2(DBG_LIB, "-- < --");
+ DBG2(DBG_ASN, "-- < --");
break;
case OID_ROLE:
parse_roleSyntax(object, level);
@@ -436,21 +436,21 @@ static bool parse_certificate(private_x509_ac_t *this)
break;
case AC_OBJ_CRITICAL:
critical = object.len && *object.ptr;
- DBG2(DBG_LIB, " %s",(critical)?"TRUE":"FALSE");
+ DBG2(DBG_ASN, " %s",(critical)?"TRUE":"FALSE");
break;
case AC_OBJ_EXTN_VALUE:
{
switch (extn_oid)
{
case OID_CRL_DISTRIBUTION_POINTS:
- DBG2(DBG_LIB, " need to parse crlDistributionPoints");
+ DBG2(DBG_ASN, " need to parse crlDistributionPoints");
break;
case OID_AUTHORITY_KEY_ID:
this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
level, &this->authKeySerialNumber);
break;
case OID_TARGET_INFORMATION:
- DBG2(DBG_LIB, " need to parse targetInformation");
+ DBG2(DBG_ASN, " need to parse targetInformation");
break;
case OID_NO_REV_AVAIL:
this->noRevAvail = TRUE;
@@ -465,7 +465,7 @@ static bool parse_certificate(private_x509_ac_t *this)
NULL);
if (this->algorithm != sig_alg)
{
- DBG1(DBG_LIB, " signature algorithms do not agree");
+ DBG1(DBG_ASN, " signature algorithms do not agree");
success = FALSE;
goto end;
}
@@ -528,7 +528,7 @@ static chunk_t build_attr_cert_validity(private_x509_ac_t *this)
{
return asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_from_time(&this->notBefore, ASN1_GENERALIZEDTIME),
- asn1_from_time(&this->notAfter, ASN1_GENERALIZEDTIME));
+ asn1_from_time(&this->notAfter, ASN1_GENERALIZEDTIME));
}
@@ -616,7 +616,6 @@ static chunk_t build_attr_cert_info(private_x509_ac_t *this)
build_extensions(this));
}
-
/**
* build an X.509 attribute certificate
*/
@@ -636,82 +635,62 @@ static chunk_t build_ac(private_x509_ac_t *this)
asn1_bitstring("m", signatureValue));
}
-/**
- * Implementation of ac_t.get_serial.
- */
-static chunk_t get_serial(private_x509_ac_t *this)
+METHOD(ac_t, get_serial, chunk_t,
+ private_x509_ac_t *this)
{
return this->serialNumber;
}
-/**
- * Implementation of ac_t.get_holderSerial.
- */
-static chunk_t get_holderSerial(private_x509_ac_t *this)
+METHOD(ac_t, get_holderSerial, chunk_t,
+ private_x509_ac_t *this)
{
return this->holderSerial;
}
-/**
- * Implementation of ac_t.get_holderIssuer.
- */
-static identification_t* get_holderIssuer(private_x509_ac_t *this)
+METHOD(ac_t, get_holderIssuer, identification_t*,
+ private_x509_ac_t *this)
{
return this->holderIssuer;
}
-/**
- * Implementation of ac_t.get_authKeyIdentifier.
- */
-static chunk_t get_authKeyIdentifier(private_x509_ac_t *this)
+METHOD(ac_t, get_authKeyIdentifier, chunk_t,
+ private_x509_ac_t *this)
{
return this->authKeyIdentifier;
}
-/**
- * Implementation of certificate_t.get_groups.
- */
-static ietf_attributes_t* get_groups(private_x509_ac_t *this)
+METHOD(ac_t, get_groups, ietf_attributes_t*,
+ private_x509_ac_t *this)
{
return this->groups ? this->groups->get_ref(this->groups) : NULL;
}
-/**
- * Implementation of certificate_t.get_type
- */
-static certificate_type_t get_type(private_x509_ac_t *this)
+METHOD(certificate_t, get_type, certificate_type_t,
+ private_x509_ac_t *this)
{
return CERT_X509_AC;
}
-/**
- * Implementation of certificate_t.get_subject
- */
-static identification_t* get_subject(private_x509_ac_t *this)
+METHOD(certificate_t, get_subject, identification_t*,
+ private_x509_ac_t *this)
{
return this->entityName;
}
-/**
- * Implementation of certificate_t.get_issuer
- */
-static identification_t* get_issuer(private_x509_ac_t *this)
+METHOD(certificate_t, get_issuer, identification_t*,
+ private_x509_ac_t *this)
{
return this->issuerName;
}
-/**
- * Implementation of certificate_t.has_subject.
- */
-static id_match_t has_subject(private_x509_ac_t *this, identification_t *subject)
+METHOD(certificate_t, has_subject, id_match_t,
+ private_x509_ac_t *this, identification_t *subject)
{
return ID_MATCH_NONE;
}
-/**
- * Implementation of certificate_t.has_issuer.
- */
-static id_match_t has_issuer(private_x509_ac_t *this, identification_t *issuer)
+METHOD(certificate_t, has_issuer, id_match_t,
+ private_x509_ac_t *this, identification_t *issuer)
{
if (issuer->get_type(issuer) == ID_KEY_ID && this->authKeyIdentifier.ptr &&
chunk_equals(this->authKeyIdentifier, issuer->get_encoding(issuer)))
@@ -721,10 +700,8 @@ static id_match_t has_issuer(private_x509_ac_t *this, identification_t *issuer)
return this->issuerName->matches(this->issuerName, issuer);
}
-/**
- * Implementation of certificate_t.issued_by
- */
-static bool issued_by(private_x509_ac_t *this, certificate_t *issuer)
+METHOD(certificate_t, issued_by, bool,
+ private_x509_ac_t *this, certificate_t *issuer)
{
public_key_t *key;
signature_scheme_t scheme;
@@ -776,28 +753,21 @@ static bool issued_by(private_x509_ac_t *this, certificate_t *issuer)
return valid;
}
-/**
- * Implementation of certificate_t.get_public_key.
- */
-static public_key_t* get_public_key(private_x509_ac_t *this)
+METHOD(certificate_t, get_public_key, public_key_t*,
+ private_x509_ac_t *this)
{
return NULL;
}
-/**
- * Implementation of certificate_t.get_ref.
- */
-static private_x509_ac_t* get_ref(private_x509_ac_t *this)
+METHOD(certificate_t, get_ref, certificate_t*,
+ private_x509_ac_t *this)
{
ref_get(&this->ref);
- return this;
+ return &this->public.interface.certificate;
}
-/**
- * Implementation of certificate_t.get_validity.
- */
-static bool get_validity(private_x509_ac_t *this, time_t *when,
- time_t *not_before, time_t *not_after)
+METHOD(certificate_t, get_validity, bool,
+ private_x509_ac_t *this, time_t *when, time_t *not_before, time_t *not_after)
{
time_t t = when ? *when : time(NULL);
@@ -812,11 +782,8 @@ static bool get_validity(private_x509_ac_t *this, time_t *when,
return (t >= this->notBefore && t <= this->notAfter);
}
-/**
- * Implementation of certificate_t.get_encoding.
- */
-static bool get_encoding(private_x509_ac_t *this, cred_encoding_type_t type,
- chunk_t *encoding)
+METHOD(certificate_t, get_encoding, bool,
+ private_x509_ac_t *this, cred_encoding_type_t type, chunk_t *encoding)
{
if (type == CERT_ASN1_DER)
{
@@ -827,10 +794,8 @@ static bool get_encoding(private_x509_ac_t *this, cred_encoding_type_t type,
CRED_PART_X509_AC_ASN1_DER, this->encoding, CRED_PART_END);
}
-/**
- * Implementation of certificate_t.equals.
- */
-static bool equals(private_x509_ac_t *this, certificate_t *other)
+METHOD(certificate_t, equals, bool,
+ private_x509_ac_t *this, certificate_t *other)
{
chunk_t encoding;
bool equal;
@@ -852,10 +817,8 @@ static bool equals(private_x509_ac_t *this, certificate_t *other)
return equal;
}
-/**
- * Implementation of x509_ac_t.destroy
- */
-static void destroy(private_x509_ac_t *this)
+METHOD(certificate_t, destroy, void,
+ private_x509_ac_t *this)
{
if (ref_put(&this->ref))
{
@@ -879,41 +842,34 @@ static void destroy(private_x509_ac_t *this)
*/
static private_x509_ac_t *create_empty(void)
{
- private_x509_ac_t *this = malloc_thing(private_x509_ac_t);
-
- /* public functions */
- this->public.interface.get_serial = (chunk_t (*)(ac_t*))get_serial;
- this->public.interface.get_holderSerial = (chunk_t (*)(ac_t*))get_holderSerial;
- this->public.interface.get_holderIssuer = (identification_t* (*)(ac_t*))get_holderIssuer;
- this->public.interface.get_authKeyIdentifier = (chunk_t (*)(ac_t*))get_authKeyIdentifier;
- this->public.interface.get_groups = (ietf_attributes_t* (*)(ac_t*))get_groups;
- this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
- this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
- this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
- this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
- this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
- this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
- this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
- this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
- this->public.interface.certificate.get_encoding = (bool(*)(certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding;
- this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
- this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
- this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
-
- /* initialize */
- this->encoding = chunk_empty;
- this->serialNumber = chunk_empty;
- this->holderSerial = chunk_empty;
- this->authKeyIdentifier = chunk_empty;
- this->holderIssuer = NULL;
- this->entityName = NULL;
- this->issuerName = NULL;
- this->holderCert = NULL;
- this->signerCert = NULL;
- this->signerKey = NULL;
- this->charging = NULL;
- this->groups = NULL;
- this->ref = 1;
+ private_x509_ac_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .certificate = {
+ .get_type = _get_type,
+ .get_subject = _get_subject,
+ .get_issuer = _get_issuer,
+ .has_subject = _has_subject,
+ .has_issuer = _has_issuer,
+ .issued_by = _issued_by,
+ .get_public_key = _get_public_key,
+ .get_validity = _get_validity,
+ .get_encoding = _get_encoding,
+ .equals = _equals,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_serial = _get_serial,
+ .get_holderSerial = _get_holderSerial,
+ .get_holderIssuer = _get_holderIssuer,
+ .get_authKeyIdentifier = _get_authKeyIdentifier,
+ .get_groups = _get_groups,
+ },
+ },
+ .ref = 1,
+ );
return this;
}
diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c
index 8b228a2b6..4859f4310 100644
--- a/src/libstrongswan/plugins/x509/x509_cert.c
+++ b/src/libstrongswan/plugins/x509/x509_cert.c
@@ -275,8 +275,8 @@ static const asn1Object_t basicConstraintsObjects[] = {
{ 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
{ 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */
{ 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
- { 0, "exit", ASN1_EOC, ASN1_EXIT }
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
#define BASIC_CONSTRAINTS_CA 1
#define BASIC_CONSTRAINTS_PATH_LEN 2
@@ -301,7 +301,7 @@ static void parse_basicConstraints(chunk_t blob, int level0,
{
case BASIC_CONSTRAINTS_CA:
isCA = object.len && *object.ptr;
- DBG2(DBG_LIB, " %s", isCA ? "TRUE" : "FALSE");
+ DBG2(DBG_ASN, " %s", isCA ? "TRUE" : "FALSE");
if (isCA)
{
this->flags |= X509_CA;
@@ -394,7 +394,7 @@ static const asn1Object_t generalNameObjects[] = {
{ 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */
{ 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
{ 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
+ { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
{ 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */
{ 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
{ 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */
@@ -482,7 +482,7 @@ static identification_t *parse_generalName(chunk_t blob, int level0)
if (id_type != ID_ANY)
{
gn = identification_create_from_encoding(id_type, object);
- DBG2(DBG_LIB, " '%Y'", gn);
+ DBG2(DBG_ASN, " '%Y'", gn);
goto end;
}
}
@@ -536,14 +536,14 @@ void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_lis
* ASN.1 definition of a authorityKeyIdentifier extension
*/
static const asn1Object_t authKeyIdentifierObjects[] = {
- { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
{ 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_BODY }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
{ 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
{ 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
- { 0, "exit", ASN1_EOC, ASN1_EXIT }
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
#define AUTH_KEY_ID_KEY_ID 1
#define AUTH_KEY_ID_CERT_ISSUER 3
@@ -638,7 +638,7 @@ static void parse_authorityInfoAccess(chunk_t blob, int level0,
/* parsing went wrong - abort */
goto end;
}
- DBG2(DBG_LIB, " '%Y'", id);
+ DBG2(DBG_ASN, " '%Y'", id);
if (accessMethod == OID_OCSP &&
asprintf(&uri, "%Y", id) > 0)
{
@@ -1107,10 +1107,10 @@ static void parse_policyConstraints(chunk_t blob, int level0,
static const asn1Object_t ipAddrBlocksObjects[] = {
{ 0, "ipAddrBlocks", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
{ 1, "ipAddressFamily", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
+ { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
{ 2, "inherit", ASN1_NULL, ASN1_OPT|ASN1_NONE }, /* 3 */
{ 2, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
- { 2, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 5 */
+ { 2, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 5 */
{ 3, "addressPrefix", ASN1_BIT_STRING, ASN1_OPT|ASN1_BODY }, /* 6 */
{ 3, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
{ 3, "addressRange", ASN1_SEQUENCE, ASN1_OPT|ASN1_NONE }, /* 8 */
@@ -1134,36 +1134,36 @@ static bool check_address_object(ts_type_t ts_type, chunk_t object)
case TS_IPV4_ADDR_RANGE:
if (object.len > 5)
{
- DBG1(DBG_LIB, "IPv4 address object is larger than 5 octets");
+ DBG1(DBG_ASN, "IPv4 address object is larger than 5 octets");
return FALSE;
}
break;
case TS_IPV6_ADDR_RANGE:
if (object.len > 17)
{
- DBG1(DBG_LIB, "IPv6 address object is larger than 17 octets");
+ DBG1(DBG_ASN, "IPv6 address object is larger than 17 octets");
return FALSE;
}
break;
default:
- DBG1(DBG_LIB, "unknown address family");
+ DBG1(DBG_ASN, "unknown address family");
return FALSE;
}
if (object.len == 0)
{
- DBG1(DBG_LIB, "An ASN.1 bit string must contain at least the "
+ DBG1(DBG_ASN, "An ASN.1 bit string must contain at least the "
"initial octet");
return FALSE;
}
if (object.len == 1 && object.ptr[0] != 0)
{
- DBG1(DBG_LIB, "An empty ASN.1 bit string must contain a zero "
+ DBG1(DBG_ASN, "An empty ASN.1 bit string must contain a zero "
"initial octet");
return FALSE;
}
if (object.ptr[0] > 7)
{
- DBG1(DBG_LIB, "number of unused bits is too large");
+ DBG1(DBG_ASN, "number of unused bits is too large");
return FALSE;
}
return TRUE;
@@ -1201,11 +1201,11 @@ static void parse_ipAddrBlocks(chunk_t blob, int level0,
{
break;
}
- DBG2(DBG_LIB, " %N", ts_type_name, ts_type);
+ DBG2(DBG_ASN, " %N", ts_type_name, ts_type);
}
break;
case IP_ADDR_BLOCKS_INHERIT:
- DBG1(DBG_LIB, "inherit choice is not supported");
+ DBG1(DBG_ASN, "inherit choice is not supported");
break;
case IP_ADDR_BLOCKS_PREFIX:
if (!check_address_object(ts_type, object))
@@ -1214,7 +1214,7 @@ static void parse_ipAddrBlocks(chunk_t blob, int level0,
}
ts = traffic_selector_create_from_rfc3779_format(ts_type,
object, object);
- DBG2(DBG_LIB, " %R", ts);
+ DBG2(DBG_ASN, " %R", ts);
this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
break;
case IP_ADDR_BLOCKS_MIN:
@@ -1231,7 +1231,7 @@ static void parse_ipAddrBlocks(chunk_t blob, int level0,
}
ts = traffic_selector_create_from_rfc3779_format(ts_type,
min_object, object);
- DBG2(DBG_LIB, " %R", ts);
+ DBG2(DBG_ASN, " %R", ts);
this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
break;
default:
@@ -1280,7 +1280,7 @@ static const asn1Object_t certObjects[] = {
#define X509_OBJ_VERSION 3
#define X509_OBJ_SERIAL_NUMBER 4
#define X509_OBJ_SIG_ALG 5
-#define X509_OBJ_ISSUER 6
+#define X509_OBJ_ISSUER 6
#define X509_OBJ_NOT_BEFORE 8
#define X509_OBJ_NOT_AFTER 9
#define X509_OBJ_SUBJECT 10
@@ -1320,12 +1320,12 @@ static bool parse_certificate(private_x509_cert_t *this)
this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
if (this->version < 1 || this->version > 3)
{
- DBG1(DBG_LIB, "X.509v%d not supported", this->version);
+ DBG1(DBG_ASN, "X.509v%d not supported", this->version);
goto end;
}
else
{
- DBG2(DBG_LIB, " X.509v%d", this->version);
+ DBG2(DBG_ASN, " X.509v%d", this->version);
}
break;
case X509_OBJ_SERIAL_NUMBER:
@@ -1336,7 +1336,7 @@ static bool parse_certificate(private_x509_cert_t *this)
break;
case X509_OBJ_ISSUER:
this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(DBG_LIB, " '%Y'", this->issuer);
+ DBG2(DBG_ASN, " '%Y'", this->issuer);
break;
case X509_OBJ_NOT_BEFORE:
this->notBefore = asn1_parse_time(object, level);
@@ -1346,13 +1346,13 @@ static bool parse_certificate(private_x509_cert_t *this)
break;
case X509_OBJ_SUBJECT:
this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(DBG_LIB, " '%Y'", this->subject);
+ DBG2(DBG_ASN, " '%Y'", this->subject);
break;
case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO:
- DBG2(DBG_LIB, "-- > --");
+ DBG2(DBG_ASN, "-- > --");
this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
KEY_ANY, BUILD_BLOB_ASN1_DER, object, BUILD_END);
- DBG2(DBG_LIB, "-- < --");
+ DBG2(DBG_ASN, "-- < --");
if (this->public_key == NULL)
{
goto end;
@@ -1361,7 +1361,7 @@ static bool parse_certificate(private_x509_cert_t *this)
case X509_OBJ_OPTIONAL_EXTENSIONS:
if (this->version != 3)
{
- DBG1(DBG_LIB, "Only X.509v3 certificates have extensions");
+ DBG1(DBG_ASN, "Only X.509v3 certificates have extensions");
goto end;
}
break;
@@ -1370,7 +1370,7 @@ static bool parse_certificate(private_x509_cert_t *this)
break;
case X509_OBJ_CRITICAL:
critical = object.len && *object.ptr;
- DBG2(DBG_LIB, " %s", critical ? "TRUE" : "FALSE");
+ DBG2(DBG_ASN, " %s", critical ? "TRUE" : "FALSE");
break;
case X509_OBJ_EXTN_VALUE:
{
@@ -1445,7 +1445,7 @@ static bool parse_certificate(private_x509_cert_t *this)
if (critical && lib->settings->get_bool(lib->settings,
"libstrongswan.x509.enforce_critical", TRUE))
{
- DBG1(DBG_LIB, "critical '%s' extension not supported",
+ DBG1(DBG_ASN, "critical '%s' extension not supported",
(extn_oid == OID_UNKNOWN) ? "unknown" :
(char*)oid_names[extn_oid].name);
goto end;
@@ -1458,7 +1458,7 @@ static bool parse_certificate(private_x509_cert_t *this)
this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
if (this->algorithm != sig_alg)
{
- DBG1(DBG_LIB, " signature algorithms do not agree");
+ DBG1(DBG_ASN, " signature algorithms do not agree");
goto end;
}
break;
@@ -1488,8 +1488,8 @@ end:
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
if (hasher == NULL)
{
- DBG1(DBG_LIB, " unable to create hash of certificate, SHA1 not supported");
- return NULL;
+ DBG1(DBG_ASN, " unable to create hash of certificate, SHA1 not supported");
+ return FALSE;
}
hasher->allocate_hash(hasher, this->encoding, &this->encoding_hash);
hasher->destroy(hasher);
@@ -1706,7 +1706,7 @@ METHOD(x509_t, get_subjectKeyIdentifier, chunk_t,
chunk_t fingerprint;
if (this->public_key->get_fingerprint(this->public_key,
- KEYID_PUBKEY_SHA1, &fingerprint))
+ KEYID_PUBKEY_SHA1, &fingerprint))
{
return fingerprint;
}
@@ -1901,7 +1901,7 @@ chunk_t build_generalName(identification_t *id)
context = ASN1_CONTEXT_S_7;
break;
default:
- DBG1(DBG_LIB, "encoding %N as generalName not supported",
+ DBG1(DBG_ASN, "encoding %N as generalName not supported",
id_type_names, id->get_type(id));
return chunk_empty;
}
diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c
index 758505ab5..7bcca16a3 100644
--- a/src/libstrongswan/plugins/x509/x509_crl.c
+++ b/src/libstrongswan/plugins/x509/x509_crl.c
@@ -242,14 +242,14 @@ static bool parse(private_x509_crl_t *this)
break;
case CRL_OBJ_VERSION:
this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
- DBG2(DBG_LIB, " v%d", this->version);
+ DBG2(DBG_ASN, " v%d", this->version);
break;
case CRL_OBJ_SIG_ALG:
sig_alg = asn1_parse_algorithmIdentifier(object, level, NULL);
break;
case CRL_OBJ_ISSUER:
this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(DBG_LIB, " '%Y'", this->issuer);
+ DBG2(DBG_ASN, " '%Y'", this->issuer);
break;
case CRL_OBJ_THIS_UPDATE:
this->thisUpdate = asn1_parse_time(object, level);
@@ -274,7 +274,7 @@ static bool parse(private_x509_crl_t *this)
case CRL_OBJ_CRL_ENTRY_CRITICAL:
case CRL_OBJ_CRITICAL:
critical = object.len && *object.ptr;
- DBG2(DBG_LIB, " %s", critical ? "TRUE" : "FALSE");
+ DBG2(DBG_ASN, " %s", critical ? "TRUE" : "FALSE");
break;
case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
case CRL_OBJ_EXTN_VALUE:
@@ -291,7 +291,7 @@ static bool parse(private_x509_crl_t *this)
{
revoked->reason = *object.ptr;
}
- DBG2(DBG_LIB, " '%N'", crl_reason_names,
+ DBG2(DBG_ASN, " '%N'", crl_reason_names,
revoked->reason);
}
break;
@@ -324,7 +324,7 @@ static bool parse(private_x509_crl_t *this)
if (critical && lib->settings->get_bool(lib->settings,
"libstrongswan.x509.enforce_critical", TRUE))
{
- DBG1(DBG_LIB, "critical '%s' extension not supported",
+ DBG1(DBG_ASN, "critical '%s' extension not supported",
(extn_oid == OID_UNKNOWN) ? "unknown" :
(char*)oid_names[extn_oid].name);
goto end;
@@ -338,7 +338,7 @@ static bool parse(private_x509_crl_t *this)
this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
if (this->algorithm != sig_alg)
{
- DBG1(DBG_LIB, " signature algorithms do not agree");
+ DBG1(DBG_ASN, " signature algorithms do not agree");
goto end;
}
break;
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
index ea02cbab5..33d0aa792 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c
@@ -304,18 +304,14 @@ static chunk_t build_OCSPRequest(private_x509_ocsp_request_t *this)
}
-/**
- * Implementation of certificate_t.get_type
- */
-static certificate_type_t get_type(private_x509_ocsp_request_t *this)
+METHOD(certificate_t, get_type, certificate_type_t,
+ private_x509_ocsp_request_t *this)
{
return CERT_X509_OCSP_REQUEST;
}
-/**
- * Implementation of certificate_t.get_subject
- */
-static identification_t* get_subject(private_x509_ocsp_request_t *this)
+METHOD(certificate_t, get_subject, identification_t*,
+ private_x509_ocsp_request_t *this)
{
certificate_t *ca = (certificate_t*)this->ca;
@@ -330,21 +326,16 @@ static identification_t* get_subject(private_x509_ocsp_request_t *this)
return ca->get_subject(ca);
}
-/**
- * Implementation of certificate_t.get_issuer
- */
-static identification_t* get_issuer(private_x509_ocsp_request_t *this)
+METHOD(certificate_t, get_issuer, identification_t*,
+ private_x509_ocsp_request_t *this)
{
certificate_t *ca = (certificate_t*)this->ca;
return ca->get_subject(ca);
}
-/**
- * Implementation of certificate_t.has_subject.
- */
-static id_match_t has_subject(private_x509_ocsp_request_t *this,
- identification_t *subject)
+METHOD(certificate_t, has_subject, id_match_t,
+ private_x509_ocsp_request_t *this, identification_t *subject)
{
certificate_t *current;
enumerator_t *enumerator;
@@ -363,10 +354,8 @@ static id_match_t has_subject(private_x509_ocsp_request_t *this,
return best;
}
-/**
- * Implementation of certificate_t.has_subject.
- */
-static id_match_t has_issuer(private_x509_ocsp_request_t *this,
+METHOD(certificate_t, has_issuer, id_match_t,
+ private_x509_ocsp_request_t *this,
identification_t *issuer)
{
certificate_t *ca = (certificate_t*)this->ca;
@@ -374,28 +363,22 @@ static id_match_t has_issuer(private_x509_ocsp_request_t *this,
return ca->has_subject(ca, issuer);
}
-/**
- * Implementation of certificate_t.issued_by
- */
-static bool issued_by(private_x509_ocsp_request_t *this, certificate_t *issuer)
+METHOD(certificate_t, issued_by, bool,
+ private_x509_ocsp_request_t *this, certificate_t *issuer)
{
DBG1(DBG_LIB, "OCSP request validation not implemented!");
return FALSE;
}
-/**
- * Implementation of certificate_t.get_public_key
- */
-static public_key_t* get_public_key(private_x509_ocsp_request_t *this)
+METHOD(certificate_t, get_public_key, public_key_t*,
+ private_x509_ocsp_request_t *this)
{
return NULL;
}
-/**
- * Implementation of x509_cert_t.get_validity.
- */
-static bool get_validity(private_x509_ocsp_request_t *this, time_t *when,
- time_t *not_before, time_t *not_after)
+METHOD(certificate_t, get_validity, bool,
+ private_x509_ocsp_request_t *this, time_t *when, time_t *not_before,
+ time_t *not_after)
{
certificate_t *cert;
@@ -410,11 +393,9 @@ static bool get_validity(private_x509_ocsp_request_t *this, time_t *when,
return cert->get_validity(cert, when, not_before, not_after);
}
-/**
- * Implementation of certificate_t.get_encoding.
- */
-static bool get_encoding(private_x509_ocsp_request_t *this,
- cred_encoding_type_t type, chunk_t *encoding)
+METHOD(certificate_t, get_encoding, bool,
+ private_x509_ocsp_request_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
{
if (type == CERT_ASN1_DER)
{
@@ -425,10 +406,8 @@ static bool get_encoding(private_x509_ocsp_request_t *this,
CRED_PART_X509_OCSP_REQ_ASN1_DER, this->encoding, CRED_PART_END);
}
-/**
- * Implementation of certificate_t.equals.
- */
-static bool equals(private_x509_ocsp_request_t *this, certificate_t *other)
+METHOD(certificate_t, equals, bool,
+ private_x509_ocsp_request_t *this, certificate_t *other)
{
chunk_t encoding;
bool equal;
@@ -454,19 +433,15 @@ static bool equals(private_x509_ocsp_request_t *this, certificate_t *other)
return equal;
}
-/**
- * Implementation of certificate_t.asdf
- */
-static private_x509_ocsp_request_t* get_ref(private_x509_ocsp_request_t *this)
+METHOD(certificate_t, get_ref, certificate_t*,
+ private_x509_ocsp_request_t *this)
{
ref_get(&this->ref);
- return this;
+ return &this->public.interface.interface;
}
-/**
- * Implementation of x509_ocsp_request_t.destroy
- */
-static void destroy(private_x509_ocsp_request_t *this)
+METHOD(certificate_t, destroy, void,
+ private_x509_ocsp_request_t *this)
{
if (ref_put(&this->ref))
{
@@ -486,29 +461,30 @@ static void destroy(private_x509_ocsp_request_t *this)
*/
static private_x509_ocsp_request_t *create_empty()
{
- private_x509_ocsp_request_t *this = malloc_thing(private_x509_ocsp_request_t);
-
- this->public.interface.interface.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
- this->public.interface.interface.get_subject = (identification_t* (*)(certificate_t *this))get_subject;
- this->public.interface.interface.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
- this->public.interface.interface.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_subject;
- this->public.interface.interface.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
- this->public.interface.interface.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
- this->public.interface.interface.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
- this->public.interface.interface.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
- this->public.interface.interface.get_encoding = (bool(*)(certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding;
- this->public.interface.interface.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
- this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
- this->public.interface.interface.destroy = (void (*)(certificate_t *this))destroy;
-
- this->ca = NULL;
- this->requestor = NULL;
- this->cert = NULL;
- this->key = NULL;
- this->nonce = chunk_empty;
- this->encoding = chunk_empty;
- this->candidates = linked_list_create();
- this->ref = 1;
+ private_x509_ocsp_request_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .interface = {
+ .get_type = _get_type,
+ .get_subject = _get_subject,
+ .get_issuer = _get_issuer,
+ .has_subject = _has_subject,
+ .has_issuer = _has_issuer,
+ .issued_by = _issued_by,
+ .get_public_key = _get_public_key,
+ .get_validity = _get_validity,
+ .get_encoding = _get_encoding,
+ .equals = _equals,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ },
+ },
+ .candidates = linked_list_create(),
+ .ref = 1,
+ );
return this;
}
diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
index 4cbe3f718..7dfef3993 100644
--- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c
+++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c
@@ -148,14 +148,10 @@ static const chunk_t ASN1_response_content = chunk_from_chars(
0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
);
-/**
- * Implementaiton of ocsp_response_t.get_status
- */
-static cert_validation_t get_status(private_x509_ocsp_response_t *this,
- x509_t *subject, x509_t *issuer,
- time_t *revocation_time,
- crl_reason_t *revocation_reason,
- time_t *this_update, time_t *next_update)
+METHOD(ocsp_response_t, get_status, cert_validation_t,
+ private_x509_ocsp_response_t *this, x509_t *subject, x509_t *issuer,
+ time_t *revocation_time, crl_reason_t *revocation_reason,
+ time_t *this_update, time_t *next_update)
{
enumerator_t *enumerator;
single_response_t *response;
@@ -236,10 +232,8 @@ static cert_validation_t get_status(private_x509_ocsp_response_t *this,
return status;
}
-/**
- * Implementation of ocsp_response_t.create_cert_enumerator.
- */
-static enumerator_t* create_cert_enumerator(private_x509_ocsp_response_t *this)
+METHOD(ocsp_response_t, create_cert_enumerator, enumerator_t*,
+ private_x509_ocsp_response_t *this)
{
return this->certs->create_enumerator(this->certs);
}
@@ -379,6 +373,10 @@ static bool parse_singleResponse(private_x509_ocsp_response_t *this,
}
this->responses->insert_last(this->responses, response);
}
+ else
+ {
+ free(response);
+ }
return success;
}
@@ -509,7 +507,7 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
if (version != OCSP_BASIC_RESPONSE_VERSION)
{
- DBG1(DBG_LIB, " ocsp ResponseData version %d not "
+ DBG1(DBG_ASN, " ocsp ResponseData version %d not "
"supported", version);
goto end;
}
@@ -518,12 +516,12 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
case BASIC_RESPONSE_ID_BY_NAME:
this->responderId = identification_create_from_encoding(
ID_DER_ASN1_DN, object);
- DBG2(DBG_LIB, " '%Y'", this->responderId);
+ DBG2(DBG_ASN, " '%Y'", this->responderId);
break;
case BASIC_RESPONSE_ID_BY_KEY:
this->responderId = identification_create_from_encoding(
ID_KEY_ID, object);
- DBG2(DBG_LIB, " '%Y'", this->responderId);
+ DBG2(DBG_ASN, " '%Y'", this->responderId);
break;
case BASIC_RESPONSE_PRODUCED_AT:
this->producedAt = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
@@ -537,7 +535,7 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this,
break;
case BASIC_RESPONSE_CRITICAL:
critical = object.len && *object.ptr;
- DBG2(DBG_LIB, " %s", critical ? "TRUE" : "FALSE");
+ DBG2(DBG_ASN, " %s", critical ? "TRUE" : "FALSE");
break;
case BASIC_RESPONSE_EXT_VALUE:
if (extn_oid == OID_NONCE)
@@ -653,35 +651,26 @@ end:
return success;
}
-/**
- * Implementation of certificate_t.get_type
- */
-static certificate_type_t get_type(private_x509_ocsp_response_t *this)
+METHOD(certificate_t, get_type, certificate_type_t,
+ private_x509_ocsp_response_t *this)
{
return CERT_X509_OCSP_RESPONSE;
}
-/**
- * Implementation of certificate_t.get_issuer
- */
-static identification_t* get_issuer(private_x509_ocsp_response_t *this)
+METHOD(certificate_t, get_issuer, identification_t*,
+ private_x509_ocsp_response_t *this)
{
return this->responderId;
}
-/**
- * Implementation of certificate_t.has_subject.
- */
-static id_match_t has_issuer(private_x509_ocsp_response_t *this,
- identification_t *issuer)
+METHOD(certificate_t, has_issuer, id_match_t,
+ private_x509_ocsp_response_t *this, identification_t *issuer)
{
return this->responderId->matches(this->responderId, issuer);
}
-/**
- * Implementation of certificate_t.issued_by
- */
-static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer)
+METHOD(certificate_t, issued_by, bool,
+ private_x509_ocsp_response_t *this, certificate_t *issuer)
{
public_key_t *key;
signature_scheme_t scheme;
@@ -736,19 +725,15 @@ static bool issued_by(private_x509_ocsp_response_t *this, certificate_t *issuer)
return valid;
}
-/**
- * Implementation of certificate_t.get_public_key
- */
-static public_key_t* get_public_key(private_x509_ocsp_response_t *this)
+METHOD(certificate_t, get_public_key, public_key_t*,
+ private_x509_ocsp_response_t *this)
{
return NULL;
}
-/**
- * Implementation of certificate_t.get_validity.
- */
-static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
- time_t *not_before, time_t *not_after)
+METHOD(certificate_t, get_validity, bool,
+ private_x509_ocsp_response_t *this, time_t *when,
+ time_t *not_before, time_t *not_after)
{
time_t t = when ? *when : time(NULL);
@@ -763,11 +748,9 @@ static bool get_validity(private_x509_ocsp_response_t *this, time_t *when,
return (t < this->usableUntil);
}
-/**
- * Implementation of certificate_t.get_encoding.
- */
-static bool get_encoding(private_x509_ocsp_response_t *this,
- cred_encoding_type_t type, chunk_t *encoding)
+METHOD(certificate_t, get_encoding, bool,
+ private_x509_ocsp_response_t *this, cred_encoding_type_t type,
+ chunk_t *encoding)
{
if (type == CERT_ASN1_DER)
{
@@ -778,10 +761,8 @@ static bool get_encoding(private_x509_ocsp_response_t *this,
CRED_PART_X509_OCSP_RES_ASN1_DER, this->encoding, CRED_PART_END);
}
-/**
- * Implementation of certificate_t.equals.
- */
-static bool equals(private_x509_ocsp_response_t *this, certificate_t *other)
+METHOD(certificate_t, equals, bool,
+ private_x509_ocsp_response_t *this, certificate_t *other)
{
chunk_t encoding;
bool equal;
@@ -807,19 +788,15 @@ static bool equals(private_x509_ocsp_response_t *this, certificate_t *other)
return equal;
}
-/**
- * Implementation of certificate_t.get_ref
- */
-static private_x509_ocsp_response_t* get_ref(private_x509_ocsp_response_t *this)
+METHOD(certificate_t, get_ref, certificate_t*,
+ private_x509_ocsp_response_t *this)
{
ref_get(&this->ref);
- return this;
+ return &this->public.interface.certificate;
}
-/**
- * Implements ocsp_t.destroy.
- */
-static void destroy(private_x509_ocsp_response_t *this)
+METHOD(certificate_t, destroy, void,
+ private_x509_ocsp_response_t *this)
{
if (ref_put(&this->ref))
{
@@ -838,34 +815,35 @@ static x509_ocsp_response_t *load(chunk_t blob)
{
private_x509_ocsp_response_t *this;
- this = malloc_thing(private_x509_ocsp_response_t);
-
- this->public.interface.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
- this->public.interface.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
- this->public.interface.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
- this->public.interface.certificate.has_subject = (id_match_t(*)(certificate_t*, identification_t *subject))has_issuer;
- this->public.interface.certificate.has_issuer = (id_match_t(*)(certificate_t*, identification_t *issuer))has_issuer;
- this->public.interface.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
- this->public.interface.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
- this->public.interface.certificate.get_validity = (bool(*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
- this->public.interface.certificate.get_encoding = (bool(*)(certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding;
- this->public.interface.certificate.equals = (bool(*)(certificate_t*, certificate_t *other))equals;
- this->public.interface.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
- this->public.interface.certificate.destroy = (void (*)(certificate_t *this))destroy;
- this->public.interface.get_status = (cert_validation_t(*)(ocsp_response_t*, x509_t *subject, x509_t *issuer, time_t *revocation_time,crl_reason_t *revocation_reason,time_t *this_update, time_t *next_update))get_status;
- this->public.interface.create_cert_enumerator = (enumerator_t*(*)(ocsp_response_t*))create_cert_enumerator;
-
- this->ref = 1;
- this->encoding = chunk_clone(blob);
- this->tbsResponseData = chunk_empty;
- this->responderId = NULL;
- this->producedAt = UNDEFINED_TIME;
- this->usableUntil = UNDEFINED_TIME;
- this->responses = linked_list_create();
- this->nonce = chunk_empty;
- this->signatureAlgorithm = OID_UNKNOWN;
- this->signature = chunk_empty;
- this->certs = linked_list_create();
+ INIT(this,
+ .public = {
+ .interface = {
+ .certificate = {
+ .get_type = _get_type,
+ .get_subject = _get_issuer,
+ .get_issuer = _get_issuer,
+ .has_subject = _has_issuer,
+ .has_issuer = _has_issuer,
+ .issued_by = _issued_by,
+ .get_public_key = _get_public_key,
+ .get_validity = _get_validity,
+ .get_encoding = _get_encoding,
+ .equals = _equals,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_status = _get_status,
+ .create_cert_enumerator = _create_cert_enumerator,
+ },
+ },
+ .ref = 1,
+ .encoding = chunk_clone(blob),
+ .producedAt = UNDEFINED_TIME,
+ .usableUntil = UNDEFINED_TIME,
+ .responses = linked_list_create(),
+ .signatureAlgorithm = OID_UNKNOWN,
+ .certs = linked_list_create(),
+ );
if (!parse_OCSPResponse(this))
{
diff --git a/src/libstrongswan/plugins/x509/x509_pkcs10.c b/src/libstrongswan/plugins/x509/x509_pkcs10.c
index 7b488484e..ca08db2c6 100644
--- a/src/libstrongswan/plugins/x509/x509_pkcs10.c
+++ b/src/libstrongswan/plugins/x509/x509_pkcs10.c
@@ -104,34 +104,26 @@ struct private_x509_pkcs10_t {
extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list);
extern chunk_t x509_build_subjectAltNames(linked_list_t *list);
-/**
- * Implementation of certificate_t.get_type.
- */
-static certificate_type_t get_type(private_x509_pkcs10_t *this)
+METHOD(certificate_t, get_type, certificate_type_t,
+ private_x509_pkcs10_t *this)
{
return CERT_PKCS10_REQUEST;
}
-/**
- * Implementation of certificate_t.get_subject and get_issuer.
- */
-static identification_t* get_subject(private_x509_pkcs10_t *this)
+METHOD(certificate_t, get_subject, identification_t*,
+ private_x509_pkcs10_t *this)
{
return this->subject;
}
-/**
- * Implementation of certificate_t.has_subject and has_issuer.
- */
-static id_match_t has_subject(private_x509_pkcs10_t *this, identification_t *subject)
+METHOD(certificate_t, has_subject, id_match_t,
+ private_x509_pkcs10_t *this, identification_t *subject)
{
return this->subject->matches(this->subject, subject);
}
-/**
- * Implementation of certificate_t.issued_by.
- */
-static bool issued_by(private_x509_pkcs10_t *this, certificate_t *issuer)
+METHOD(certificate_t, issued_by, bool,
+ private_x509_pkcs10_t *this, certificate_t *issuer)
{
public_key_t *key;
signature_scheme_t scheme;
@@ -162,20 +154,16 @@ static bool issued_by(private_x509_pkcs10_t *this, certificate_t *issuer)
this->signature);
}
-/**
- * Implementation of certificate_t.get_public_key.
- */
-static public_key_t* get_public_key(private_x509_pkcs10_t *this)
+METHOD(certificate_t, get_public_key, public_key_t*,
+ private_x509_pkcs10_t *this)
{
this->public_key->get_ref(this->public_key);
return this->public_key;
}
-/**
- * Implementation of certificate_t.get_validity.
- */
-static bool get_validity(private_x509_pkcs10_t *this, time_t *when,
- time_t *not_before, time_t *not_after)
+METHOD(certificate_t, get_validity, bool,
+ private_x509_pkcs10_t *this, time_t *when, time_t *not_before,
+ time_t *not_after)
{
if (not_before)
{
@@ -188,11 +176,8 @@ static bool get_validity(private_x509_pkcs10_t *this, time_t *when,
return TRUE;
}
-/**
- * Implementation of certificate_t.get_encoding.
- */
-static bool get_encoding(private_x509_pkcs10_t *this, cred_encoding_type_t type,
- chunk_t *encoding)
+METHOD(certificate_t, get_encoding, bool,
+ private_x509_pkcs10_t *this, cred_encoding_type_t type, chunk_t *encoding)
{
if (type == CERT_ASN1_DER)
{
@@ -203,10 +188,8 @@ static bool get_encoding(private_x509_pkcs10_t *this, cred_encoding_type_t type,
CRED_PART_PKCS10_ASN1_DER, this->encoding, CRED_PART_END);
}
-/**
- * Implementation of certificate_t.equals.
- */
-static bool equals(private_x509_pkcs10_t *this, certificate_t *other)
+METHOD(certificate_t, equals, bool,
+ private_x509_pkcs10_t *this, certificate_t *other)
{
chunk_t encoding;
bool equal;
@@ -232,27 +215,21 @@ static bool equals(private_x509_pkcs10_t *this, certificate_t *other)
return equal;
}
-/**
- * Implementation of certificate_t.get_ref
- */
-static private_x509_pkcs10_t* get_ref(private_x509_pkcs10_t *this)
+METHOD(certificate_t, get_ref, certificate_t*,
+ private_x509_pkcs10_t *this)
{
ref_get(&this->ref);
- return this;
+ return &this->public.interface.interface;
}
-/**
- * Implementation of certificate_t.get_challengePassword.
- */
-static chunk_t get_challengePassword(private_x509_pkcs10_t *this)
+METHOD(pkcs10_t, get_challengePassword, chunk_t,
+ private_x509_pkcs10_t *this)
{
return this->challengePassword;
}
-/**
- * Implementation of pkcs10_t.create_subjectAltName_enumerator.
- */
-static enumerator_t* create_subjectAltName_enumerator(private_x509_pkcs10_t *this)
+METHOD(pkcs10_t, create_subjectAltName_enumerator, enumerator_t*,
+ private_x509_pkcs10_t *this)
{
return this->subjectAltNames->create_enumerator(this->subjectAltNames);
}
@@ -299,7 +276,7 @@ static bool parse_extension_request(private_x509_pkcs10_t *this, chunk_t blob, i
break;
case PKCS10_EXTN_CRITICAL:
critical = object.len && *object.ptr;
- DBG2(DBG_LIB, " %s", critical ? "TRUE" : "FALSE");
+ DBG2(DBG_ASN, " %s", critical ? "TRUE" : "FALSE");
break;
case PKCS10_EXTN_VALUE:
{
@@ -332,25 +309,25 @@ static bool parse_challengePassword(private_x509_pkcs10_t *this, chunk_t blob, i
if (blob.len < 2)
{
- DBG1(DBG_LIB, "L%d - challengePassword: ASN.1 object smaller "
+ DBG1(DBG_ASN, "L%d - challengePassword: ASN.1 object smaller "
"than 2 octets", level);
return FALSE;
}
tag = *blob.ptr;
if (tag < ASN1_UTF8STRING || tag > ASN1_IA5STRING)
{
- DBG1(DBG_LIB, "L%d - challengePassword: ASN.1 object is not "
+ DBG1(DBG_ASN, "L%d - challengePassword: ASN.1 object is not "
"a character string", level);
return FALSE;
}
if (asn1_length(&blob) == ASN1_INVALID_LENGTH)
{
- DBG1(DBG_LIB, "L%d - challengePassword: ASN.1 object has an "
+ DBG1(DBG_ASN, "L%d - challengePassword: ASN.1 object has an "
"invalid length", level);
return FALSE;
}
- DBG2(DBG_LIB, "L%d - challengePassword:", level);
- DBG4(DBG_LIB, " '%.*s'", blob.len, blob.ptr);
+ DBG2(DBG_ASN, "L%d - challengePassword:", level);
+ DBG4(DBG_ASN, " '%.*s'", blob.len, blob.ptr);
return TRUE;
}
@@ -408,14 +385,14 @@ static bool parse_certificate_request(private_x509_pkcs10_t *this)
case PKCS10_VERSION:
if (object.len > 0 && *object.ptr != 0)
{
- DBG1(DBG_LIB, "PKCS#10 certificate request format is "
+ DBG1(DBG_ASN, "PKCS#10 certificate request format is "
"not version 1");
goto end;
}
break;
case PKCS10_SUBJECT:
this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(DBG_LIB, " '%Y'", this->subject);
+ DBG2(DBG_ASN, " '%Y'", this->subject);
break;
case PKCS10_SUBJECT_PUBLIC_KEY_INFO:
this->public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
@@ -477,10 +454,8 @@ end:
return success;
}
-/**
- * Implementation of certificate_t.destroy
- */
-static void destroy(private_x509_pkcs10_t *this)
+METHOD(certificate_t, destroy, void,
+ private_x509_pkcs10_t *this)
{
if (ref_put(&this->ref))
{
@@ -504,33 +479,32 @@ static void destroy(private_x509_pkcs10_t *this)
*/
static private_x509_pkcs10_t* create_empty(void)
{
- private_x509_pkcs10_t *this = malloc_thing(private_x509_pkcs10_t);
-
- this->public.interface.interface.get_type = (certificate_type_t (*) (certificate_t*))get_type;
- this->public.interface.interface.get_subject = (identification_t* (*) (certificate_t*))get_subject;
- this->public.interface.interface.get_issuer = (identification_t* (*) (certificate_t*))get_subject;
- this->public.interface.interface.has_subject = (id_match_t (*) (certificate_t*, identification_t*))has_subject;
- this->public.interface.interface.has_issuer = (id_match_t (*) (certificate_t*, identification_t*))has_subject;
- this->public.interface.interface.issued_by = (bool (*) (certificate_t*, certificate_t*))issued_by;
- this->public.interface.interface.get_public_key = (public_key_t* (*) (certificate_t*))get_public_key;
- this->public.interface.interface.get_validity = (bool (*) (certificate_t*, time_t*, time_t*, time_t*))get_validity;
- this->public.interface.interface.get_encoding = (bool (*) (certificate_t*,cred_encoding_type_t,chunk_t*))get_encoding;
- this->public.interface.interface.equals = (bool (*)(certificate_t*, certificate_t*))equals;
- this->public.interface.interface.get_ref = (certificate_t* (*)(certificate_t*))get_ref;
- this->public.interface.interface.destroy = (void (*)(certificate_t*))destroy;
- this->public.interface.get_challengePassword = (chunk_t (*)(pkcs10_t*))get_challengePassword;
- this->public.interface.create_subjectAltName_enumerator = (enumerator_t* (*)(pkcs10_t*))create_subjectAltName_enumerator;
-
- this->encoding = chunk_empty;
- this->certificationRequestInfo = chunk_empty;
- this->subject = NULL;
- this->public_key = NULL;
- this->subjectAltNames = linked_list_create();
- this->challengePassword = chunk_empty;
- this->signature = chunk_empty;
- this->ref = 1;
- this->self_signed = FALSE;
- this->parsed = FALSE;
+ private_x509_pkcs10_t *this;
+
+ INIT(this,
+ .public = {
+ .interface = {
+ .interface = {
+ .get_type = _get_type,
+ .get_subject = _get_subject,
+ .get_issuer = _get_subject,
+ .has_subject = _has_subject,
+ .has_issuer = _has_subject,
+ .issued_by = _issued_by,
+ .get_public_key = _get_public_key,
+ .get_validity = _get_validity,
+ .get_encoding = _get_encoding,
+ .equals = _equals,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_challengePassword = _get_challengePassword,
+ .create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
+ },
+ },
+ .subjectAltNames = linked_list_create(),
+ .ref = 1,
+ );
return this;
}
diff --git a/src/libstrongswan/plugins/x509/x509_plugin.c b/src/libstrongswan/plugins/x509/x509_plugin.c
index bfeb74b0e..ed6fbfd91 100644
--- a/src/libstrongswan/plugins/x509/x509_plugin.c
+++ b/src/libstrongswan/plugins/x509/x509_plugin.c
@@ -42,29 +42,46 @@ METHOD(plugin_t, get_name, char*,
return "x509";
}
+METHOD(plugin_t, get_features, int,
+ private_x509_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(CERT_ENCODE, x509_cert_gen, FALSE),
+ PLUGIN_PROVIDE(CERT_ENCODE, CERT_X509),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_REGISTER(CERT_DECODE, x509_cert_load, TRUE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_X509),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+
+ PLUGIN_REGISTER(CERT_ENCODE, x509_ac_gen, FALSE),
+ PLUGIN_PROVIDE(CERT_ENCODE, CERT_X509_AC),
+ PLUGIN_REGISTER(CERT_DECODE, x509_ac_load, TRUE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_AC),
+
+ PLUGIN_REGISTER(CERT_ENCODE, x509_crl_gen, FALSE),
+ PLUGIN_PROVIDE(CERT_ENCODE, CERT_X509_CRL),
+ PLUGIN_REGISTER(CERT_DECODE, x509_crl_load, TRUE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL),
+
+ PLUGIN_REGISTER(CERT_ENCODE, x509_ocsp_request_gen, FALSE),
+ PLUGIN_PROVIDE(CERT_ENCODE, CERT_X509_OCSP_REQUEST),
+ PLUGIN_DEPENDS(HASHER, HASH_SHA1),
+ PLUGIN_DEPENDS(RNG, RNG_WEAK),
+ PLUGIN_REGISTER(CERT_DECODE, x509_ocsp_response_load, TRUE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_OCSP_RESPONSE),
+
+ PLUGIN_REGISTER(CERT_ENCODE, x509_pkcs10_gen, FALSE),
+ PLUGIN_PROVIDE(CERT_ENCODE, CERT_PKCS10_REQUEST),
+ PLUGIN_REGISTER(CERT_DECODE, x509_pkcs10_load, TRUE),
+ PLUGIN_PROVIDE(CERT_DECODE, CERT_PKCS10_REQUEST),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_x509_plugin_t *this)
{
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)x509_cert_gen);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)x509_cert_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)x509_ac_gen);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)x509_ac_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)x509_crl_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)x509_crl_gen);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)x509_ocsp_request_gen);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)x509_ocsp_response_load);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)x509_pkcs10_gen);
- lib->creds->remove_builder(lib->creds,
- (builder_function_t)x509_pkcs10_load);
free(this);
}
@@ -79,33 +96,12 @@ plugin_t *x509_plugin_create()
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509, FALSE,
- (builder_function_t)x509_cert_gen);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509, TRUE,
- (builder_function_t)x509_cert_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC, FALSE,
- (builder_function_t)x509_ac_gen);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_AC, TRUE,
- (builder_function_t)x509_ac_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, TRUE,
- (builder_function_t)x509_crl_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, FALSE,
- (builder_function_t)x509_crl_gen);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_REQUEST, FALSE,
- (builder_function_t)x509_ocsp_request_gen);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_X509_OCSP_RESPONSE, TRUE,
- (builder_function_t)x509_ocsp_response_load);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST, FALSE,
- (builder_function_t)x509_pkcs10_gen);
- lib->creds->add_builder(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST, TRUE,
- (builder_function_t)x509_pkcs10_load);
-
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in
index 35f868de4..ae23ce730 100644
--- a/src/libstrongswan/plugins/xcbc/Makefile.in
+++ b/src/libstrongswan/plugins/xcbc/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/libstrongswan/plugins/xcbc/xcbc.c b/src/libstrongswan/plugins/xcbc/xcbc.c
index 8ddde962c..53629abe5 100644
--- a/src/libstrongswan/plugins/xcbc/xcbc.c
+++ b/src/libstrongswan/plugins/xcbc/xcbc.c
@@ -3,13 +3,13 @@
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General xcbc License as published by the
+ * 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 xcbc License
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
diff --git a/src/libstrongswan/plugins/xcbc/xcbc.h b/src/libstrongswan/plugins/xcbc/xcbc.h
index f28e0b8e0..5d5eb04fb 100644
--- a/src/libstrongswan/plugins/xcbc/xcbc.h
+++ b/src/libstrongswan/plugins/xcbc/xcbc.h
@@ -28,7 +28,7 @@ typedef struct xcbc_t xcbc_t;
/**
* Message authentication using CBC crypter.
*
- * This class implements the message authenticaion algorithm
+ * This class implements the message authentication algorithm
* described in RFC3566.
*/
struct xcbc_t {
diff --git a/src/libstrongswan/plugins/xcbc/xcbc_plugin.c b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c
index 0fcb093c8..3c3b9d12a 100644
--- a/src/libstrongswan/plugins/xcbc/xcbc_plugin.c
+++ b/src/libstrongswan/plugins/xcbc/xcbc_plugin.c
@@ -38,13 +38,28 @@ METHOD(plugin_t, get_name, char*,
return "xcbc";
}
+METHOD(plugin_t, get_features, int,
+ private_xcbc_plugin_t *this, plugin_feature_t *features[])
+{
+ static plugin_feature_t f[] = {
+ PLUGIN_REGISTER(PRF, xcbc_prf_create),
+ PLUGIN_PROVIDE(PRF, PRF_AES128_XCBC),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ PLUGIN_PROVIDE(PRF, PRF_CAMELLIA128_XCBC),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16),
+ PLUGIN_REGISTER(SIGNER, xcbc_signer_create),
+ PLUGIN_PROVIDE(SIGNER, AUTH_CAMELLIA_XCBC_96),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_CAMELLIA_CBC, 16),
+ PLUGIN_PROVIDE(SIGNER, AUTH_AES_XCBC_96),
+ PLUGIN_DEPENDS(CRYPTER, ENCR_AES_CBC, 16),
+ };
+ *features = f;
+ return countof(f);
+}
+
METHOD(plugin_t, destroy, void,
private_xcbc_plugin_t *this)
{
- lib->crypto->remove_prf(lib->crypto,
- (prf_constructor_t)xcbc_prf_create);
- lib->crypto->remove_signer(lib->crypto,
- (signer_constructor_t)xcbc_signer_create);
free(this);
}
@@ -54,36 +69,17 @@ METHOD(plugin_t, destroy, void,
plugin_t *xcbc_plugin_create()
{
private_xcbc_plugin_t *this;
- crypter_t *crypter;
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
- .reload = (void*)return_false,
+ .get_features = _get_features,
.destroy = _destroy,
},
},
);
- crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CBC, 16);
- if (crypter)
- {
- crypter->destroy(crypter);
- lib->crypto->add_prf(lib->crypto, PRF_AES128_XCBC, get_name(this),
- (prf_constructor_t)xcbc_prf_create);
- lib->crypto->add_signer(lib->crypto, AUTH_AES_XCBC_96, get_name(this),
- (signer_constructor_t)xcbc_signer_create);
- }
- crypter = lib->crypto->create_crypter(lib->crypto, ENCR_CAMELLIA_CBC, 16);
- if (crypter)
- {
- crypter->destroy(crypter);
- lib->crypto->add_prf(lib->crypto, PRF_CAMELLIA128_XCBC, get_name(this),
- (prf_constructor_t)xcbc_prf_create);
- lib->crypto->add_signer(lib->crypto, AUTH_CAMELLIA_XCBC_96, get_name(this),
- (signer_constructor_t)xcbc_signer_create);
- }
return &this->public.plugin;
}
diff --git a/src/libstrongswan/printf_hook.c b/src/libstrongswan/printf_hook.c
index 7e7045d69..c3b5191fd 100644
--- a/src/libstrongswan/printf_hook.c
+++ b/src/libstrongswan/printf_hook.c
@@ -173,7 +173,7 @@ static int custom_fmt_cb(Vstr_base *base, size_t pos, Vstr_fmt_spec *fmt_spec)
{
vstr_add_buf(base, pos, buf, written);
}
- return TRUE;
+ return 1;
}
/**
diff --git a/src/libstrongswan/processing/jobs/callback_job.c b/src/libstrongswan/processing/jobs/callback_job.c
index 0043a9cdb..13f22e69c 100644
--- a/src/libstrongswan/processing/jobs/callback_job.c
+++ b/src/libstrongswan/processing/jobs/callback_job.c
@@ -62,7 +62,7 @@ struct private_callback_job_t {
mutex_t *mutex;
/**
- * list of asociated child jobs
+ * list of associated child jobs
*/
linked_list_t *children;
@@ -88,6 +88,11 @@ struct private_callback_job_t {
* without risking that it gets freed too early during destruction.
*/
sem_t *terminated;
+
+ /**
+ * Priority of this job
+ */
+ job_priority_t prio;
};
/**
@@ -227,12 +232,18 @@ METHOD(job_t, execute, void,
thread_cleanup_pop(cleanup);
}
+METHOD(job_t, get_priority, job_priority_t,
+ private_callback_job_t *this)
+{
+ return this->prio;
+}
+
/*
* 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)
+callback_job_t *callback_job_create_with_prio(callback_job_cb_t cb, void *data,
+ callback_job_cleanup_t cleanup, callback_job_t *parent,
+ job_priority_t prio)
{
private_callback_job_t *this;
@@ -240,6 +251,7 @@ callback_job_t *callback_job_create(callback_job_cb_t cb, void *data,
.public = {
.job = {
.execute = _execute,
+ .get_priority = _get_priority,
.destroy = _destroy,
},
.cancel = _cancel,
@@ -251,6 +263,7 @@ callback_job_t *callback_job_create(callback_job_cb_t cb, void *data,
.children = linked_list_create(),
.parent = (private_callback_job_t*)parent,
.destroyable = condvar_create(CONDVAR_TYPE_DEFAULT),
+ .prio = prio,
);
/* register us at parent */
@@ -264,3 +277,13 @@ callback_job_t *callback_job_create(callback_job_cb_t cb, void *data,
return &this->public;
}
+/*
+ * 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)
+{
+ return callback_job_create_with_prio(cb, data, cleanup, parent,
+ JOB_PRIO_MEDIUM);
+}
diff --git a/src/libstrongswan/processing/jobs/callback_job.h b/src/libstrongswan/processing/jobs/callback_job.h
index 1eb5664d3..3e92b01c0 100644
--- a/src/libstrongswan/processing/jobs/callback_job.h
+++ b/src/libstrongswan/processing/jobs/callback_job.h
@@ -120,4 +120,20 @@ callback_job_t *callback_job_create(callback_job_cb_t cb, void *data,
callback_job_cleanup_t cleanup,
callback_job_t *parent);
+/**
+ * Creates a callback job, with priority.
+ *
+ * Same as callback_job_create(), but with different priorities than default.
+ *
+ * @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
+ * @param prio job priority
+ * @return callback_job_t object
+ */
+callback_job_t *callback_job_create_with_prio(callback_job_cb_t cb, void *data,
+ callback_job_cleanup_t cleanup, callback_job_t *parent,
+ job_priority_t prio);
+
#endif /** CALLBACK_JOB_H_ @}*/
diff --git a/src/libstrongswan/processing/jobs/job.c b/src/libstrongswan/processing/jobs/job.c
new file mode 100644
index 000000000..ccb897173
--- /dev/null
+++ b/src/libstrongswan/processing/jobs/job.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 "job.h"
+
+ENUM(job_priority_names, JOB_PRIO_CRITICAL, JOB_PRIO_LOW,
+ "critical",
+ "high",
+ "medium",
+ "low",
+);
diff --git a/src/libstrongswan/processing/jobs/job.h b/src/libstrongswan/processing/jobs/job.h
index 0f1c16ebe..d25cee03e 100644
--- a/src/libstrongswan/processing/jobs/job.h
+++ b/src/libstrongswan/processing/jobs/job.h
@@ -23,11 +23,32 @@
#define JOB_H_
typedef struct job_t job_t;
+typedef enum job_priority_t job_priority_t;
#include <library.h>
/**
- * Job-Interface as it is stored in the job queue.
+ * Priority classes of jobs
+ */
+enum job_priority_t {
+ /** Critical infrastructure jobs that should always been served */
+ JOB_PRIO_CRITICAL = 0,
+ /** Short jobs executed with highest priority */
+ JOB_PRIO_HIGH,
+ /** Default job priority */
+ JOB_PRIO_MEDIUM,
+ /** Low priority jobs with thread blocking operations */
+ JOB_PRIO_LOW,
+ JOB_PRIO_MAX
+};
+
+/**
+ * Enum names for job priorities
+ */
+extern enum_name_t *job_priority_names;
+
+/**
+ * Job interface as it is stored in the job queue.
*/
struct job_t {
@@ -41,12 +62,19 @@ struct job_t {
void (*execute) (job_t *this);
/**
+ * Get the priority of a job.
+ *
+ * @return job priority
+ */
+ job_priority_t (*get_priority)(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);
+ void (*destroy) (job_t *this);
};
#endif /** JOB_H_ @}*/
diff --git a/src/libstrongswan/processing/processor.c b/src/libstrongswan/processing/processor.c
index de556f86b..222f1a535 100644
--- a/src/libstrongswan/processing/processor.c
+++ b/src/libstrongswan/processing/processor.c
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2005-2011 Martin Willi
* Copyright (C) 2011 revosec AG
+ * Copyright (C) 2008-2011 Tobias Brunner
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -25,15 +26,16 @@
#include <threading/thread.h>
#include <threading/condvar.h>
#include <threading/mutex.h>
+#include <threading/thread_value.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.
*/
@@ -50,9 +52,9 @@ struct private_processor_t {
u_int desired_threads;
/**
- * Number of threads waiting for work
+ * Number of threads currently working, for each priority
*/
- u_int idle_threads;
+ u_int working_threads[JOB_PRIO_MAX];
/**
* All threads managed in the pool (including threads that have been
@@ -61,12 +63,22 @@ struct private_processor_t {
linked_list_t *threads;
/**
- * The jobs are stored in a linked list
+ * A list of queued jobs for each priority
+ */
+ linked_list_t *jobs[JOB_PRIO_MAX];
+
+ /**
+ * Threads reserved for each priority
+ */
+ int prio_threads[JOB_PRIO_MAX];
+
+ /**
+ * Priority of the job executed by a thread
*/
- linked_list_t *list;
+ thread_value_t *priority;
/**
- * access to linked_list is locked through this mutex
+ * access to job lists is locked through this mutex
*/
mutex_t *mutex;
@@ -90,7 +102,7 @@ static void restart(private_processor_t *this)
{
thread_t *thread;
- DBG2(DBG_JOB, "terminated worker thread, ID: %u", thread_current_id());
+ DBG2(DBG_JOB, "terminated worker thread %.2u", thread_current_id());
/* respawn thread if required */
this->mutex->lock(this->mutex);
@@ -108,6 +120,31 @@ static void restart(private_processor_t *this)
}
/**
+ * Decrement working thread count of a priority class
+ */
+static void decrement_working_threads(private_processor_t *this)
+{
+ this->mutex->lock(this->mutex);
+ this->working_threads[(intptr_t)this->priority->get(this->priority)]--;
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Get number of idle threads, non-locking variant
+ */
+static u_int get_idle_threads_nolock(private_processor_t *this)
+{
+ u_int count, i;
+
+ count = this->total_threads;
+ for (i = 0; i < JOB_PRIO_MAX; i++)
+ {
+ count -= this->working_threads[i];
+ }
+ return count;
+}
+
+/**
* Process queued jobs, called by the worker threads
*/
static void process_jobs(private_processor_t *this)
@@ -115,27 +152,51 @@ 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());
+ DBG2(DBG_JOB, "started worker thread %.2u", thread_current_id());
this->mutex->lock(this->mutex);
while (this->desired_threads >= this->total_threads)
{
- job_t *job;
+ job_t *job = NULL;
+ int i, reserved = 0, idle;
- if (this->list->get_count(this->list) == 0)
+ idle = get_idle_threads_nolock(this);
+
+ for (i = 0; i < JOB_PRIO_MAX; i++)
+ {
+ if (reserved && reserved >= idle)
+ {
+ DBG2(DBG_JOB, "delaying %N priority jobs: %d threads idle, "
+ "but %d reserved for higher priorities",
+ job_priority_names, i, idle, reserved);
+ break;
+ }
+ if (this->working_threads[i] < this->prio_threads[i])
+ {
+ reserved += this->prio_threads[i] - this->working_threads[i];
+ }
+ if (this->jobs[i]->remove_first(this->jobs[i],
+ (void**)&job) == SUCCESS)
+ {
+ this->working_threads[i]++;
+ this->mutex->unlock(this->mutex);
+ this->priority->set(this->priority, (void*)(intptr_t)i);
+ /* terminated threads are restarted to get a constant pool */
+ thread_cleanup_push((thread_cleanup_t)restart, this);
+ thread_cleanup_push((thread_cleanup_t)decrement_working_threads,
+ this);
+ job->execute(job);
+ thread_cleanup_pop(FALSE);
+ thread_cleanup_pop(FALSE);
+ this->mutex->lock(this->mutex);
+ this->working_threads[i]--;
+ break;
+ }
+ }
+ if (!job)
{
- 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->total_threads--;
this->thread_terminated->signal(this->thread_terminated);
@@ -159,18 +220,42 @@ METHOD(processor_t, get_idle_threads, u_int,
u_int count;
this->mutex->lock(this->mutex);
- count = this->idle_threads;
+ count = get_idle_threads_nolock(this);
+ this->mutex->unlock(this->mutex);
+ return count;
+}
+
+/**
+ * Check priority bounds
+ */
+static job_priority_t sane_prio(job_priority_t prio)
+{
+ if ((int)prio < 0 || prio >= JOB_PRIO_MAX)
+ {
+ return JOB_PRIO_MAX - 1;
+ }
+ return prio;
+}
+
+METHOD(processor_t, get_working_threads, u_int,
+ private_processor_t *this, job_priority_t prio)
+{
+ u_int count;
+
+ this->mutex->lock(this->mutex);
+ count = this->working_threads[sane_prio(prio)];
this->mutex->unlock(this->mutex);
return count;
}
METHOD(processor_t, get_job_load, u_int,
- private_processor_t *this)
+ private_processor_t *this, job_priority_t prio)
{
u_int load;
+ prio = sane_prio(prio);
this->mutex->lock(this->mutex);
- load = this->list->get_count(this->list);
+ load = this->jobs[prio]->get_count(this->jobs[prio]);
this->mutex->unlock(this->mutex);
return load;
}
@@ -178,8 +263,11 @@ METHOD(processor_t, get_job_load, u_int,
METHOD(processor_t, queue_job, void,
private_processor_t *this, job_t *job)
{
+ job_priority_t prio;
+
+ prio = sane_prio(job->get_priority(job));
this->mutex->lock(this->mutex);
- this->list->insert_last(this->list, job);
+ this->jobs[prio]->insert_last(this->jobs[prio], job);
this->job_added->signal(this->job_added);
this->mutex->unlock(this->mutex);
}
@@ -217,6 +305,7 @@ METHOD(processor_t, destroy, void,
private_processor_t *this)
{
thread_t *current;
+ int i;
set_threads(this, 0);
this->mutex->lock(this->mutex);
@@ -231,10 +320,14 @@ METHOD(processor_t, destroy, void,
current->join(current);
}
this->mutex->unlock(this->mutex);
+ this->priority->destroy(this->priority);
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));
+ for (i = 0; i < JOB_PRIO_MAX; i++)
+ {
+ this->jobs[i]->destroy_offset(this->jobs[i], offsetof(job_t, destroy));
+ }
this->threads->destroy(this->threads);
free(this);
}
@@ -245,22 +338,31 @@ METHOD(processor_t, destroy, void,
processor_t *processor_create()
{
private_processor_t *this;
+ int i;
INIT(this,
.public = {
.get_total_threads = _get_total_threads,
.get_idle_threads = _get_idle_threads,
+ .get_working_threads = _get_working_threads,
.get_job_load = _get_job_load,
.queue_job = _queue_job,
.set_threads = _set_threads,
.destroy = _destroy,
},
- .list = linked_list_create(),
.threads = linked_list_create(),
+ .priority = thread_value_create(NULL),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.job_added = condvar_create(CONDVAR_TYPE_DEFAULT),
.thread_terminated = condvar_create(CONDVAR_TYPE_DEFAULT),
);
+ for (i = 0; i < JOB_PRIO_MAX; i++)
+ {
+ this->jobs[i] = linked_list_create();
+ this->prio_threads[i] = lib->settings->get_int(lib->settings,
+ "libstrongswan.processor.priority_threads.%N", 0,
+ job_priority_names, i);
+ }
return &this->public;
}
diff --git a/src/libstrongswan/processing/processor.h b/src/libstrongswan/processing/processor.h
index bebbe3a15..5db42c04c 100644
--- a/src/libstrongswan/processing/processor.h
+++ b/src/libstrongswan/processing/processor.h
@@ -42,18 +42,27 @@ struct processor_t {
u_int (*get_total_threads) (processor_t *this);
/**
- * Get the number of threads currently waiting.
+ * Get the number of threads currently waiting for work.
*
* @return number of idle threads
*/
u_int (*get_idle_threads) (processor_t *this);
/**
- * Get the number of queued jobs.
+ * Get the number of threads currently working, per priority class.
*
+ * @param prioritiy to check
+ * @return number of threads in priority working
+ */
+ u_int (*get_working_threads)(processor_t *this, job_priority_t prio);
+
+ /**
+ * Get the number of queued jobs for a specified priority.
+ *
+ * @param prio priority class to get job load for
* @return number of items in queue
*/
- u_int (*get_job_load) (processor_t *this);
+ u_int (*get_job_load) (processor_t *this, job_priority_t prio);
/**
* Adds a job to the queue.
diff --git a/src/libstrongswan/processing/scheduler.c b/src/libstrongswan/processing/scheduler.c
index 7d9bcd70f..f3cc1164a 100644
--- a/src/libstrongswan/processing/scheduler.c
+++ b/src/libstrongswan/processing/scheduler.c
@@ -341,7 +341,8 @@ scheduler_t * scheduler_create()
this->heap = (event_t**)calloc(this->heap_size + 1, sizeof(event_t*));
- this->job = callback_job_create((callback_job_cb_t)schedule, this, NULL, NULL);
+ this->job = callback_job_create_with_prio((callback_job_cb_t)schedule,
+ this, NULL, NULL, JOB_PRIO_CRITICAL);
lib->processor->queue_job(lib->processor, (job_t*)this->job);
return &this->public;
diff --git a/src/libstrongswan/processing/scheduler.h b/src/libstrongswan/processing/scheduler.h
index f2c72550f..abbf74e2c 100644
--- a/src/libstrongswan/processing/scheduler.h
+++ b/src/libstrongswan/processing/scheduler.h
@@ -35,7 +35,7 @@ typedef struct scheduler_t scheduler_t;
* 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
+ * We use a min-heap with 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
diff --git a/src/libstrongswan/selectors/traffic_selector.c b/src/libstrongswan/selectors/traffic_selector.c
index 32da194ef..b1bcf1b2d 100644
--- a/src/libstrongswan/selectors/traffic_selector.c
+++ b/src/libstrongswan/selectors/traffic_selector.c
@@ -24,6 +24,7 @@
#include <utils/linked_list.h>
#include <utils/identification.h>
+#include <debug.h>
#define NON_SUBNET_ADDRESS_RANGE 255
@@ -61,7 +62,7 @@ struct private_traffic_selector_t {
bool dynamic;
/**
- * subnet size in CIDR notation, 255 means a non-subnet address range
+ * subnet size in CIDR notation, 255 means a non-subnet address range
*/
u_int8_t netbits;
@@ -129,12 +130,12 @@ static void calc_range(private_traffic_selector_t *this, u_int8_t netbits)
static u_int8_t calc_netbits(private_traffic_selector_t *this)
{
int byte, bit;
- u_int8_t netbits;
+ u_int8_t netbits;
size_t size = (this->type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
bool prefix = TRUE;
-
+
/* a perfect match results in a single address with a /32 or /128 netmask */
- netbits = (size * 8);
+ netbits = (size * 8);
this->netbits = netbits;
/* go through all bits of the addresses, beginning in the front.
@@ -152,7 +153,7 @@ static u_int8_t calc_netbits(private_traffic_selector_t *this)
{
/* store the common prefix which might be a true subnet */
netbits = (7 - bit) + (byte * 8);
- this->netbits = netbits;
+ this->netbits = netbits;
prefix = FALSE;
}
}
@@ -164,7 +165,7 @@ static u_int8_t calc_netbits(private_traffic_selector_t *this)
return netbits; /* return a pseudo subnet */
}
- }
+ }
}
}
return netbits; /* return a true subnet */
@@ -183,7 +184,7 @@ int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec
{
private_traffic_selector_t *this = *((private_traffic_selector_t**)(args[0]));
linked_list_t *list = *((linked_list_t**)(args[0]));
- iterator_t *iterator;
+ enumerator_t *enumerator;
char from_str[INET6_ADDRSTRLEN] = "";
char to_str[INET6_ADDRSTRLEN] = "";
char *serv_proto = NULL;
@@ -199,13 +200,13 @@ int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec
if (spec->hash)
{
- iterator = list->create_iterator(list, TRUE);
- while (iterator->iterate(iterator, (void**)&this))
+ enumerator = list->create_enumerator(list);
+ while (enumerator->enumerate(enumerator, (void**)&this))
{
/* call recursivly */
written += print_in_hook(dst, len, "%R ", this);
}
- iterator->destroy(iterator);
+ enumerator->destroy(enumerator);
return written;
}
@@ -305,7 +306,7 @@ int traffic_selector_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec
}
/**
- * implements traffic_selector_t.get_subset
+ * Implements traffic_selector_t.get_subset
*/
static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_traffic_selector_t *other)
{
@@ -376,7 +377,7 @@ static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_
}
/**
- * implements traffic_selector_t.equals
+ * Implements traffic_selector_t.equals
*/
static bool equals(private_traffic_selector_t *this, private_traffic_selector_t *other)
{
@@ -412,10 +413,8 @@ static bool equals(private_traffic_selector_t *this, private_traffic_selector_t
return FALSE;
}
-/**
- * Implements traffic_selector_t.get_from_address.
- */
-static chunk_t get_from_address(private_traffic_selector_t *this)
+METHOD(traffic_selector_t, get_from_address, chunk_t,
+ private_traffic_selector_t *this)
{
switch (this->type)
{
@@ -428,10 +427,8 @@ static chunk_t get_from_address(private_traffic_selector_t *this)
}
}
-/**
- * Implements traffic_selector_t.get_to_address.
- */
-static chunk_t get_to_address(private_traffic_selector_t *this)
+METHOD(traffic_selector_t, get_to_address, chunk_t,
+ private_traffic_selector_t *this)
{
switch (this->type)
{
@@ -444,42 +441,32 @@ static chunk_t get_to_address(private_traffic_selector_t *this)
}
}
-/**
- * Implements traffic_selector_t.get_from_port.
- */
-static u_int16_t get_from_port(private_traffic_selector_t *this)
+METHOD(traffic_selector_t, get_from_port, u_int16_t,
+ private_traffic_selector_t *this)
{
return this->from_port;
}
-/**
- * Implements traffic_selector_t.get_to_port.
- */
-static u_int16_t get_to_port(private_traffic_selector_t *this)
+METHOD(traffic_selector_t, get_to_port, u_int16_t,
+ private_traffic_selector_t *this)
{
return this->to_port;
}
-/**
- * Implements traffic_selector_t.get_type.
- */
-static ts_type_t get_type(private_traffic_selector_t *this)
+METHOD(traffic_selector_t, get_type, ts_type_t,
+ private_traffic_selector_t *this)
{
return this->type;
}
-/**
- * Implements traffic_selector_t.get_protocol.
- */
-static u_int8_t get_protocol(private_traffic_selector_t *this)
+METHOD(traffic_selector_t, get_protocol, u_int8_t,
+ private_traffic_selector_t *this)
{
return this->protocol;
}
-/**
- * Implements traffic_selector_t.is_host.
- */
-static bool is_host(private_traffic_selector_t *this, host_t *host)
+METHOD(traffic_selector_t, is_host, bool,
+ private_traffic_selector_t *this, host_t *host)
{
if (host)
{
@@ -514,18 +501,14 @@ static bool is_host(private_traffic_selector_t *this, host_t *host)
return FALSE;
}
-/**
- * Implementation of traffic_selector_t.is_dynamic
- */
-static bool is_dynamic(private_traffic_selector_t *this)
+METHOD(traffic_selector_t, is_dynamic, bool,
+ private_traffic_selector_t *this)
{
return this->dynamic;
}
-/**
- * Implements traffic_selector_t.set_address.
- */
-static void set_address(private_traffic_selector_t *this, host_t *host)
+METHOD(traffic_selector_t, set_address, void,
+ private_traffic_selector_t *this, host_t *host)
{
if (this->dynamic)
{
@@ -570,10 +553,8 @@ static bool is_contained_in(private_traffic_selector_t *this,
return contained_in;
}
-/**
- * Implements traffic_selector_t.includes.
- */
-static bool includes(private_traffic_selector_t *this, host_t *host)
+METHOD(traffic_selector_t, includes, bool,
+ private_traffic_selector_t *this, host_t *host)
{
chunk_t addr;
int family = host->get_family(host);
@@ -590,16 +571,14 @@ static bool includes(private_traffic_selector_t *this, host_t *host)
return FALSE;
}
-/**
- * Implements traffic_selector_t.to_subnet.
- */
-static void to_subnet(private_traffic_selector_t *this, host_t **net, u_int8_t *mask)
+METHOD(traffic_selector_t, to_subnet, void,
+ private_traffic_selector_t *this, host_t **net, u_int8_t *mask)
{
/* there is no way to do this cleanly, as the address range may
* be anything else but a subnet. We use from_addr as subnet
* and try to calculate a usable subnet mask.
*/
- int family, byte;
+ int family, non_zero_bytes;
u_int16_t port = 0;
chunk_t net_chunk;
@@ -622,12 +601,12 @@ static void to_subnet(private_traffic_selector_t *this, host_t **net, u_int8_t *
}
net_chunk.ptr = malloc(net_chunk.len);
- memcpy(net_chunk.ptr, this->from, net_chunk.len);
-
- for (byte = net_chunk.len - 1; byte >= (*mask / 8); --byte)
+ memset(net_chunk.ptr, 0x00, net_chunk.len);
+ if (*mask)
{
- int shift = (byte + 1) * 8 - *mask;
- net_chunk.ptr[byte] = net_chunk.ptr[byte] & (0xFF << shift);
+ non_zero_bytes = (*mask + 7) / 8;
+ memcpy(net_chunk.ptr, this->from, non_zero_bytes);
+ net_chunk.ptr[non_zero_bytes-1] &= 0xFF << (8 * non_zero_bytes - *mask);
}
if (this->to_port == this->from_port)
@@ -639,10 +618,8 @@ static void to_subnet(private_traffic_selector_t *this, host_t **net, u_int8_t *
chunk_free(&net_chunk);
}
-/**
- * Implements traffic_selector_t.clone.
- */
-static traffic_selector_t *clone_(private_traffic_selector_t *this)
+METHOD(traffic_selector_t, clone_, traffic_selector_t*,
+ private_traffic_selector_t *this)
{
private_traffic_selector_t *clone;
@@ -667,10 +644,8 @@ static traffic_selector_t *clone_(private_traffic_selector_t *this)
}
}
-/**
- * Implements traffic_selector_t.destroy.
- */
-static void destroy(private_traffic_selector_t *this)
+METHOD(traffic_selector_t, destroy, void,
+ private_traffic_selector_t *this)
{
free(this);
}
@@ -887,31 +862,32 @@ traffic_selector_t *traffic_selector_create_dynamic(u_int8_t protocol,
static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol,
ts_type_t type, u_int16_t from_port, u_int16_t to_port)
{
- private_traffic_selector_t *this = malloc_thing(private_traffic_selector_t);
-
- /* public functions */
- this->public.get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset;
- this->public.equals = (bool(*)(traffic_selector_t*,traffic_selector_t*))equals;
- this->public.get_from_address = (chunk_t(*)(traffic_selector_t*))get_from_address;
- this->public.get_to_address = (chunk_t(*)(traffic_selector_t*))get_to_address;
- this->public.get_from_port = (u_int16_t(*)(traffic_selector_t*))get_from_port;
- this->public.get_to_port = (u_int16_t(*)(traffic_selector_t*))get_to_port;
- this->public.get_type = (ts_type_t(*)(traffic_selector_t*))get_type;
- this->public.get_protocol = (u_int8_t(*)(traffic_selector_t*))get_protocol;
- this->public.is_host = (bool(*)(traffic_selector_t*,host_t*))is_host;
- this->public.is_dynamic = (bool(*)(traffic_selector_t*))is_dynamic;
- this->public.is_contained_in = (bool(*)(traffic_selector_t*,traffic_selector_t*))is_contained_in;
- this->public.includes = (bool(*)(traffic_selector_t*,host_t*))includes;
- this->public.set_address = (void(*)(traffic_selector_t*,host_t*))set_address;
- this->public.to_subnet = (void(*)(traffic_selector_t*,host_t**,u_int8_t*))to_subnet;
- this->public.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone_;
- this->public.destroy = (void(*)(traffic_selector_t*))destroy;
-
- this->from_port = from_port;
- this->to_port = to_port;
- this->protocol = protocol;
- this->type = type;
- this->dynamic = FALSE;
+ private_traffic_selector_t *this;
+
+ INIT(this,
+ .public = {
+ .get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset,
+ .equals = (bool(*)(traffic_selector_t*,traffic_selector_t*))equals,
+ .get_from_address = _get_from_address,
+ .get_to_address = _get_to_address,
+ .get_from_port = _get_from_port,
+ .get_to_port = _get_to_port,
+ .get_type = _get_type,
+ .get_protocol = _get_protocol,
+ .is_host = _is_host,
+ .is_dynamic = _is_dynamic,
+ .is_contained_in = (bool(*)(traffic_selector_t*,traffic_selector_t*))is_contained_in,
+ .includes = _includes,
+ .set_address = _set_address,
+ .to_subnet = _to_subnet,
+ .clone = _clone_,
+ .destroy = _destroy,
+ },
+ .from_port = from_port,
+ .to_port = to_port,
+ .protocol = protocol,
+ .type = type,
+ );
return this;
}
diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c
index 8a2248b46..b26fbebb4 100644
--- a/src/libstrongswan/settings.c
+++ b/src/libstrongswan/settings.c
@@ -965,6 +965,7 @@ static bool parse_file(linked_list_t *contents, char *file, int level,
if (fread(text, 1, len, fd) != len)
{
free(text);
+ fclose(fd);
return FALSE;
}
fclose(fd);
diff --git a/src/libstrongswan/settings.h b/src/libstrongswan/settings.h
index 9ccd02327..a864779f1 100644
--- a/src/libstrongswan/settings.h
+++ b/src/libstrongswan/settings.h
@@ -110,7 +110,7 @@ u_int32_t settings_value_as_time(char *value, u_int32_t def);
* already existing values are replaced.
*
* All settings included from files are added relative to the section the
- * include statment is in.
+ * include statement is in.
*
* The following files result in the same final config as above:
*
diff --git a/src/libstrongswan/threading/mutex.c b/src/libstrongswan/threading/mutex.c
index 8597abb44..3bdb3bf29 100644
--- a/src/libstrongswan/threading/mutex.c
+++ b/src/libstrongswan/threading/mutex.c
@@ -96,11 +96,8 @@ struct private_condvar_t {
};
-
-/**
- * Implementation of mutex_t.lock.
- */
-static void lock(private_mutex_t *this)
+METHOD(mutex_t, lock, void,
+ private_mutex_t *this)
{
int err;
@@ -113,10 +110,8 @@ static void lock(private_mutex_t *this)
profiler_end(&this->profile);
}
-/**
- * Implementation of mutex_t.unlock.
- */
-static void unlock(private_mutex_t *this)
+METHOD(mutex_t, unlock, void,
+ private_mutex_t *this)
{
int err;
@@ -127,10 +122,8 @@ static void unlock(private_mutex_t *this)
}
}
-/**
- * Implementation of mutex_t.lock.
- */
-static void lock_r(private_r_mutex_t *this)
+METHOD(mutex_t, lock_r, void,
+ private_r_mutex_t *this)
{
pthread_t self = pthread_self();
@@ -151,10 +144,8 @@ static void lock_r(private_r_mutex_t *this)
}
}
-/**
- * Implementation of mutex_t.unlock.
- */
-static void unlock_r(private_r_mutex_t *this)
+METHOD(mutex_t, unlock_r, void,
+ private_r_mutex_t *this)
{
uintptr_t times;
@@ -169,20 +160,16 @@ static void unlock_r(private_r_mutex_t *this)
}
}
-/**
- * Implementation of mutex_t.destroy
- */
-static void mutex_destroy(private_mutex_t *this)
+METHOD(mutex_t, mutex_destroy, void,
+ private_mutex_t *this)
{
profiler_cleanup(&this->profile);
pthread_mutex_destroy(&this->mutex);
free(this);
}
-/**
- * Implementation of mutex_t.destroy for recursive mutex'
- */
-static void mutex_destroy_r(private_r_mutex_t *this)
+METHOD(mutex_t, mutex_destroy_r, void,
+ private_r_mutex_t *this)
{
profiler_cleanup(&this->generic.profile);
pthread_mutex_destroy(&this->generic.mutex);
@@ -199,31 +186,39 @@ mutex_t *mutex_create(mutex_type_t type)
{
case MUTEX_TYPE_RECURSIVE:
{
- private_r_mutex_t *this = malloc_thing(private_r_mutex_t);
-
- this->generic.public.lock = (void(*)(mutex_t*))lock_r;
- this->generic.public.unlock = (void(*)(mutex_t*))unlock_r;
- this->generic.public.destroy = (void(*)(mutex_t*))mutex_destroy_r;
+ private_r_mutex_t *this;
+
+ INIT(this,
+ .generic = {
+ .public = {
+ .lock = _lock_r,
+ .unlock = _unlock_r,
+ .destroy = _mutex_destroy_r,
+ },
+ .recursive = TRUE,
+ },
+ );
pthread_mutex_init(&this->generic.mutex, NULL);
pthread_key_create(&this->times, NULL);
- this->generic.recursive = TRUE;
profiler_init(&this->generic.profile);
- this->thread = 0;
return &this->generic.public;
}
case MUTEX_TYPE_DEFAULT:
default:
{
- private_mutex_t *this = malloc_thing(private_mutex_t);
+ private_mutex_t *this;
- this->public.lock = (void(*)(mutex_t*))lock;
- this->public.unlock = (void(*)(mutex_t*))unlock;
- this->public.destroy = (void(*)(mutex_t*))mutex_destroy;
+ INIT(this,
+ .public = {
+ .lock = _lock,
+ .unlock = _unlock,
+ .destroy = _mutex_destroy,
+ },
+ );
pthread_mutex_init(&this->mutex, NULL);
- this->recursive = FALSE;
profiler_init(&this->profile);
return &this->public;
@@ -232,11 +227,8 @@ mutex_t *mutex_create(mutex_type_t type)
}
-
-/**
- * Implementation of condvar_t.wait.
- */
-static void _wait(private_condvar_t *this, private_mutex_t *mutex)
+METHOD(condvar_t, wait_, void,
+ private_condvar_t *this, private_mutex_t *mutex)
{
if (mutex->recursive)
{
@@ -258,11 +250,8 @@ static void _wait(private_condvar_t *this, private_mutex_t *mutex)
#define pthread_cond_timedwait pthread_cond_timedwait_monotonic
#endif
-/**
- * Implementation of condvar_t.timed_wait_abs.
- */
-static bool timed_wait_abs(private_condvar_t *this, private_mutex_t *mutex,
- timeval_t time)
+METHOD(condvar_t, timed_wait_abs, bool,
+ private_condvar_t *this, private_mutex_t *mutex, timeval_t time)
{
struct timespec ts;
bool timed_out;
@@ -287,11 +276,8 @@ static bool timed_wait_abs(private_condvar_t *this, private_mutex_t *mutex,
return timed_out;
}
-/**
- * Implementation of condvar_t.timed_wait.
- */
-static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex,
- u_int timeout)
+METHOD(condvar_t, timed_wait, bool,
+ private_condvar_t *this, private_mutex_t *mutex, u_int timeout)
{
timeval_t tv;
u_int s, ms;
@@ -312,26 +298,20 @@ static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex,
return timed_wait_abs(this, mutex, tv);
}
-/**
- * Implementation of condvar_t.signal.
- */
-static void _signal(private_condvar_t *this)
+METHOD(condvar_t, signal_, void,
+ private_condvar_t *this)
{
pthread_cond_signal(&this->condvar);
}
-/**
- * Implementation of condvar_t.broadcast.
- */
-static void broadcast(private_condvar_t *this)
+METHOD(condvar_t, broadcast, void,
+ private_condvar_t *this)
{
pthread_cond_broadcast(&this->condvar);
}
-/**
- * Implementation of condvar_t.destroy
- */
-static void condvar_destroy(private_condvar_t *this)
+METHOD(condvar_t, condvar_destroy, void,
+ private_condvar_t *this)
{
pthread_cond_destroy(&this->condvar);
free(this);
@@ -347,14 +327,18 @@ condvar_t *condvar_create(condvar_type_t type)
case CONDVAR_TYPE_DEFAULT:
default:
{
- private_condvar_t *this = malloc_thing(private_condvar_t);
-
- this->public.wait = (void(*)(condvar_t*, mutex_t *mutex))_wait;
- this->public.timed_wait = (bool(*)(condvar_t*, mutex_t *mutex, u_int timeout))timed_wait;
- this->public.timed_wait_abs = (bool(*)(condvar_t*, mutex_t *mutex, timeval_t time))timed_wait_abs;
- this->public.signal = (void(*)(condvar_t*))_signal;
- this->public.broadcast = (void(*)(condvar_t*))broadcast;
- this->public.destroy = (void(*)(condvar_t*))condvar_destroy;
+ private_condvar_t *this;
+
+ INIT(this,
+ .public = {
+ .wait = (void*)_wait_,
+ .timed_wait = (void*)_timed_wait,
+ .timed_wait_abs = (void*)_timed_wait_abs,
+ .signal = _signal_,
+ .broadcast = _broadcast,
+ .destroy = _condvar_destroy,
+ }
+ );
#ifdef HAVE_PTHREAD_CONDATTR_INIT
{
diff --git a/src/libstrongswan/threading/rwlock.c b/src/libstrongswan/threading/rwlock.c
index cec43f59c..15dc0b334 100644
--- a/src/libstrongswan/threading/rwlock.c
+++ b/src/libstrongswan/threading/rwlock.c
@@ -87,10 +87,8 @@ struct private_rwlock_t {
#ifdef HAVE_PTHREAD_RWLOCK_INIT
-/**
- * Implementation of rwlock_t.read_lock
- */
-static void read_lock(private_rwlock_t *this)
+METHOD(rwlock_t, read_lock, void,
+ private_rwlock_t *this)
{
int err;
@@ -103,10 +101,8 @@ static void read_lock(private_rwlock_t *this)
profiler_end(&this->profile);
}
-/**
- * Implementation of rwlock_t.write_lock
- */
-static void write_lock(private_rwlock_t *this)
+METHOD(rwlock_t, write_lock, void,
+ private_rwlock_t *this)
{
int err;
@@ -119,18 +115,14 @@ static void write_lock(private_rwlock_t *this)
profiler_end(&this->profile);
}
-/**
- * Implementation of rwlock_t.try_write_lock
- */
-static bool try_write_lock(private_rwlock_t *this)
+METHOD(rwlock_t, try_write_lock, bool,
+ private_rwlock_t *this)
{
return pthread_rwlock_trywrlock(&this->rwlock) == 0;
}
-/**
- * Implementation of rwlock_t.unlock
- */
-static void rw_unlock(private_rwlock_t *this)
+METHOD(rwlock_t, unlock, void,
+ private_rwlock_t *this)
{
int err;
@@ -141,10 +133,8 @@ static void rw_unlock(private_rwlock_t *this)
}
}
-/**
- * Implementation of rwlock_t.destroy
- */
-static void rw_destroy(private_rwlock_t *this)
+METHOD(rwlock_t, destroy, void,
+ private_rwlock_t *this)
{
pthread_rwlock_destroy(&this->rwlock);
profiler_cleanup(&this->profile);
@@ -161,13 +151,17 @@ rwlock_t *rwlock_create(rwlock_type_t type)
case RWLOCK_TYPE_DEFAULT:
default:
{
- private_rwlock_t *this = malloc_thing(private_rwlock_t);
-
- this->public.read_lock = (void(*)(rwlock_t*))read_lock;
- this->public.write_lock = (void(*)(rwlock_t*))write_lock;
- this->public.try_write_lock = (bool(*)(rwlock_t*))try_write_lock;
- this->public.unlock = (void(*)(rwlock_t*))rw_unlock;
- this->public.destroy = (void(*)(rwlock_t*))rw_destroy;
+ private_rwlock_t *this;
+
+ INIT(this,
+ .public = {
+ .read_lock = _read_lock,
+ .write_lock = _write_lock,
+ .try_write_lock = _try_write_lock,
+ .unlock = _unlock,
+ .destroy = _destroy,
+ }
+ );
pthread_rwlock_init(&this->rwlock, NULL);
profiler_init(&this->profile);
@@ -200,10 +194,8 @@ rwlock_t *rwlock_create(rwlock_type_t type)
* checked or enforced so behave yourself to prevent deadlocks).
*/
-/**
- * Implementation of rwlock_t.read_lock
- */
-static void read_lock(private_rwlock_t *this)
+METHOD(rwlock_t, read_lock, void,
+ private_rwlock_t *this)
{
profiler_start(&this->profile);
this->mutex->lock(this->mutex);
@@ -216,10 +208,8 @@ static void read_lock(private_rwlock_t *this)
this->mutex->unlock(this->mutex);
}
-/**
- * Implementation of rwlock_t.write_lock
- */
-static void write_lock(private_rwlock_t *this)
+METHOD(rwlock_t, write_lock, void,
+ private_rwlock_t *this)
{
profiler_start(&this->profile);
this->mutex->lock(this->mutex);
@@ -234,10 +224,8 @@ static void write_lock(private_rwlock_t *this)
this->mutex->unlock(this->mutex);
}
-/**
- * Implementation of rwlock_t.try_write_lock
- */
-static bool try_write_lock(private_rwlock_t *this)
+METHOD(rwlock_t, try_write_lock, bool,
+ private_rwlock_t *this)
{
bool res = FALSE;
this->mutex->lock(this->mutex);
@@ -250,10 +238,8 @@ static bool try_write_lock(private_rwlock_t *this)
return res;
}
-/**
- * Implementation of rwlock_t.unlock
- */
-static void rw_unlock(private_rwlock_t *this)
+METHOD(rwlock_t, unlock, void,
+ private_rwlock_t *this)
{
this->mutex->lock(this->mutex);
if (this->writer == pthread_self())
@@ -279,10 +265,8 @@ static void rw_unlock(private_rwlock_t *this)
this->mutex->unlock(this->mutex);
}
-/**
- * Implementation of rwlock_t.destroy
- */
-static void rw_destroy(private_rwlock_t *this)
+METHOD(rwlock_t, destroy, void,
+ private_rwlock_t *this)
{
this->mutex->destroy(this->mutex);
this->writers->destroy(this->writers);
@@ -301,20 +285,20 @@ rwlock_t *rwlock_create(rwlock_type_t type)
case RWLOCK_TYPE_DEFAULT:
default:
{
- private_rwlock_t *this = malloc_thing(private_rwlock_t);
-
- this->public.read_lock = (void(*)(rwlock_t*))read_lock;
- this->public.write_lock = (void(*)(rwlock_t*))write_lock;
- this->public.try_write_lock = (bool(*)(rwlock_t*))try_write_lock;
- this->public.unlock = (void(*)(rwlock_t*))rw_unlock;
- this->public.destroy = (void(*)(rwlock_t*))rw_destroy;
-
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
- this->writers = condvar_create(CONDVAR_TYPE_DEFAULT);
- this->readers = condvar_create(CONDVAR_TYPE_DEFAULT);
- this->waiting_writers = 0;
- this->reader_count = 0;
- this->writer = 0;
+ private_rwlock_t *this;
+
+ INIT(this,
+ .public = {
+ .read_lock = _read_lock,
+ .write_lock = _write_lock,
+ .try_write_lock = _try_write_lock,
+ .unlock = _unlock,
+ .destroy = _destroy,
+ },
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ .writers = condvar_create(CONDVAR_TYPE_DEFAULT),
+ .readers = condvar_create(CONDVAR_TYPE_DEFAULT),
+ );
profiler_init(&this->profile);
diff --git a/src/libstrongswan/threading/thread.c b/src/libstrongswan/threading/thread.c
index fcc0019d8..49a1b8430 100644
--- a/src/libstrongswan/threading/thread.c
+++ b/src/libstrongswan/threading/thread.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Tobias Brunner
+ * Copyright (C) 2009-2012 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,6 +18,19 @@
#include <signal.h>
#include <semaphore.h>
+#ifdef HAVE_GETTID
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_GETTID
+#include <sys/syscall.h>
+static inline pid_t gettid()
+{
+ return syscall(SYS_gettid);
+}
+#endif
+
#include <library.h>
#include <debug.h>
@@ -113,6 +126,7 @@ static mutex_t *id_mutex;
*/
static thread_value_t *current_thread;
+
#ifndef HAVE_PTHREAD_CANCEL
/* if pthread_cancel is not available, we emulate it using a signal */
#define SIG_CANCEL (SIGRTMIN+7)
@@ -146,10 +160,8 @@ static void thread_destroy(private_thread_t *this)
free(this);
}
-/**
- * Implementation of thread_t.cancel.
- */
-static void cancel(private_thread_t *this)
+METHOD(thread_t, cancel, void,
+ private_thread_t *this)
{
this->mutex->lock(this->mutex);
if (pthread_equal(this->thread_id, pthread_self()))
@@ -166,10 +178,8 @@ static void cancel(private_thread_t *this)
this->mutex->unlock(this->mutex);
}
-/**
- * Implementation of thread_t.kill.
- */
-static void _kill(private_thread_t *this, int sig)
+METHOD(thread_t, kill_, void,
+ private_thread_t *this, int sig)
{
this->mutex->lock(this->mutex);
if (pthread_equal(this->thread_id, pthread_self()))
@@ -187,10 +197,8 @@ static void _kill(private_thread_t *this, int sig)
this->mutex->unlock(this->mutex);
}
-/**
- * Implementation of thread_t.detach.
- */
-static void detach(private_thread_t *this)
+METHOD(thread_t, detach, void,
+ private_thread_t *this)
{
this->mutex->lock(this->mutex);
pthread_detach(this->thread_id);
@@ -198,10 +206,8 @@ static void detach(private_thread_t *this)
thread_destroy(this);
}
-/**
- * Implementation of thread_t.join.
- */
-static void *join(private_thread_t *this)
+METHOD(thread_t, join, void*,
+ private_thread_t *this)
{
pthread_t thread_id;
void *val;
@@ -241,22 +247,19 @@ static void *join(private_thread_t *this)
*/
static private_thread_t *thread_create_internal()
{
- private_thread_t *this = malloc_thing(private_thread_t);
-
- this->public.cancel = (void(*)(thread_t*))cancel;
- this->public.kill = (void(*)(thread_t*,int))_kill;
- this->public.detach = (void(*)(thread_t*))detach;
- this->public.join = (void*(*)(thread_t*))join;
-
- this->id = 0;
- this->thread_id = 0;
- this->main = NULL;
- this->arg = NULL;
- this->cleanup_handlers = linked_list_create();
- this->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
+ private_thread_t *this;
+
+ INIT(this,
+ .public = {
+ .cancel = _cancel,
+ .kill = _kill_,
+ .detach = _detach,
+ .join = _join,
+ },
+ .cleanup_handlers = linked_list_create(),
+ .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+ );
sem_init(&this->created, FALSE, 0);
- this->detached_or_joined = FALSE;
- this->terminated = FALSE;
return this;
}
@@ -288,6 +291,17 @@ static void *thread_main(private_thread_t *this)
sem_wait(&this->created);
current_thread->set(current_thread, this);
pthread_cleanup_push((thread_cleanup_t)thread_cleanup, this);
+
+ /* TODO: this is not 100% portable as pthread_t is an opaque type (i.e.
+ * could be of any size, or even a struct) */
+#ifdef HAVE_GETTID
+ DBG2(DBG_LIB, "created thread %.2d [%u]",
+ this->id, gettid());
+#else
+ DBG2(DBG_LIB, "created thread %.2d [%lx]",
+ this->id, (u_long)this->thread_id);
+#endif
+
res = this->main(this->arg);
pthread_cleanup_pop(TRUE);
@@ -344,10 +358,12 @@ void thread_cleanup_push(thread_cleanup_t cleanup, void *arg)
private_thread_t *this = (private_thread_t*)thread_current();
cleanup_handler_t *handler;
+ INIT(handler,
+ .cleanup = cleanup,
+ .arg = arg,
+ );
+
this->mutex->lock(this->mutex);
- handler = malloc_thing(cleanup_handler_t);
- handler->cleanup = cleanup;
- handler->arg = arg;
this->cleanup_handlers->insert_last(this->cleanup_handlers, handler);
this->mutex->unlock(this->mutex);
}
@@ -422,12 +438,20 @@ void thread_exit(void *val)
}
/**
+ * A dummy thread value that reserved pthread_key_t value "0". A buggy PKCS#11
+ * library mangles this key, without owning it, so we allocate it for them.
+ */
+static thread_value_t *dummy1;
+
+/**
* Described in header.
*/
void threads_init()
{
private_thread_t *main_thread = thread_create_internal();
+ dummy1 = thread_value_create(NULL);
+
main_thread->id = 0;
main_thread->thread_id = pthread_self();
current_thread = thread_value_create(NULL);
@@ -451,6 +475,8 @@ void threads_deinit()
{
private_thread_t *main_thread = (private_thread_t*)thread_current();
+ dummy1->destroy(dummy1);
+
main_thread->mutex->lock(main_thread->mutex);
thread_destroy(main_thread);
current_thread->destroy(current_thread);
diff --git a/src/libstrongswan/threading/thread_value.c b/src/libstrongswan/threading/thread_value.c
index 8f2a8846c..3fa70acb2 100644
--- a/src/libstrongswan/threading/thread_value.c
+++ b/src/libstrongswan/threading/thread_value.c
@@ -35,27 +35,20 @@ struct private_thread_value_t {
};
-
-/**
- * Implementation of thread_value_t.set.
- */
-static void set(private_thread_value_t *this, void *val)
+METHOD(thread_value_t, set, void,
+ private_thread_value_t *this, void *val)
{
pthread_setspecific(this->key, val);
}
-/**
- * Implementation of thread_value_t.get.
- */
-static void *get(private_thread_value_t *this)
+METHOD(thread_value_t, get, void*,
+ private_thread_value_t *this)
{
return pthread_getspecific(this->key);
}
-/**
- * Implementation of thread_value_t.destroy.
- */
-static void destroy(private_thread_value_t *this)
+METHOD(thread_value_t, destroy, void,
+ private_thread_value_t *this)
{
pthread_key_delete(this->key);
free(this);
@@ -67,10 +60,15 @@ static void destroy(private_thread_value_t *this)
*/
thread_value_t *thread_value_create(thread_cleanup_t destructor)
{
- private_thread_value_t *this = malloc_thing(private_thread_value_t);
- this->public.set = (void(*)(thread_value_t*,void*))set;
- this->public.get = (void*(*)(thread_value_t*))get;
- this->public.destroy = (void(*)(thread_value_t*))destroy;
+ private_thread_value_t *this;
+
+ INIT(this,
+ .public = {
+ .set = _set,
+ .get = _get,
+ .destroy = _destroy,
+ },
+ );
pthread_key_create(&this->key, destructor);
return &this->public;
diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c
index 6ffb62aaf..f76245a19 100644
--- a/src/libstrongswan/utils.c
+++ b/src/libstrongswan/utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2010 Tobias Brunner
+ * Copyright (C) 2008-2011 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -20,6 +20,7 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
+#include <inttypes.h>
#include <stdint.h>
#include <limits.h>
#include <dirent.h>
@@ -27,6 +28,7 @@
#include "enum.h"
#include "debug.h"
+#include "utils/enumerator.h"
ENUM(status_names, SUCCESS, NEED_MORE,
"SUCCESS",
@@ -192,6 +194,49 @@ bool mkdir_p(const char *path, mode_t mode)
return TRUE;
}
+#ifndef HAVE_CLOSEFROM
+/**
+ * Described in header.
+ */
+void closefrom(int lowfd)
+{
+ char fd_dir[PATH_MAX];
+ int maxfd, fd, len;
+
+ /* try to close only open file descriptors on Linux... */
+ len = snprintf(fd_dir, sizeof(fd_dir), "/proc/%u/fd", getpid());
+ if (len > 0 && len < sizeof(fd_dir) && access(fd_dir, F_OK) == 0)
+ {
+ enumerator_t *enumerator = enumerator_create_directory(fd_dir);
+ if (enumerator)
+ {
+ char *rel;
+ while (enumerator->enumerate(enumerator, &rel, NULL, NULL))
+ {
+ fd = atoi(rel);
+ if (fd >= lowfd)
+ {
+ close(fd);
+ }
+ }
+ enumerator->destroy(enumerator);
+ return;
+ }
+ }
+
+ /* ...fall back to closing all fds otherwise */
+ maxfd = (int)sysconf(_SC_OPEN_MAX);
+ if (maxfd < 0)
+ {
+ maxfd = 256;
+ }
+ for (fd = lowfd; fd < maxfd; fd++)
+ {
+ close(fd);
+ }
+}
+#endif /* HAVE_CLOSEFROM */
+
/**
* Return monotonic time
*/
@@ -299,6 +344,28 @@ bool ref_put(refcount_t *ref)
pthread_mutex_unlock(&ref_mutex);
return !more_refs;
}
+
+/**
+ * Single mutex for all compare and swap operations.
+ */
+static pthread_mutex_t cas_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Compare and swap if equal to old value
+ */
+#define _cas_impl(name, type) \
+bool cas_##name(type *ptr, type oldval, type newval) \
+{ \
+ bool swapped; \
+ pthread_mutex_lock(&cas_mutex); \
+ if ((swapped = (*ptr == oldval))) { *ptr = newval; } \
+ pthread_mutex_unlock(&cas_mutex); \
+ return swapped; \
+}
+
+_cas_impl(bool, bool)
+_cas_impl(ptr, void*)
+
#endif /* HAVE_GCC_ATOMIC_OPERATIONS */
/**
@@ -342,7 +409,7 @@ int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
char* unit = "second";
time_t *arg1 = *((time_t**)(args[0]));
time_t *arg2 = *((time_t**)(args[1]));
- time_t delta = abs(*arg1 - *arg2);
+ u_int64_t delta = llabs(*arg1 - *arg2);
if (delta > 2 * 60 * 60 * 24)
{
@@ -359,7 +426,8 @@ int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
delta /= 60;
unit = "minute";
}
- return print_in_hook(dst, len, "%d %s%s", delta, unit, (delta == 1)? "":"s");
+ return print_in_hook(dst, len, "%" PRIu64 " %s%s", delta, unit,
+ (delta == 1) ? "" : "s");
}
/**
@@ -376,7 +444,7 @@ int mem_printf_hook(char *dst, size_t dstlen,
printf_hook_spec_t *spec, const void *const *args)
{
char *bytes = *((void**)(args[0]));
- int len = *((size_t*)(args[1]));
+ u_int len = *((int*)(args[1]));
char buffer[BYTES_PER_LINE * 3];
char ascii_buffer[BYTES_PER_LINE + 1];
@@ -387,7 +455,7 @@ int mem_printf_hook(char *dst, size_t dstlen,
int i = 0;
int written = 0;
- written += print_in_hook(dst, dstlen, "=> %d bytes @ %p", len, bytes);
+ written += print_in_hook(dst, dstlen, "=> %u bytes @ %p", len, bytes);
while (bytes_pos < bytes_roof)
{
diff --git a/src/libstrongswan/utils.h b/src/libstrongswan/utils.h
index a334954ae..cedfe8fd1 100644
--- a/src/libstrongswan/utils.h
+++ b/src/libstrongswan/utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2010 Tobias Brunner
+ * Copyright (C) 2008-2011 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -121,8 +121,9 @@
/**
* Object allocation/initialization macro, using designated initializer.
*/
-#define INIT(this, ...) { (this) = malloc(sizeof(*this)); \
- *(this) = (typeof(*this)){ __VA_ARGS__ }; }
+#define INIT(this, ...) ({ (this) = malloc(sizeof(*(this))); \
+ *(this) = (typeof(*(this))){ __VA_ARGS__ }; \
+ (this); })
/**
* Method declaration/definition macro, providing private and public interface.
@@ -347,17 +348,20 @@ void memwipe_noinline(void *ptr, size_t n);
static inline void memwipe_inline(void *ptr, size_t n)
{
volatile char *c = (volatile char*)ptr;
- int m, i;
+ size_t m, i;
/* byte wise until long aligned */
- for (i = 0; (uintptr_t)&c % sizeof(long) && i < n; i++)
+ for (i = 0; (uintptr_t)&c[i] % sizeof(long) && i < n; i++)
{
c[i] = 0;
}
- /* word wize */
- for (m = n - sizeof(long); i <= m; i += sizeof(long))
+ /* word wise */
+ if (n >= sizeof(long))
{
- *(volatile long*)&c[i] = 0;
+ for (m = n - sizeof(long); i <= m; i += sizeof(long))
+ {
+ *(volatile long*)&c[i] = 0;
+ }
}
/* byte wise of the rest */
for (; i < n; i++)
@@ -404,6 +408,15 @@ char *translate(char *str, const char *from, const char *to);
*/
bool mkdir_p(const char *path, mode_t mode);
+#ifndef HAVE_CLOSEFROM
+/**
+ * Close open file descriptors greater than or equal to lowfd.
+ *
+ * @param lowfd start closing file descriptoros from here
+ */
+void closefrom(int lowfd);
+#endif
+
/**
* Get a timestamp from a monotonic time source.
*
@@ -470,6 +483,27 @@ static inline void htoun32(void *network, u_int32_t host)
}
/**
+ * Write a 64-bit host order value in network order to an unaligned address.
+ *
+ * @param host host order 64-bit value
+ * @param network unaligned address to write network order value to
+ */
+static inline void htoun64(void *network, u_int64_t host)
+{
+ char *unaligned = (char*)network;
+ u_int32_t high_part, low_part;
+
+ high_part = host >> 32;
+ high_part = htonl(high_part);
+ low_part = host & 0xFFFFFFFFLL;
+ low_part = htonl(low_part);
+
+ memcpy(unaligned, &high_part, sizeof(high_part));
+ unaligned += sizeof(high_part);
+ memcpy(unaligned, &low_part, sizeof(low_part));
+}
+
+/**
* Read a 16-bit value in network order from an unaligned address to host order.
*
* @param network unaligned address to read network order value from
@@ -500,6 +534,27 @@ static inline u_int32_t untoh32(void *network)
}
/**
+ * Read a 64-bit value in network order from an unaligned address to host order.
+ *
+ * @param network unaligned address to read network order value from
+ * @return host order value
+ */
+static inline u_int64_t untoh64(void *network)
+{
+ char *unaligned = (char*)network;
+ u_int32_t high_part, low_part;
+
+ memcpy(&high_part, unaligned, sizeof(high_part));
+ unaligned += sizeof(high_part);
+ memcpy(&low_part, unaligned, sizeof(low_part));
+
+ high_part = ntohl(high_part);
+ low_part = ntohl(low_part);
+
+ return (((u_int64_t)high_part) << 32) + low_part;
+}
+
+/**
* Special type to count references
*/
typedef volatile u_int refcount_t;
@@ -510,6 +565,11 @@ typedef volatile u_int refcount_t;
#define ref_get(ref) {__sync_fetch_and_add(ref, 1); }
#define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
+#define cas_bool(ptr, oldval, newval) \
+ (__sync_bool_compare_and_swap(ptr, oldval, newval))
+#define cas_ptr(ptr, oldval, newval) \
+ (__sync_bool_compare_and_swap(ptr, oldval, newval))
+
#else /* !HAVE_GCC_ATOMIC_OPERATIONS */
/**
@@ -532,6 +592,27 @@ void ref_get(refcount_t *ref);
*/
bool ref_put(refcount_t *ref);
+/**
+ * Atomically replace value of ptr with newval if it currently equals oldval.
+ *
+ * @param ptr pointer to variable
+ * @param oldval old value of the variable
+ * @param newval new value set if possible
+ * @return TRUE if value equaled oldval and newval was written
+ */
+bool cas_bool(bool *ptr, bool oldval, bool newval);
+
+/**
+ * Atomically replace value of ptr with newval if it currently equals oldval.
+ *
+ * @param ptr pointer to variable
+ * @param oldval old value of the variable
+ * @param newval new value set if possible
+ * @return TRUE if value equaled oldval and newval was written
+ */
+bool cas_ptr(void **ptr, void *oldval, void *newval);
+
+
#endif /* HAVE_GCC_ATOMIC_OPERATIONS */
/**
@@ -556,7 +637,7 @@ int time_delta_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
* printf hook for memory areas.
*
* Arguments are:
- * u_char *ptr, int len
+ * u_char *ptr, u_int len
*/
int mem_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
const void *const *args);
diff --git a/src/libstrongswan/utils/backtrace.c b/src/libstrongswan/utils/backtrace.c
index 5744439f8..cb83d9830 100644
--- a/src/libstrongswan/utils/backtrace.c
+++ b/src/libstrongswan/utils/backtrace.c
@@ -50,10 +50,8 @@ struct private_backtrace_t {
void *frames[];
};
-/**
- * Implementation of backtrace_t.log
- */
-static void log_(private_backtrace_t *this, FILE *file, bool detailed)
+METHOD(backtrace_t, log_, void,
+ private_backtrace_t *this, FILE *file, bool detailed)
{
#ifdef HAVE_BACKTRACE
size_t i;
@@ -129,11 +127,8 @@ static void log_(private_backtrace_t *this, FILE *file, bool detailed)
#endif /* HAVE_BACKTRACE */
}
-/**
- * Implementation of backtrace_t.contains_function
- */
-static bool contains_function(private_backtrace_t *this,
- char *function[], int count)
+METHOD(backtrace_t, contains_function, bool,
+ private_backtrace_t *this, char *function[], int count)
{
#ifdef HAVE_DLADDR
int i, j;
@@ -157,10 +152,70 @@ static bool contains_function(private_backtrace_t *this,
return FALSE;
}
+METHOD(backtrace_t, equals, bool,
+ private_backtrace_t *this, backtrace_t *other_public)
+{
+ private_backtrace_t *other = (private_backtrace_t*)other_public;
+ int i;
+
+ if (this == other)
+ {
+ return TRUE;
+ }
+ if (this->frame_count != other->frame_count)
+ {
+ return FALSE;
+ }
+ for (i = 0; i < this->frame_count; i++)
+ {
+ if (this->frames[i] != other->frames[i])
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
/**
- * Implementation of backtrace_t.destroy.
+ * Frame enumerator
*/
-static void destroy(private_backtrace_t *this)
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** reference to backtrace */
+ private_backtrace_t *bt;
+ /** current position */
+ int i;
+} frame_enumerator_t;
+
+METHOD(enumerator_t, frame_enumerate, bool,
+ frame_enumerator_t *this, void **addr)
+{
+ if (this->i < this->bt->frame_count)
+ {
+ *addr = this->bt->frames[this->i++];
+ return TRUE;
+ }
+ return FALSE;
+}
+
+METHOD(backtrace_t, create_frame_enumerator, enumerator_t*,
+ private_backtrace_t *this)
+{
+ frame_enumerator_t *enumerator;
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)_frame_enumerate,
+ .destroy = (void*)free,
+ },
+ .bt = this,
+ );
+ return &enumerator->public;
+}
+
+METHOD(backtrace_t, destroy, void,
+ private_backtrace_t *this)
{
free(this);
}
@@ -182,9 +237,13 @@ backtrace_t *backtrace_create(int skip)
memcpy(this->frames, frames + skip, frame_count * sizeof(void*));
this->frame_count = frame_count;
- this->public.log = (void(*)(backtrace_t*,FILE*,bool))log_;
- this->public.contains_function = (bool(*)(backtrace_t*, char *function[], int count))contains_function;
- this->public.destroy = (void(*)(backtrace_t*))destroy;
+ this->public = (backtrace_t) {
+ .log = _log_,
+ .contains_function = _contains_function,
+ .equals = _equals,
+ .create_frame_enumerator = _create_frame_enumerator,
+ .destroy = _destroy,
+ };
return &this->public;
}
diff --git a/src/libstrongswan/utils/backtrace.h b/src/libstrongswan/utils/backtrace.h
index e8ccfc1bd..9d59d2503 100644
--- a/src/libstrongswan/utils/backtrace.h
+++ b/src/libstrongswan/utils/backtrace.h
@@ -50,6 +50,20 @@ struct backtrace_t {
bool (*contains_function)(backtrace_t *this, char *function[], int count);
/**
+ * Check two backtraces for equality.
+ *
+ * @param other backtrace to compare to this
+ * @return TRUE if backtraces are equal
+ */
+ bool (*equals)(backtrace_t *this, backtrace_t *other);
+ /**
+ * Create an enumerator over the stack frame addresses.
+ *
+ * @return enumerator_t over void*
+ */
+ enumerator_t* (*create_frame_enumerator)(backtrace_t *this);
+
+ /**
* Destroy a backtrace instance.
*/
void (*destroy)(backtrace_t *this);
diff --git a/src/libstrongswan/utils/enumerator.h b/src/libstrongswan/utils/enumerator.h
index 537bf69e1..12b5712ae 100644
--- a/src/libstrongswan/utils/enumerator.h
+++ b/src/libstrongswan/utils/enumerator.h
@@ -26,7 +26,7 @@ typedef struct enumerator_t enumerator_t;
#include "../utils.h"
/**
- * Enumerate is simpler, but more flexible than iterator.
+ * Enumerator interface, allows enumeration over collections.
*/
struct enumerator_t {
@@ -36,7 +36,7 @@ struct enumerator_t {
* The enumerate function takes a variable argument list containing
* pointers where the enumerated values get written.
*
- * @param ... variable list of enumerated items, implementation dependant
+ * @param ... variable list of enumerated items, implementation dependent
* @return TRUE if pointers returned
*/
bool (*enumerate)(enumerator_t *this, ...);
diff --git a/src/libstrongswan/utils/hashtable.c b/src/libstrongswan/utils/hashtable.c
index 49b0bb68c..33f645170 100644
--- a/src/libstrongswan/utils/hashtable.c
+++ b/src/libstrongswan/utils/hashtable.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2010 Tobias Brunner
+ * Copyright (C) 2008-2011 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -13,7 +13,6 @@
* for more details.
*/
-#include <utils/linked_list.h>
#include "hashtable.h"
@@ -40,12 +39,17 @@ struct pair_t {
* Cached hash (used in case of a resize).
*/
u_int hash;
+
+ /**
+ * Next pair in an overflow list.
+ */
+ pair_t *next;
};
/**
* Creates an empty pair object.
*/
-pair_t *pair_create(void *key, void *value, u_int hash)
+static inline pair_t *pair_create(void *key, void *value, u_int hash)
{
pair_t *this;
@@ -93,7 +97,7 @@ struct private_hashtable_t {
/**
* The actual table.
*/
- linked_list_t **table;
+ pair_t **table;
/**
* The hashing function.
@@ -129,23 +133,21 @@ struct private_enumerator_t {
u_int row;
/**
+ * number of remaining items in hashtable
+ */
+ u_int count;
+
+ /**
* current pair
*/
- pair_t *pair;
+ pair_t *current;
/**
- * enumerator for the current row
+ * previous pair (used by remove_at)
*/
- enumerator_t *current;
-};
+ pair_t *prev;
-/**
- * Compare a pair in a list with the given key.
- */
-static inline bool pair_equals(pair_t *pair, private_hashtable_t *this, void *key)
-{
- return this->equals(key, pair->key);
-}
+};
/**
* This function returns the next-highest power of two for the given number.
@@ -175,7 +177,7 @@ static void init_hashtable(private_hashtable_t *this, u_int capacity)
this->mask = this->capacity - 1;
this->load_factor = 0.75;
- this->table = calloc(this->capacity, sizeof(linked_list_t*));
+ this->table = calloc(this->capacity, sizeof(pair_t*));
}
/**
@@ -183,7 +185,7 @@ static void init_hashtable(private_hashtable_t *this, u_int capacity)
*/
static void rehash(private_hashtable_t *this)
{
- linked_list_t **old_table;
+ pair_t **old_table;
u_int row, old_capacity;
if (this->capacity >= MAX_CAPACITY)
@@ -198,29 +200,17 @@ static void rehash(private_hashtable_t *this)
for (row = 0; row < old_capacity; row++)
{
- enumerator_t *enumerator;
- linked_list_t *list, *new_list;
- pair_t *pair;
+ pair_t *pair, *next;
u_int new_row;
- list = old_table[row];
- if (list)
- {
- enumerator = list->create_enumerator(list);
- while (enumerator->enumerate(enumerator, &pair))
- {
- new_row = pair->hash & this->mask;
-
- list->remove_at(list, enumerator);
- new_list = this->table[new_row];
- if (!new_list)
- {
- new_list = this->table[new_row] = linked_list_create();
- }
- new_list->insert_last(new_list, pair);
- }
- enumerator->destroy(enumerator);
- list->destroy(list);
+ pair = old_table[row];
+ while (pair)
+ { /* insert pair at the front of new bucket*/
+ next = pair->next;
+ new_row = pair->hash & this->mask;
+ pair->next = this->table[new_row];
+ this->table[new_row] = pair;
+ pair = next;
}
}
free(old_table);
@@ -230,38 +220,28 @@ METHOD(hashtable_t, put, void*,
private_hashtable_t *this, void *key, void *value)
{
void *old_value = NULL;
- linked_list_t *list;
- u_int hash;
- u_int row;
+ pair_t *pair;
+ u_int hash, row;
hash = this->hash(key);
row = hash & this->mask;
- list = this->table[row];
- if (list)
- {
- enumerator_t *enumerator;
- pair_t *pair;
-
- enumerator = list->create_enumerator(list);
- while (enumerator->enumerate(enumerator, &pair))
+ pair = this->table[row];
+ while (pair)
+ { /* search existing bucket for key */
+ if (this->equals(key, pair->key))
{
- if (pair_equals(pair, this, key))
- {
- old_value = pair->value;
- pair->value = value;
- pair->key = key;
- break;
- }
+ old_value = pair->value;
+ pair->value = value;
+ pair->key = key;
+ break;
}
- enumerator->destroy(enumerator);
- }
- else
- {
- list = this->table[row] = linked_list_create();
+ pair = pair->next;
}
- if (!old_value)
- {
- list->insert_last(list, pair_create(key, value, hash));
+ if (!pair)
+ { /* insert at the front of bucket */
+ pair = pair_create(key, value, hash);
+ pair->next = this->table[row];
+ this->table[row] = pair;
this->count++;
}
if (this->count >= this->capacity * this->load_factor)
@@ -275,17 +255,17 @@ METHOD(hashtable_t, get, void*,
private_hashtable_t *this, void *key)
{
void *value = NULL;
- linked_list_t *list;
pair_t *pair;
- list = this->table[this->hash(key) & this->mask];
- if (list)
+ pair = this->table[this->hash(key) & this->mask];
+ while (pair)
{
- if (list->find_first(list, (linked_list_match_t)pair_equals,
- (void**)&pair, this, key) == SUCCESS)
+ if (this->equals(key, pair->key))
{
value = pair->value;
+ break;
}
+ pair = pair->next;
}
return value;
}
@@ -294,27 +274,30 @@ METHOD(hashtable_t, remove_, void*,
private_hashtable_t *this, void *key)
{
void *value = NULL;
- linked_list_t *list;
+ pair_t *pair, *prev = NULL;
+ u_int row;
- list = this->table[this->hash(key) & this->mask];
- if (list)
+ row = this->hash(key) & this->mask;
+ pair = this->table[row];
+ while (pair)
{
- enumerator_t *enumerator;
- pair_t *pair;
-
- enumerator = list->create_enumerator(list);
- while (enumerator->enumerate(enumerator, &pair))
+ if (this->equals(key, pair->key))
{
- if (pair_equals(pair, this, key))
+ if (prev)
{
- list->remove_at(list, enumerator);
- value = pair->value;
- this->count--;
- free(pair);
- break;
+ prev->next = pair->next;
}
+ else
+ {
+ this->table[row] = pair->next;
+ }
+ value = pair->value;
+ this->count--;
+ free(pair);
+ break;
}
- enumerator->destroy(enumerator);
+ prev = pair;
+ pair = pair->next;
}
return value;
}
@@ -324,14 +307,18 @@ METHOD(hashtable_t, remove_at, void,
{
if (enumerator->table == this && enumerator->current)
{
- linked_list_t *list;
- list = this->table[enumerator->row];
- if (list)
+ pair_t *current = enumerator->current;
+ if (enumerator->prev)
{
- list->remove_at(list, enumerator->current);
- free(enumerator->pair);
- this->count--;
+ enumerator->prev->next = current->next;
+ }
+ else
+ {
+ this->table[enumerator->row] = current->next;
}
+ enumerator->current = enumerator->prev;
+ free(current);
+ this->count--;
}
}
@@ -344,50 +331,35 @@ METHOD(hashtable_t, get_count, u_int,
METHOD(enumerator_t, enumerate, bool,
private_enumerator_t *this, void **key, void **value)
{
- while (this->row < this->table->capacity)
+ while (this->count && this->row < this->table->capacity)
{
+ this->prev = this->current;
if (this->current)
{
- if (this->current->enumerate(this->current, &this->pair))
- {
- if (key)
- {
- *key = this->pair->key;
- }
- if (value)
- {
- *value = this->pair->value;
- }
- return TRUE;
- }
- this->current->destroy(this->current);
- this->current = NULL;
+ this->current = this->current->next;
}
else
{
- linked_list_t *list;
- list = this->table->table[this->row];
- if (list)
+ this->current = this->table->table[this->row];
+ }
+ if (this->current)
+ {
+ if (key)
{
- this->current = list->create_enumerator(list);
- continue;
+ *key = this->current->key;
}
+ if (value)
+ {
+ *value = this->current->value;
+ }
+ this->count--;
+ return TRUE;
}
this->row++;
}
return FALSE;
}
-METHOD(enumerator_t, enumerator_destroy, void,
- private_enumerator_t *this)
-{
- if (this->current)
- {
- this->current->destroy(this->current);
- }
- free(this);
-}
-
METHOD(hashtable_t, create_enumerator, enumerator_t*,
private_hashtable_t *this)
{
@@ -396,9 +368,10 @@ METHOD(hashtable_t, create_enumerator, enumerator_t*,
INIT(enumerator,
.enumerator = {
.enumerate = (void*)_enumerate,
- .destroy = (void*)_enumerator_destroy,
+ .destroy = (void*)free,
},
.table = this,
+ .count = this->count,
);
return &enumerator->enumerator;
@@ -407,15 +380,17 @@ METHOD(hashtable_t, create_enumerator, enumerator_t*,
METHOD(hashtable_t, destroy, void,
private_hashtable_t *this)
{
- linked_list_t *list;
+ pair_t *pair, *next;
u_int row;
for (row = 0; row < this->capacity; row++)
{
- list = this->table[row];
- if (list)
+ pair = this->table[row];
+ while (pair)
{
- list->destroy_function(list, free);
+ next = pair->next;
+ free(pair);
+ pair = next;
}
}
free(this->table);
diff --git a/src/libstrongswan/utils/host.c b/src/libstrongswan/utils/host.c
index 615d85c95..d3020a5d0 100644
--- a/src/libstrongswan/utils/host.c
+++ b/src/libstrongswan/utils/host.c
@@ -40,7 +40,7 @@ struct private_host_t {
host_t public;
/**
- * low-lewel structure, wich stores the address
+ * low-lewel structure, which stores the address
*/
union {
/** generic type */
@@ -59,26 +59,20 @@ struct private_host_t {
};
-/**
- * implements host_t.get_sockaddr
- */
-static sockaddr_t *get_sockaddr(private_host_t *this)
+METHOD(host_t, get_sockaddr, sockaddr_t*,
+ private_host_t *this)
{
return &(this->address);
}
-/**
- * implements host_t.get_sockaddr_len
- */
-static socklen_t *get_sockaddr_len(private_host_t *this)
+METHOD(host_t, get_sockaddr_len, socklen_t*,
+ private_host_t *this)
{
return &(this->socklen);
}
-/**
- * Implementation of host_t.is_anyaddr.
- */
-static bool is_anyaddr(private_host_t *this)
+METHOD(host_t, is_anyaddr, bool,
+ private_host_t *this)
{
switch (this->address.sa_family)
{
@@ -163,10 +157,8 @@ int host_printf_hook(char *dst, size_t dstlen, printf_hook_spec_t *spec,
return print_in_hook(dst, dstlen, "%*s", spec->width, buffer);
}
-/**
- * Implementation of host_t.get_address.
- */
-static chunk_t get_address(private_host_t *this)
+METHOD(host_t, get_address, chunk_t,
+ private_host_t *this)
{
chunk_t address = chunk_empty;
@@ -192,18 +184,14 @@ static chunk_t get_address(private_host_t *this)
}
}
-/**
- * implements host_t.get_family
- */
-static int get_family(private_host_t *this)
+METHOD(host_t, get_family, int,
+ private_host_t *this)
{
return this->address.sa_family;
}
-/**
- * implements host_t.get_port
- */
-static u_int16_t get_port(private_host_t *this)
+METHOD(host_t, get_port, u_int16_t,
+ private_host_t *this)
{
switch (this->address.sa_family)
{
@@ -222,10 +210,8 @@ static u_int16_t get_port(private_host_t *this)
}
}
-/**
- * implements host_t.set_port
- */
-static void set_port(private_host_t *this, u_int16_t port)
+METHOD(host_t, set_port, void,
+ private_host_t *this, u_int16_t port)
{
switch (this->address.sa_family)
{
@@ -246,19 +232,19 @@ static void set_port(private_host_t *this, u_int16_t port)
}
}
-/**
- * Implements host_t.clone.
- */
-static private_host_t *clone_(private_host_t *this)
+METHOD(host_t, clone_, host_t*,
+ private_host_t *this)
{
- private_host_t *new = malloc_thing(private_host_t);
+ private_host_t *new;
+ new = malloc_thing(private_host_t);
memcpy(new, this, sizeof(private_host_t));
- return new;
+
+ return &new->public;
}
/**
- * Impelements host_t.ip_equals
+ * Implements host_t.ip_equals
*/
static bool ip_equals(private_host_t *this, private_host_t *other)
{
@@ -332,10 +318,8 @@ static bool equals(private_host_t *this, private_host_t *other)
return FALSE;
}
-/**
- * Implements host_t.destroy
- */
-static void destroy(private_host_t *this)
+METHOD(host_t, destroy, void,
+ private_host_t *this)
{
free(this);
}
@@ -345,20 +329,24 @@ static void destroy(private_host_t *this)
*/
static private_host_t *host_create_empty(void)
{
- private_host_t *this = malloc_thing(private_host_t);
-
- this->public.get_sockaddr = (sockaddr_t* (*) (host_t*))get_sockaddr;
- this->public.get_sockaddr_len = (socklen_t*(*) (host_t*))get_sockaddr_len;
- this->public.clone = (host_t* (*) (host_t*))clone_;
- this->public.get_family = (int (*) (host_t*))get_family;
- this->public.get_address = (chunk_t (*) (host_t *)) get_address;
- this->public.get_port = (u_int16_t (*) (host_t *))get_port;
- this->public.set_port = (void (*) (host_t *,u_int16_t))set_port;
- this->public.get_differences = get_differences;
- this->public.ip_equals = (bool (*) (host_t *,host_t *)) ip_equals;
- this->public.equals = (bool (*) (host_t *,host_t *)) equals;
- this->public.is_anyaddr = (bool (*) (host_t *)) is_anyaddr;
- this->public.destroy = (void (*) (host_t*))destroy;
+ private_host_t *this;
+
+ INIT(this,
+ .public = {
+ .get_sockaddr = _get_sockaddr,
+ .get_sockaddr_len = _get_sockaddr_len,
+ .clone = _clone_,
+ .get_family = _get_family,
+ .get_address = _get_address,
+ .get_port = _get_port,
+ .set_port = _set_port,
+ .get_differences = get_differences,
+ .ip_equals = (bool (*)(host_t *,host_t *))ip_equals,
+ .equals = (bool (*)(host_t *,host_t *)) equals,
+ .is_anyaddr = _is_anyaddr,
+ .destroy = _destroy,
+ },
+ );
return this;
}
@@ -585,7 +573,7 @@ host_t *host_create_from_subnet(char *string, int *bits)
*bits = atoi(pos + 1);
return host_create_from_string(buf, 0);
}
- net = host_create_from_string(buf, 0);
+ net = host_create_from_string(string, 0);
if (net)
{
if (net->get_family(net) == AF_INET)
diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c
index 252cfa28e..9f0007f78 100644
--- a/src/libstrongswan/utils/identification.c
+++ b/src/libstrongswan/utils/identification.c
@@ -81,6 +81,7 @@ static const x501rdn_t x501rdns[] = {
{"N", OID_NAME, ASN1_PRINTABLESTRING},
{"G", OID_GIVEN_NAME, ASN1_PRINTABLESTRING},
{"I", OID_INITIALS, ASN1_PRINTABLESTRING},
+ {"dnQualifier", OID_DN_QUALIFIER, ASN1_PRINTABLESTRING},
{"ID", OID_UNIQUE_IDENTIFIER, ASN1_PRINTABLESTRING},
{"EN", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
{"employeeNumber", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
@@ -219,6 +220,7 @@ METHOD(enumerator_t, rdn_part_enumerate, bool,
{OID_NAME, ID_PART_RDN_N},
{OID_GIVEN_NAME, ID_PART_RDN_G},
{OID_INITIALS, ID_PART_RDN_I},
+ {OID_DN_QUALIFIER, ID_PART_RDN_DNQ},
{OID_UNIQUE_IDENTIFIER, ID_PART_RDN_ID},
{OID_EMAIL_ADDRESS, ID_PART_RDN_E},
{OID_EMPLOYEE_NUMBER, ID_PART_RDN_EN},
diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h
index c463b0274..3978b23f3 100644
--- a/src/libstrongswan/utils/identification.h
+++ b/src/libstrongswan/utils/identification.h
@@ -171,6 +171,8 @@ enum id_part_t {
ID_PART_RDN_G,
/** Initials RDN of a DN */
ID_PART_RDN_I,
+ /** DN Qualifier RDN of a DN */
+ ID_PART_RDN_DNQ,
/** UniqueIdentifier RDN of a DN */
ID_PART_RDN_ID,
/** Locality RDN of a DN */
@@ -293,12 +295,12 @@ struct identification_t {
*
* In favour of pluto, domainnames are prepended with an @, since
* pluto resolves domainnames without an @ to IPv4 addresses. Since
- * we use a seperate host_t class for addresses, this doesn't
+ * we use a separate host_t class for addresses, this doesn't
* make sense for us.
*
* A distinguished name may contain one or more of the following RDNs:
* ND, UID, DC, CN, S, SN, serialNumber, C, L, ST, O, OU, T, D,
- * N, G, I, ID, EN, EmployeeNumber, E, Email, emailAddress, UN,
+ * N, G, I, dnQualifier, ID, EN, EmployeeNumber, E, Email, emailAddress, UN,
* unstructuredName, TCGID.
*
* This constructor never returns NULL. If it does not find a suitable
diff --git a/src/libstrongswan/utils/iterator.h b/src/libstrongswan/utils/iterator.h
deleted file mode 100644
index 9be65b229..000000000
--- a/src/libstrongswan/utils/iterator.h
+++ /dev/null
@@ -1,114 +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 iterator iterator
- * @{ @ingroup utils
- */
-
-#ifndef ITERATOR_H_
-#define ITERATOR_H_
-
-#include <library.h>
-
-
-typedef struct iterator_t iterator_t;
-
-/**
- * Iterator interface, allows iteration over collections.
- *
- * iterator_t defines an interface for iterating over collections.
- * It allows searching, deleting, updating and inserting.
- *
- * @deprecated Use enumerator instead.
- */
-struct iterator_t {
-
- /**
- * Return number of list items.
- *
- * @return number of list items
- */
- int (*get_count) (iterator_t *this);
-
- /**
- * Iterate over all items.
- *
- * The easy way to iterate over items.
- *
- * @param value item
- * @return TRUE, if there was an element available, FALSE otherwise
- */
- bool (*iterate) (iterator_t *this, void** value);
-
- /**
- * Inserts a new item before the given iterator position.
- *
- * The iterator position is not changed after inserting
- *
- * @param item value to insert in list
- */
- void (*insert_before) (iterator_t *this, void *item);
-
- /**
- * Inserts a new item after the given iterator position.
- *
- * The iterator position is not changed after inserting.
- *
- * @param this calling iterator
- * @param item value to insert in list
- */
- void (*insert_after) (iterator_t *this, void *item);
-
- /**
- * Replace the current item at current iterator position.
- *
- * The iterator position is not changed after replacing.
- *
- * @param this calling iterator
- * @param old old value will be written here(can be NULL)
- * @param new new value
- * @return SUCCESS, FAILED if iterator is on an invalid position
- */
- status_t (*replace) (iterator_t *this, void **old, void *new);
-
- /**
- * Removes an element from list at the given iterator position.
- *
- * The iterator is set the the following position:
- * - to the item before, if available
- * - it gets reseted, otherwise
- *
- * @return SUCCESS, FAILED if iterator is on an invalid position
- */
- status_t (*remove) (iterator_t *this);
-
- /**
- * Resets the iterator position.
- *
- * After reset, the iterator_t objects doesn't point to an element.
- * A call to iterator_t.has_next is necessary to do any other operations
- * with the resetted iterator.
- */
- void (*reset) (iterator_t *this);
-
- /**
- * Destroys an iterator.
- */
- void (*destroy) (iterator_t *this);
-};
-
-#endif /** ITERATOR_H_ @}*/
diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c
index 39505d3f3..0a8789335 100644
--- a/src/libstrongswan/utils/leak_detective.c
+++ b/src/libstrongswan/utils/leak_detective.c
@@ -34,6 +34,7 @@
#include <library.h>
#include <debug.h>
#include <utils/backtrace.h>
+#include <utils/hashtable.h>
typedef struct private_leak_detective_t private_leak_detective_t;
@@ -92,11 +93,6 @@ typedef struct memory_tail_t memory_tail_t;
struct memory_header_t {
/**
- * Number of bytes following after the header
- */
- u_int bytes;
-
- /**
* Pointer to previous entry in linked list
*/
memory_header_t *previous;
@@ -112,6 +108,11 @@ struct memory_header_t {
backtrace_t *backtrace;
/**
+ * Number of bytes following after the header
+ */
+ u_int32_t bytes;
+
+ /**
* magic bytes to detect bad free or heap underflow, MEMORY_HEADER_MAGIC
*/
u_int32_t magic;
@@ -148,6 +149,37 @@ static memory_header_t first_header = {
static bool installed = FALSE;
/**
+ * Installs the malloc hooks, enables leak detection
+ */
+static void install_hooks()
+{
+ if (!installed)
+ {
+ old_malloc_hook = __malloc_hook;
+ old_realloc_hook = __realloc_hook;
+ old_free_hook = __free_hook;
+ __malloc_hook = malloc_hook;
+ __realloc_hook = realloc_hook;
+ __free_hook = free_hook;
+ installed = TRUE;
+ }
+}
+
+/**
+ * Uninstalls the malloc hooks, disables leak detection
+ */
+static void uninstall_hooks()
+{
+ if (installed)
+ {
+ __malloc_hook = old_malloc_hook;
+ __free_hook = old_free_hook;
+ __realloc_hook = old_realloc_hook;
+ installed = FALSE;
+ }
+}
+
+/**
* Leak report white list
*
* List of functions using static allocation buffers or should be suppressed
@@ -162,6 +194,7 @@ char *whitelist[] = {
"__pthread_setspecific",
/* glibc functions */
"mktime",
+ "ctime",
"__gmtime_r",
"localtime_r",
"tzset",
@@ -172,6 +205,7 @@ char *whitelist[] = {
"getprotobynumber",
"getservbyport",
"getservbyname",
+ "gethostbyname",
"gethostbyname2",
"gethostbyname_r",
"gethostbyname2_r",
@@ -187,6 +221,9 @@ char *whitelist[] = {
"getaddrinfo",
"setlocale",
"getpass",
+ "getpwent_r",
+ "setpwent",
+ "endpwent",
/* ignore dlopen, as we do not dlclose to get proper leak reports */
"dlopen",
"dlerror",
@@ -236,31 +273,109 @@ char *whitelist[] = {
"gnutls_global_init",
};
+
/**
- * Report leaks at library destruction
+ * Hashtable hash function
*/
-static void report(private_leak_detective_t *this, bool detailed)
+static u_int hash(backtrace_t *key)
{
- if (lib->leak_detective)
+ enumerator_t *enumerator;
+ void *addr;
+ u_int hash = 0;
+
+ enumerator = key->create_frame_enumerator(key);
+ while (enumerator->enumerate(enumerator, &addr))
{
- memory_header_t *hdr;
- int leaks = 0, whitelisted = 0;
+ hash = chunk_hash_inc(chunk_from_thing(addr), hash);
+ }
+ enumerator->destroy(enumerator);
+
+ return hash;
+}
+
+/**
+ * Hashtable equals function
+ */
+static bool equals(backtrace_t *a, backtrace_t *b)
+{
+ return a->equals(a, b);
+}
- for (hdr = first_header.next; hdr != NULL; hdr = hdr->next)
+/**
+ * Summarize and print backtraces
+ */
+static int print_traces(private_leak_detective_t *this,
+ FILE *out, int thresh, bool detailed, int *whitelisted)
+{
+ int leaks = 0;
+ memory_header_t *hdr;
+ enumerator_t *enumerator;
+ hashtable_t *entries;
+ struct {
+ /** associated backtrace */
+ backtrace_t *backtrace;
+ /** total size of all allocations */
+ size_t bytes;
+ /** number of allocations */
+ u_int count;
+ } *entry;
+
+ uninstall_hooks();
+
+ entries = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 1024);
+ for (hdr = first_header.next; hdr != NULL; hdr = hdr->next)
+ {
+ if (whitelisted &&
+ hdr->backtrace->contains_function(hdr->backtrace,
+ whitelist, countof(whitelist)))
{
- if (hdr->backtrace->contains_function(hdr->backtrace,
- whitelist, countof(whitelist)))
- {
- whitelisted++;
- }
- else
- {
- fprintf(stderr, "Leak (%d bytes at %p):\n", hdr->bytes, hdr + 1);
- /* skip the first frame, contains leak detective logic */
- hdr->backtrace->log(hdr->backtrace, stderr, detailed);
- leaks++;
- }
+ (*whitelisted)++;
+ continue;
+ }
+ entry = entries->get(entries, hdr->backtrace);
+ if (entry)
+ {
+ entry->bytes += hdr->bytes;
+ entry->count++;
+ }
+ else
+ {
+ INIT(entry,
+ .backtrace = hdr->backtrace,
+ .bytes = hdr->bytes,
+ .count = 1,
+ );
+ entries->put(entries, hdr->backtrace, entry);
}
+ leaks++;
+ }
+ enumerator = entries->create_enumerator(entries);
+ while (enumerator->enumerate(enumerator, NULL, &entry))
+ {
+ if (!thresh || entry->bytes >= thresh)
+ {
+ fprintf(out, "%d bytes total, %d allocations, %d bytes average:\n",
+ entry->bytes, entry->count, entry->bytes / entry->count);
+ entry->backtrace->log(entry->backtrace, out, detailed);
+ }
+ free(entry);
+ }
+ enumerator->destroy(enumerator);
+ entries->destroy(entries);
+
+ install_hooks();
+ return leaks;
+}
+
+METHOD(leak_detective_t, report, void,
+ private_leak_detective_t *this, bool detailed)
+{
+ if (lib->leak_detective)
+ {
+ int leaks = 0, whitelisted = 0;
+
+ leaks = print_traces(this, stderr, 0, detailed, &whitelisted);
switch (leaks)
{
case 0:
@@ -281,35 +396,26 @@ static void report(private_leak_detective_t *this, bool detailed)
}
}
-/**
- * Installs the malloc hooks, enables leak detection
- */
-static void install_hooks()
+METHOD(leak_detective_t, usage, void,
+ private_leak_detective_t *this, FILE *out)
{
- if (!installed)
- {
- old_malloc_hook = __malloc_hook;
- old_realloc_hook = __realloc_hook;
- old_free_hook = __free_hook;
- __malloc_hook = malloc_hook;
- __realloc_hook = realloc_hook;
- __free_hook = free_hook;
- installed = TRUE;
- }
-}
+ int oldpolicy, thresh;
+ bool detailed;
+ pthread_t thread_id = pthread_self();
+ struct sched_param oldparams, params;
-/**
- * Uninstalls the malloc hooks, disables leak detection
- */
-static void uninstall_hooks()
-{
- if (installed)
- {
- __malloc_hook = old_malloc_hook;
- __free_hook = old_free_hook;
- __realloc_hook = old_realloc_hook;
- installed = FALSE;
- }
+ thresh = lib->settings->get_int(lib->settings,
+ "libstrongswan.leak_detective.usage_threshold", 10240);
+ detailed = lib->settings->get_bool(lib->settings,
+ "libstrongswan.leak_detective.detailed", TRUE);
+
+ pthread_getschedparam(thread_id, &oldpolicy, &oldparams);
+ params.__sched_priority = sched_get_priority_max(SCHED_FIFO);
+ pthread_setschedparam(thread_id, SCHED_FIFO, &params);
+
+ print_traces(this, out, thresh, detailed, NULL);
+
+ pthread_setschedparam(thread_id, oldpolicy, &oldparams);
}
/**
@@ -492,10 +598,8 @@ void *realloc_hook(void *old, size_t bytes, const void *caller)
return hdr + 1;
}
-/**
- * Implementation of leak_detective_t.destroy
- */
-static void destroy(private_leak_detective_t *this)
+METHOD(leak_detective_t, destroy, void,
+ private_leak_detective_t *this)
{
if (installed)
{
@@ -509,10 +613,15 @@ static void destroy(private_leak_detective_t *this)
*/
leak_detective_t *leak_detective_create()
{
- private_leak_detective_t *this = malloc_thing(private_leak_detective_t);
+ private_leak_detective_t *this;
- this->public.report = (void(*)(leak_detective_t*,bool))report;
- this->public.destroy = (void(*)(leak_detective_t*))destroy;
+ INIT(this,
+ .public = {
+ .report = _report,
+ .usage = _usage,
+ .destroy = _destroy,
+ },
+ );
if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
{
@@ -526,7 +635,6 @@ leak_detective_t *leak_detective_create()
fprintf(stderr, "setting CPU affinity failed: %m");
}
- lib->leak_detective = TRUE;
install_hooks();
}
return &this->public;
diff --git a/src/libstrongswan/utils/leak_detective.h b/src/libstrongswan/utils/leak_detective.h
index fa45a6076..8c80d2532 100644
--- a/src/libstrongswan/utils/leak_detective.h
+++ b/src/libstrongswan/utils/leak_detective.h
@@ -43,6 +43,13 @@ struct leak_detective_t {
void (*report)(leak_detective_t *this, bool detailed);
/**
+ * Report current memory usage to out.
+ *
+ * @param out target to write usage report to
+ */
+ void (*usage)(leak_detective_t *this, FILE *out);
+
+ /**
* Destroy a leak_detective instance.
*/
void (*destroy)(leak_detective_t *this);
diff --git a/src/libstrongswan/utils/linked_list.c b/src/libstrongswan/utils/linked_list.c
index 9b37359dc..59d416f2f 100644
--- a/src/libstrongswan/utils/linked_list.c
+++ b/src/libstrongswan/utils/linked_list.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2008 Tobias Brunner
+ * Copyright (C) 2007-2011 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -51,13 +51,11 @@ struct element_t {
*/
element_t *element_create(void *value)
{
- element_t *this = malloc_thing(element_t);
-
- this->previous = NULL;
- this->next = NULL;
- this->value = value;
-
- return (this);
+ element_t *this;
+ INIT(this,
+ .value = value,
+ );
+ return this;
}
@@ -91,34 +89,6 @@ struct private_linked_list_t {
element_t *last;
};
-
-typedef struct private_iterator_t private_iterator_t;
-
-/**
- * Private variables and functions of linked list iterator.
- */
-struct private_iterator_t {
- /**
- * Public part of linked list iterator.
- */
- iterator_t public;
-
- /**
- * Associated linked list.
- */
- private_linked_list_t * list;
-
- /**
- * Current element of the iterator.
- */
- element_t *current;
-
- /**
- * Direction of iterator.
- */
- bool forward;
-};
-
typedef struct private_enumerator_t private_enumerator_t;
/**
@@ -140,241 +110,78 @@ struct private_enumerator_t {
* current item
*/
element_t *current;
+
+ /**
+ * enumerator has enumerated all items
+ */
+ bool finished;
};
-/**
- * Implementation of private_enumerator_t.enumerator.enumerate.
- */
-static bool enumerate(private_enumerator_t *this, void **item)
+METHOD(enumerator_t, enumerate, bool,
+ private_enumerator_t *this, void **item)
{
+ if (this->finished)
+ {
+ return FALSE;
+ }
if (!this->current)
{
- if (!this->list->first)
- {
- return FALSE;
- }
this->current = this->list->first;
}
else
{
- if (!this->current->next)
- {
- return FALSE;
- }
this->current = this->current->next;
}
- *item = this->current->value;
- return TRUE;
-}
-
-/**
- * Implementation of linked_list_t.create_enumerator.
- */
-static enumerator_t* create_enumerator(private_linked_list_t *this)
-{
- private_enumerator_t *enumerator = malloc_thing(private_enumerator_t);
-
- enumerator->enumerator.enumerate = (void*)enumerate;
- enumerator->enumerator.destroy = (void*)free;
- enumerator->list = this;
- enumerator->current = NULL;
-
- return &enumerator->enumerator;
-}
-
-/**
- * Implementation of iterator_t.get_count.
- */
-static int get_list_count(private_iterator_t *this)
-{
- return this->list->count;
-}
-
-/**
- * Implementation of iterator_t.iterate.
- */
-static bool iterate(private_iterator_t *this, void** value)
-{
- if (this->forward)
- {
- this->current = this->current ? this->current->next : this->list->first;
- }
- else
- {
- this->current = this->current ? this->current->previous : this->list->last;
- }
- if (this->current == NULL)
+ if (!this->current)
{
+ this->finished = TRUE;
return FALSE;
}
- *value = this->current->value;
+ *item = this->current->value;
return TRUE;
}
-/**
- * Implementation of iterator_t.reset.
- */
-static void iterator_reset(private_iterator_t *this)
+METHOD(linked_list_t, create_enumerator, enumerator_t*,
+ private_linked_list_t *this)
{
- this->current = NULL;
-}
+ private_enumerator_t *enumerator;
-/**
- * Implementation of iterator_t.remove.
- */
-static status_t iterator_remove(private_iterator_t *this)
-{
- element_t *new_current;
+ INIT(enumerator,
+ .enumerator = {
+ .enumerate = (void*)_enumerate,
+ .destroy = (void*)free,
+ },
+ .list = this,
+ );
- if (this->current == NULL)
- {
- return NOT_FOUND;
- }
-
- if (this->list->count == 0)
- {
- return NOT_FOUND;
- }
- /* find out the new iterator position, depending on iterator direction */
- if (this->forward && this->current->previous != NULL)
- {
- new_current = this->current->previous;
- }
- else if (!this->forward && this->current->next != NULL)
- {
- new_current = this->current->next;
- }
- else
- {
- new_current = NULL;
- }
-
- /* now delete the entry :-) */
- if (this->current->previous == NULL)
- {
- if (this->current->next == NULL)
- {
- this->list->first = NULL;
- this->list->last = NULL;
- }
- else
- {
- this->current->next->previous = NULL;
- this->list->first = this->current->next;
- }
- }
- else if (this->current->next == NULL)
- {
- this->current->previous->next = NULL;
- this->list->last = this->current->previous;
- }
- else
- {
- this->current->previous->next = this->current->next;
- this->current->next->previous = this->current->previous;
- }
-
- this->list->count--;
- free(this->current);
- /* set the new iterator position */
- this->current = new_current;
- return SUCCESS;
-}
-
-/**
- * Implementation of iterator_t.insert_before.
- */
-static void insert_before(private_iterator_t * iterator, void *item)
-{
- if (iterator->current == NULL)
- {
- iterator->list->public.insert_first(&(iterator->list->public), item);
- return;
- }
-
- element_t *element = element_create(item);
- if (iterator->current->previous == NULL)
- {
- iterator->current->previous = element;
- element->next = iterator->current;
- iterator->list->first = element;
- }
- else
- {
- iterator->current->previous->next = element;
- element->previous = iterator->current->previous;
- iterator->current->previous = element;
- element->next = iterator->current;
- }
- iterator->list->count++;
+ return &enumerator->enumerator;
}
-/**
- * Implementation of iterator_t.replace.
- */
-static status_t replace(private_iterator_t *this, void **old_item, void *new_item)
+METHOD(linked_list_t, reset_enumerator, void,
+ private_linked_list_t *this, private_enumerator_t *enumerator)
{
- if (this->current == NULL)
- {
- return NOT_FOUND;
- }
- if (old_item != NULL)
- {
- *old_item = this->current->value;
- }
- this->current->value = new_item;
-
- return SUCCESS;
+ enumerator->current = NULL;
+ enumerator->finished = FALSE;
}
-/**
- * Implementation of iterator_t.insert_after.
- */
-static void insert_after(private_iterator_t *iterator, void *item)
+METHOD(linked_list_t, has_more, bool,
+ private_linked_list_t *this, private_enumerator_t *enumerator)
{
- if (iterator->current == NULL)
- {
- iterator->list->public.insert_first(&(iterator->list->public),item);
- return;
- }
-
- element_t *element = element_create(item);
- if (iterator->current->next == NULL)
- {
- iterator->current->next = element;
- element->previous = iterator->current;
- iterator->list->last = element;
- }
- else
+ if (enumerator->current)
{
- iterator->current->next->previous = element;
- element->next = iterator->current->next;
- iterator->current->next = element;
- element->previous = iterator->current;
+ return enumerator->current->next != NULL;
}
- iterator->list->count++;
+ return !enumerator->finished && this->first != NULL;
}
-/**
- * Implementation of iterator_t.destroy.
- */
-static void iterator_destroy(private_iterator_t *this)
-{
- free(this);
-}
-
-/**
- * Implementation of linked_list_t.get_count.
- */
-static int get_count(private_linked_list_t *this)
+METHOD(linked_list_t, get_count, int,
+ private_linked_list_t *this)
{
return this->count;
}
-/**
- * Implementation of linked_list_t.insert_first.
- */
-static void insert_first(private_linked_list_t *this, void *item)
+METHOD(linked_list_t, insert_first, void,
+ private_linked_list_t *this, void *item)
{
element_t *element;
@@ -384,15 +191,11 @@ static void insert_first(private_linked_list_t *this, void *item)
/* first entry in list */
this->first = element;
this->last = element;
- element->previous = NULL;
- element->next = NULL;
}
else
{
- element_t *old_first_element = this->first;
- element->next = old_first_element;
- element->previous = NULL;
- old_first_element->previous = element;
+ element->next = this->first;
+ this->first->previous = element;
this->first = element;
}
this->count++;
@@ -401,7 +204,8 @@ static void insert_first(private_linked_list_t *this, void *item)
/**
* unlink an element form the list, returns following element
*/
-static element_t* remove_element(private_linked_list_t *this, element_t *element)
+static element_t* remove_element(private_linked_list_t *this,
+ element_t *element)
{
element_t *next, *previous;
@@ -432,10 +236,8 @@ static element_t* remove_element(private_linked_list_t *this, element_t *element
return next;
}
-/**
- * Implementation of linked_list_t.get_first.
- */
-static status_t get_first(private_linked_list_t *this, void **item)
+METHOD(linked_list_t, get_first, status_t,
+ private_linked_list_t *this, void **item)
{
if (this->count == 0)
{
@@ -445,10 +247,8 @@ static status_t get_first(private_linked_list_t *this, void **item)
return SUCCESS;
}
-/**
- * Implementation of linked_list_t.remove_first.
- */
-static status_t remove_first(private_linked_list_t *this, void **item)
+METHOD(linked_list_t, remove_first, status_t,
+ private_linked_list_t *this, void **item)
{
if (get_first(this, item) == SUCCESS)
{
@@ -458,36 +258,79 @@ static status_t remove_first(private_linked_list_t *this, void **item)
return NOT_FOUND;
}
-/**
- * Implementation of linked_list_t.insert_last.
- */
-static void insert_last(private_linked_list_t *this, void *item)
+METHOD(linked_list_t, insert_last, void,
+ private_linked_list_t *this, void *item)
{
- element_t *element = element_create(item);
+ element_t *element;
+ element = element_create(item);
if (this->count == 0)
{
/* first entry in list */
this->first = element;
this->last = element;
- element->previous = NULL;
- element->next = NULL;
}
else
{
- element_t *old_last_element = this->last;
- element->previous = old_last_element;
- element->next = NULL;
- old_last_element->next = element;
+ element->previous = this->last;
+ this->last->next = element;
this->last = element;
}
this->count++;
}
-/**
- * Implementation of linked_list_t.get_last.
- */
-static status_t get_last(private_linked_list_t *this, void **item)
+METHOD(linked_list_t, insert_before, void,
+ private_linked_list_t *this, private_enumerator_t *enumerator,
+ void *item)
+{
+ element_t *current, *element;
+
+ current = enumerator->current;
+ if (!current)
+ {
+ if (enumerator->finished)
+ {
+ this->public.insert_last(&this->public, item);
+ }
+ else
+ {
+ this->public.insert_first(&this->public, item);
+ }
+ return;
+ }
+ element = element_create(item);
+ if (current->previous)
+ {
+ current->previous->next = element;
+ element->previous = current->previous;
+ current->previous = element;
+ element->next = current;
+ }
+ else
+ {
+ current->previous = element;
+ element->next = current;
+ this->first = element;
+ }
+ this->count++;
+}
+
+METHOD(linked_list_t, replace, void*,
+ private_linked_list_t *this, private_enumerator_t *enumerator,
+ void *item)
+{
+ void *old = NULL;
+
+ if (enumerator->current)
+ {
+ old = enumerator->current->value;
+ enumerator->current->value = item;
+ }
+ return old;
+}
+
+METHOD(linked_list_t, get_last, status_t,
+ private_linked_list_t *this, void **item)
{
if (this->count == 0)
{
@@ -497,10 +340,8 @@ static status_t get_last(private_linked_list_t *this, void **item)
return SUCCESS;
}
-/**
- * Implementation of linked_list_t.remove_last.
- */
-static status_t remove_last(private_linked_list_t *this, void **item)
+METHOD(linked_list_t, remove_last, status_t,
+ private_linked_list_t *this, void **item)
{
if (get_last(this, item) == SUCCESS)
{
@@ -510,11 +351,8 @@ static status_t remove_last(private_linked_list_t *this, void **item)
return NOT_FOUND;
}
-/**
- * Implementation of linked_list_t.remove.
- */
-static int remove_(private_linked_list_t *this, void *item,
- bool (*compare)(void *,void*))
+METHOD(linked_list_t, remove_, int,
+ private_linked_list_t *this, void *item, bool (*compare)(void*,void*))
{
element_t *current = this->first;
int removed = 0;
@@ -535,10 +373,8 @@ static int remove_(private_linked_list_t *this, void *item,
return removed;
}
-/**
- * Implementation of linked_list_t.remove_at.
- */
-static void remove_at(private_linked_list_t *this, private_enumerator_t *enumerator)
+METHOD(linked_list_t, remove_at, void,
+ private_linked_list_t *this, private_enumerator_t *enumerator)
{
element_t *current;
@@ -550,11 +386,9 @@ static void remove_at(private_linked_list_t *this, private_enumerator_t *enumera
}
}
-/**
- * Implementation of linked_list_t.find_first.
- */
-static status_t find_first(private_linked_list_t *this, linked_list_match_t match,
- void **item, void *d1, void *d2, void *d3, void *d4, void *d5)
+METHOD(linked_list_t, find_first, status_t,
+ private_linked_list_t *this, linked_list_match_t match,
+ void **item, void *d1, void *d2, void *d3, void *d4, void *d5)
{
element_t *current = this->first;
@@ -574,11 +408,9 @@ static status_t find_first(private_linked_list_t *this, linked_list_match_t matc
return NOT_FOUND;
}
-/**
- * Implementation of linked_list_t.find_last.
- */
-static status_t find_last(private_linked_list_t *this, linked_list_match_t match,
- void **item, void *d1, void *d2, void *d3, void *d4, void *d5)
+METHOD(linked_list_t, find_last, status_t,
+ private_linked_list_t *this, linked_list_match_t match,
+ void **item, void *d1, void *d2, void *d3, void *d4, void *d5)
{
element_t *current = this->last;
@@ -598,27 +430,24 @@ static status_t find_last(private_linked_list_t *this, linked_list_match_t match
return NOT_FOUND;
}
-/**
- * Implementation of linked_list_t.invoke_offset.
- */
-static void invoke_offset(private_linked_list_t *this, size_t offset,
- void *d1, void *d2, void *d3, void *d4, void *d5)
+METHOD(linked_list_t, invoke_offset, void,
+ private_linked_list_t *this, size_t offset,
+ void *d1, void *d2, void *d3, void *d4, void *d5)
{
element_t *current = this->first;
+ linked_list_invoke_t *method;
while (current)
{
- linked_list_invoke_t *method = current->value + offset;
+ method = current->value + offset;
(*method)(current->value, d1, d2, d3, d4, d5);
current = current->next;
}
}
-/**
- * Implementation of linked_list_t.invoke_function.
- */
-static void invoke_function(private_linked_list_t *this, linked_list_invoke_t fn,
- void *d1, void *d2, void *d3, void *d4, void *d5)
+METHOD(linked_list_t, invoke_function, void,
+ private_linked_list_t *this, linked_list_invoke_t fn,
+ void *d1, void *d2, void *d3, void *d4, void *d5)
{
element_t *current = this->first;
@@ -629,14 +458,13 @@ static void invoke_function(private_linked_list_t *this, linked_list_invoke_t fn
}
}
-/**
- * Implementation of linked_list_t.clone_offset
- */
-static linked_list_t *clone_offset(private_linked_list_t *this, size_t offset)
+METHOD(linked_list_t, clone_offset, linked_list_t*,
+ private_linked_list_t *this, size_t offset)
{
- linked_list_t *clone = linked_list_create();
element_t *current = this->first;
+ linked_list_t *clone;
+ clone = linked_list_create();
while (current)
{
void* (**method)(void*) = current->value + offset;
@@ -647,29 +475,26 @@ static linked_list_t *clone_offset(private_linked_list_t *this, size_t offset)
return clone;
}
-/**
- * Implementation of linked_list_t.clone_function
- */
-static linked_list_t *clone_function(private_linked_list_t *this, void* (*fn)(void*))
+METHOD(linked_list_t, clone_function, linked_list_t*,
+ private_linked_list_t *this, void* (*fn)(void*))
{
- linked_list_t *clone = linked_list_create();
element_t *current = this->first;
+ linked_list_t *clone;
+ clone = linked_list_create();
while (current)
{
clone->insert_last(clone, fn(current->value));
current = current->next;
}
-
return clone;
}
-/**
- * Implementation of linked_list_t.destroy.
- */
-static void destroy(private_linked_list_t *this)
+METHOD(linked_list_t, destroy, void,
+ private_linked_list_t *this)
{
void *value;
+
/* Remove all list items before destroying list */
while (remove_first(this, &value) == SUCCESS)
{
@@ -679,10 +504,8 @@ static void destroy(private_linked_list_t *this)
free(this);
}
-/**
- * Implementation of linked_list_t.destroy_offset.
- */
-static void destroy_offset(private_linked_list_t *this, size_t offset)
+METHOD(linked_list_t, destroy_offset, void,
+ private_linked_list_t *this, size_t offset)
{
element_t *current = this->first, *next;
@@ -697,10 +520,8 @@ static void destroy_offset(private_linked_list_t *this, size_t offset)
free(this);
}
-/**
- * Implementation of linked_list_t.destroy_function.
- */
-static void destroy_function(private_linked_list_t *this, void (*fn)(void*))
+METHOD(linked_list_t, destroy_function, void,
+ private_linked_list_t *this, void (*fn)(void*))
{
element_t *current = this->first, *next;
@@ -714,60 +535,40 @@ static void destroy_function(private_linked_list_t *this, void (*fn)(void*))
free(this);
}
-/**
- * Implementation of linked_list_t.create_iterator.
- */
-static iterator_t *create_iterator(private_linked_list_t *linked_list, bool forward)
-{
- private_iterator_t *this = malloc_thing(private_iterator_t);
-
- this->public.get_count = (int (*) (iterator_t*)) get_list_count;
- this->public.iterate = (bool (*) (iterator_t*, void **value)) iterate;
- this->public.insert_before = (void (*) (iterator_t*, void *item)) insert_before;
- this->public.insert_after = (void (*) (iterator_t*, void *item)) insert_after;
- this->public.replace = (status_t (*) (iterator_t*, void **, void *)) replace;
- this->public.remove = (status_t (*) (iterator_t*)) iterator_remove;
- this->public.reset = (void (*) (iterator_t*)) iterator_reset;
- this->public.destroy = (void (*) (iterator_t*)) iterator_destroy;
-
- this->forward = forward;
- this->current = NULL;
- this->list = linked_list;
-
- return &this->public;
-}
-
/*
* Described in header.
*/
linked_list_t *linked_list_create()
{
- private_linked_list_t *this = malloc_thing(private_linked_list_t);
-
- this->public.get_count = (int (*) (linked_list_t *)) get_count;
- this->public.create_iterator = (iterator_t * (*) (linked_list_t *,bool))create_iterator;
- this->public.create_enumerator = (enumerator_t*(*)(linked_list_t*))create_enumerator;
- this->public.get_first = (status_t (*) (linked_list_t *, void **item))get_first;
- this->public.get_last = (status_t (*) (linked_list_t *, void **item))get_last;
- this->public.find_first = (status_t (*) (linked_list_t *, linked_list_match_t,void**,...))find_first;
- this->public.find_last = (status_t (*) (linked_list_t *, linked_list_match_t,void**,...))find_last;
- this->public.insert_first = (void (*) (linked_list_t *, void *item))insert_first;
- this->public.insert_last = (void (*) (linked_list_t *, void *item))insert_last;
- this->public.remove_first = (status_t (*) (linked_list_t *, void **item))remove_first;
- this->public.remove_last = (status_t (*) (linked_list_t *, void **item))remove_last;
- this->public.remove = (int(*)(linked_list_t*, void *item, bool (*compare)(void *,void*)))remove_;
- this->public.remove_at = (void(*)(linked_list_t*, enumerator_t *enumerator))remove_at;
- this->public.invoke_offset = (void (*)(linked_list_t*,size_t,...))invoke_offset;
- this->public.invoke_function = (void (*)(linked_list_t*,linked_list_invoke_t,...))invoke_function;
- this->public.clone_offset = (linked_list_t * (*)(linked_list_t*,size_t))clone_offset;
- this->public.clone_function = (linked_list_t * (*)(linked_list_t*,void*(*)(void*)))clone_function;
- this->public.destroy = (void (*) (linked_list_t *))destroy;
- this->public.destroy_offset = (void (*) (linked_list_t *,size_t))destroy_offset;
- this->public.destroy_function = (void (*)(linked_list_t*,void(*)(void*)))destroy_function;
-
- this->count = 0;
- this->first = NULL;
- this->last = NULL;
+ private_linked_list_t *this;
+
+ INIT(this,
+ .public = {
+ .get_count = _get_count,
+ .create_enumerator = _create_enumerator,
+ .reset_enumerator = (void*)_reset_enumerator,
+ .has_more = (void*)_has_more,
+ .get_first = _get_first,
+ .get_last = _get_last,
+ .find_first = (void*)_find_first,
+ .find_last = (void*)_find_last,
+ .insert_first = _insert_first,
+ .insert_last = _insert_last,
+ .insert_before = (void*)_insert_before,
+ .replace = (void*)_replace,
+ .remove_first = _remove_first,
+ .remove_last = _remove_last,
+ .remove = _remove_,
+ .remove_at = (void*)_remove_at,
+ .invoke_offset = (void*)_invoke_offset,
+ .invoke_function = (void*)_invoke_function,
+ .clone_offset = _clone_offset,
+ .clone_function = _clone_function,
+ .destroy = _destroy,
+ .destroy_offset = _destroy_offset,
+ .destroy_function = _destroy_function,
+ },
+ );
return &this->public;
}
diff --git a/src/libstrongswan/utils/linked_list.h b/src/libstrongswan/utils/linked_list.h
index 1444c93fc..293ca8661 100644
--- a/src/libstrongswan/utils/linked_list.h
+++ b/src/libstrongswan/utils/linked_list.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2008 Tobias Brunner
+ * Copyright (C) 2007-2011 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -25,7 +25,6 @@
typedef struct linked_list_t linked_list_t;
-#include <utils/iterator.h>
#include <utils/enumerator.h>
/**
@@ -62,27 +61,29 @@ struct linked_list_t {
int (*get_count) (linked_list_t *this);
/**
- * Creates a iterator for the given list.
- *
- * @warning Created iterator_t object has to get destroyed by the caller.
+ * Create an enumerator over the list.
*
- * @deprecated Iterator is obsolete and will disappear, it is too
- * complicated to implement. Use enumerator instead.
+ * @note The enumerator's position is invalid before the first call
+ * to enumerate().
*
- * @param forward iterator direction (TRUE: front to end)
- * @return new iterator_t object
+ * @return enumerator over list items
*/
- iterator_t *(*create_iterator) (linked_list_t *this, bool forward);
+ enumerator_t* (*create_enumerator)(linked_list_t *this);
/**
- * Create an enumerator over the list.
+ * Resets the enumerator's current position to the beginning of the list.
*
- * The enumerator is a "lightweight" iterator. It only has two methods
- * and should therefore be much easier to implement.
+ * @param enumerator enumerator to reset
+ */
+ void (*reset_enumerator)(linked_list_t *this, enumerator_t *enumerator);
+
+ /**
+ * Checks if there are more elements following after the enumerator's
+ * current position.
*
- * @return enumerator over list items
+ * @param enumerator enumerator to check
*/
- enumerator_t* (*create_enumerator)(linked_list_t *this);
+ bool (*has_more)(linked_list_t *this, enumerator_t *enumerator);
/**
* Inserts a new item at the beginning of the list.
@@ -100,6 +101,32 @@ struct linked_list_t {
status_t (*remove_first) (linked_list_t *this, void **item);
/**
+ * Inserts a new item before the item the enumerator currently points to.
+ *
+ * If this method is called before starting the enumeration the item is
+ * inserted first. If it is called after all items have been enumerated
+ * the item is inserted last. This is helpful when inserting items into
+ * a sorted list.
+ *
+ * @note The position of the enumerator is not changed.
+ *
+ * @param enumerator enumerator with position
+ * @param item item value to insert in list
+ */
+ void (*insert_before)(linked_list_t *this, enumerator_t *enumerator,
+ void *item);
+
+ /**
+ * Replaces the item the enumerator currently points to with the given item.
+ *
+ * @param enumerator enumerator with position
+ * @param item item value to replace current item with
+ * @return current item or NULL if the enumerator is at an
+ * invalid position
+ */
+ void *(*replace)(linked_list_t *this, enumerator_t *enumerator, void *item);
+
+ /**
* Remove an item from the list where the enumerator points to.
*
* @param enumerator enumerator with position
@@ -125,7 +152,6 @@ struct linked_list_t {
/**
* Returns the value of the first list item without removing it.
*
- * @param this calling object
* @param item returned value of first item
* @return SUCCESS, NOT_FOUND if list is empty
*/
@@ -141,7 +167,6 @@ struct linked_list_t {
/**
* Removes the last item in the list and returns its value.
*
- * @param this calling object
* @param item returned value of last item, or NULL
* @return SUCCESS, NOT_FOUND if list is empty
*/
@@ -150,7 +175,6 @@ struct linked_list_t {
/**
* Returns the value of the last list item without removing it.
*
- * @param this calling object
* @param item returned value of last item
* @return SUCCESS, NOT_FOUND if list is empty
*/
diff --git a/src/libstrongswan/utils/optionsfrom.c b/src/libstrongswan/utils/optionsfrom.c
index e51780290..5fd4cfd4d 100644
--- a/src/libstrongswan/utils/optionsfrom.c
+++ b/src/libstrongswan/utils/optionsfrom.c
@@ -67,7 +67,6 @@ METHOD(options_t, from, bool,
int newargc;
int next; /* place for next argument */
char **newargv;
- size_t bytes;
chunk_t src, line, token;
bool good = TRUE;
int linepos = 0;
@@ -99,7 +98,14 @@ METHOD(options_t, from, bool,
src.ptr = this->buffers[this->nuses] = malloc(src.len + 1);
/* read the whole file into a chunk */
- bytes = fread(src.ptr, 1, src.len, fd);
+ if (fread(src.ptr, 1, src.len, fd) != src.len)
+ {
+ DBG1(DBG_LIB, "optionsfrom: unable to read file '%s': %s",
+ filename, strerror(errno));
+ free(src.ptr);
+ fclose(fd);
+ return FALSE;
+ }
fclose(fd);
if (this->room)
diff --git a/src/libtls/Makefile.am b/src/libtls/Makefile.am
index a58e783d7..4cc1a1bdb 100644
--- a/src/libtls/Makefile.am
+++ b/src/libtls/Makefile.am
@@ -1,7 +1,7 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan
-noinst_LTLIBRARIES = libtls.la
+ipseclib_LTLIBRARIES = libtls.la
libtls_la_SOURCES = \
tls_protection.h tls_protection.c \
tls_compression.h tls_compression.c \
@@ -9,10 +9,9 @@ libtls_la_SOURCES = \
tls_alert.h tls_alert.c \
tls_crypto.h tls_crypto.c \
tls_prf.h tls_prf.c \
- tls_reader.h tls_reader.c \
- tls_writer.h tls_writer.c \
tls_socket.h tls_socket.c \
tls_eap.h tls_eap.c \
+ tls_cache.h tls_cache.c \
tls_peer.h tls_peer.c \
tls_server.h tls_server.c \
tls_handshake.h tls_application.h tls.h tls.c
diff --git a/src/libtls/Makefile.in b/src/libtls/Makefile.in
index 5a1aa81c0..844b65156 100644
--- a/src/libtls/Makefile.in
+++ b/src/libtls/Makefile.in
@@ -51,12 +51,34 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
-LTLIBRARIES = $(noinst_LTLIBRARIES)
+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)$(ipseclibdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
libtls_la_LIBADD =
am_libtls_la_OBJECTS = tls_protection.lo tls_compression.lo \
tls_fragmentation.lo tls_alert.lo tls_crypto.lo tls_prf.lo \
- tls_reader.lo tls_writer.lo tls_socket.lo tls_eap.lo \
- tls_peer.lo tls_server.lo tls.lo
+ tls_socket.lo tls_eap.lo tls_cache.lo tls_peer.lo \
+ tls_server.lo tls.lo
libtls_la_OBJECTS = $(am_libtls_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -167,6 +189,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -175,6 +200,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -191,11 +217,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -239,6 +267,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -250,7 +279,7 @@ urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
INCLUDES = -I$(top_srcdir)/src/libstrongswan
-noinst_LTLIBRARIES = libtls.la
+ipseclib_LTLIBRARIES = libtls.la
libtls_la_SOURCES = \
tls_protection.h tls_protection.c \
tls_compression.h tls_compression.c \
@@ -258,10 +287,9 @@ libtls_la_SOURCES = \
tls_alert.h tls_alert.c \
tls_crypto.h tls_crypto.c \
tls_prf.h tls_prf.c \
- tls_reader.h tls_reader.c \
- tls_writer.h tls_writer.c \
tls_socket.h tls_socket.c \
tls_eap.h tls_eap.c \
+ tls_cache.h tls_cache.c \
tls_peer.h tls_peer.c \
tls_server.h tls_server.c \
tls_handshake.h tls_application.h tls.h tls.c
@@ -300,17 +328,39 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
+ }
+
+uninstall-ipseclibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
+ done
-clean-noinstLTLIBRARIES:
- -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
- @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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
libtls.la: $(libtls_la_OBJECTS) $(libtls_la_DEPENDENCIES)
- $(LINK) $(libtls_la_OBJECTS) $(libtls_la_LIBADD) $(LIBS)
+ $(LINK) -rpath $(ipseclibdir) $(libtls_la_OBJECTS) $(libtls_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -320,6 +370,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_alert.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_cache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_compression.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_crypto.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_eap.Plo@am__quote@
@@ -327,10 +378,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_peer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_prf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_protection.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_reader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_server.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_socket.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_writer.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -445,6 +494,9 @@ check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
+ for dir in "$(DESTDIR)$(ipseclibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
@@ -472,7 +524,7 @@ maintainer-clean-generic:
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
@@ -493,7 +545,7 @@ info: info-am
info-am:
-install-data-am:
+install-data-am: install-ipseclibLTLIBRARIES
install-dvi: install-dvi-am
@@ -539,22 +591,23 @@ ps: ps-am
ps-am:
-uninstall-am:
+uninstall-am: uninstall-ipseclibLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ clean-ipseclibLTLIBRARIES clean-libtool 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-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
+ install-html-am install-info install-info-am \
+ install-ipseclibLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-ipseclibLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/libtls/tls.c b/src/libtls/tls.c
index ea527b122..2bcaffbc8 100644
--- a/src/libtls/tls.c
+++ b/src/libtls/tls.c
@@ -192,6 +192,14 @@ struct private_tls_t {
size_t headpos;
};
+/**
+ * Described in header.
+ */
+void libtls_init(void)
+{
+ /* empty */
+}
+
METHOD(tls_t, process, status_t,
private_tls_t *this, void *buf, size_t buflen)
{
@@ -429,7 +437,7 @@ METHOD(tls_t, destroy, void,
*/
tls_t *tls_create(bool is_server, identification_t *server,
identification_t *peer, tls_purpose_t purpose,
- tls_application_t *application)
+ tls_application_t *application, tls_cache_t *cache)
{
private_tls_t *this;
@@ -464,7 +472,7 @@ tls_t *tls_create(bool is_server, identification_t *server,
.purpose = purpose,
);
- this->crypto = tls_crypto_create(&this->public);
+ this->crypto = tls_crypto_create(&this->public, cache);
this->alert = tls_alert_create();
if (is_server)
{
diff --git a/src/libtls/tls.h b/src/libtls/tls.h
index 54b0621b5..e22b0facc 100644
--- a/src/libtls/tls.h
+++ b/src/libtls/tls.h
@@ -35,6 +35,7 @@ typedef struct tls_t tls_t;
#include <library.h>
#include "tls_application.h"
+#include "tls_cache.h"
/**
* TLS/SSL version numbers
@@ -228,6 +229,11 @@ struct tls_t {
};
/**
+ * Dummy libtls initialization function needed for integrity test
+ */
+void libtls_init(void);
+
+/**
* Create a tls instance.
*
* @param is_server TRUE to act as server, FALSE for client
@@ -235,10 +241,11 @@ struct tls_t {
* @param peer peer identity, NULL for no client authentication
* @param purpose purpose this TLS stack instance is used for
* @param application higher layer application or NULL if none
+ * @param cache session cache to use, or NULL
* @return TLS stack
*/
tls_t *tls_create(bool is_server, identification_t *server,
identification_t *peer, tls_purpose_t purpose,
- tls_application_t *application);
+ tls_application_t *application, tls_cache_t *cache);
#endif /** TLS_H_ @}*/
diff --git a/src/libtls/tls_alert.h b/src/libtls/tls_alert.h
index 95ba4d91b..8ce50f83d 100644
--- a/src/libtls/tls_alert.h
+++ b/src/libtls/tls_alert.h
@@ -98,7 +98,7 @@ struct tls_alert_t {
/**
* Did a fatal alert occur?.
*
- * @return TRUE if a fatal alert has occured
+ * @return TRUE if a fatal alert has occurred
*/
bool (*fatal)(tls_alert_t *this);
diff --git a/src/libtls/tls_application.h b/src/libtls/tls_application.h
index b54a25e22..bd839fbb6 100644
--- a/src/libtls/tls_application.h
+++ b/src/libtls/tls_application.h
@@ -23,8 +23,8 @@
typedef struct tls_application_t tls_application_t;
-#include "tls_reader.h"
-#include "tls_writer.h"
+#include <bio/bio_reader.h>
+#include <bio/bio_writer.h>
/**
* TLS application data interface.
@@ -40,7 +40,7 @@ struct tls_application_t {
* - FAILED if application data processing failed
* - NEED_MORE if another invocation of process/build needed
*/
- status_t (*process)(tls_application_t *this, tls_reader_t *reader);
+ status_t (*process)(tls_application_t *this, bio_reader_t *reader);
/**
* Build TLS application data to send out.
@@ -52,7 +52,7 @@ struct tls_application_t {
* - NEED_MORE if more data ready for delivery
* - INVALID_STATE if more input to process() required
*/
- status_t (*build)(tls_application_t *this, tls_writer_t *writer);
+ status_t (*build)(tls_application_t *this, bio_writer_t *writer);
/**
* Destroy a tls_application_t.
diff --git a/src/libtls/tls_cache.c b/src/libtls/tls_cache.c
new file mode 100644
index 000000000..a89201ad7
--- /dev/null
+++ b/src/libtls/tls_cache.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 "tls_cache.h"
+
+#include <debug.h>
+#include <utils/linked_list.h>
+#include <utils/hashtable.h>
+#include <threading/rwlock.h>
+
+typedef struct private_tls_cache_t private_tls_cache_t;
+
+/**
+ * Private data of an tls_cache_t object.
+ */
+struct private_tls_cache_t {
+
+ /**
+ * Public tls_cache_t interface.
+ */
+ tls_cache_t public;
+
+ /**
+ * Mapping session => entry_t, fast lookup by session
+ */
+ hashtable_t *table;
+
+ /**
+ * List containing all entries
+ */
+ linked_list_t *list;
+
+ /**
+ * Lock to list and table
+ */
+ rwlock_t *lock;
+
+ /**
+ * Session limit
+ */
+ u_int max_sessions;
+
+ /**
+ * maximum age of a session, in seconds
+ */
+ u_int max_age;
+};
+
+/**
+ * Hashtable entry
+ */
+typedef struct {
+ /** session identifier */
+ chunk_t session;
+ /** master secret */
+ chunk_t master;
+ /** TLS cipher suite */
+ tls_cipher_suite_t suite;
+ /** optional identity this entry is bound to */
+ identification_t *id;
+ /** time of add */
+ time_t t;
+} entry_t;
+
+/**
+ * Destroy an entry
+ */
+static void entry_destroy(entry_t *entry)
+{
+ chunk_clear(&entry->session);
+ chunk_clear(&entry->master);
+ DESTROY_IF(entry->id);
+ free(entry);
+}
+
+/**
+ * Hashtable hash function
+ */
+static u_int hash(chunk_t *key)
+{
+ return chunk_hash(*key);
+}
+
+/**
+ * Hashtable equals function
+ */
+static bool equals(chunk_t *a, chunk_t *b)
+{
+ return chunk_equals(*a, *b);
+}
+
+METHOD(tls_cache_t, create_, void,
+ private_tls_cache_t *this, chunk_t session, identification_t *id,
+ chunk_t master, tls_cipher_suite_t suite)
+{
+ entry_t *entry;
+
+ INIT(entry,
+ .session = chunk_clone(session),
+ .master = chunk_clone(master),
+ .suite = suite,
+ .id = id ? id->clone(id) : NULL,
+ .t = time_monotonic(NULL),
+ );
+
+ this->lock->write_lock(this->lock);
+ this->list->insert_first(this->list, entry);
+ this->table->put(this->table, &entry->session, entry);
+ if (this->list->get_count(this->list) > this->max_sessions &&
+ this->list->remove_last(this->list, (void**)&entry) == SUCCESS)
+ {
+ DBG2(DBG_TLS, "session limit of %u reached, deleting %#B",
+ this->max_sessions, &entry->session);
+ this->table->remove(this->table, &entry->session);
+ entry_destroy(entry);
+ }
+ this->lock->unlock(this->lock);
+
+ DBG2(DBG_TLS, "created TLS session %#B, %d sessions",
+ &session, this->list->get_count(this->list));
+}
+
+METHOD(tls_cache_t, lookup, tls_cipher_suite_t,
+ private_tls_cache_t *this, chunk_t session, identification_t *id,
+ chunk_t* master)
+{
+ tls_cipher_suite_t suite = 0;
+ entry_t *entry;
+ time_t now;
+ u_int age;
+
+ now = time_monotonic(NULL);
+
+ this->lock->write_lock(this->lock);
+ entry = this->table->get(this->table, &session);
+ if (entry)
+ {
+ age = now - entry->t;
+ if (age <= this->max_age)
+ {
+ if (!id || !entry->id || id->equals(id, entry->id))
+ {
+ *master = chunk_clone(entry->master);
+ suite = entry->suite;
+ }
+ }
+ else
+ {
+ DBG2(DBG_TLS, "TLS session %#B expired: %u seconds", &session, age);
+ }
+ }
+ this->lock->unlock(this->lock);
+
+ if (suite)
+ {
+ DBG2(DBG_TLS, "resuming TLS session %#B, age %u seconds", &session, age);
+ }
+ return suite;
+}
+
+METHOD(tls_cache_t, check, chunk_t,
+ private_tls_cache_t *this, identification_t *id)
+{
+ chunk_t session = chunk_empty;
+ enumerator_t *enumerator;
+ entry_t *entry;
+ time_t now;
+
+ now = time_monotonic(NULL);
+ this->lock->read_lock(this->lock);
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->t + this->max_age >= now &&
+ entry->id && id->equals(id, entry->id))
+ {
+ session = chunk_clone(entry->session);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+
+ return session;
+}
+
+METHOD(tls_cache_t, destroy, void,
+ private_tls_cache_t *this)
+{
+ entry_t *entry;
+
+ while (this->list->remove_last(this->list, (void**)&entry) == SUCCESS)
+ {
+ entry_destroy(entry);
+ }
+ this->list->destroy(this->list);
+ this->table->destroy(this->table);
+ this->lock->destroy(this->lock);
+ free(this);
+}
+
+/**
+ * See header
+ */
+tls_cache_t *tls_cache_create(u_int max_sessions, u_int max_age)
+{
+ private_tls_cache_t *this;
+
+ INIT(this,
+ .public = {
+ .create = _create_,
+ .lookup = _lookup,
+ .check = _check,
+ .destroy = _destroy,
+ },
+ .table = hashtable_create((hashtable_hash_t)hash,
+ (hashtable_equals_t)equals, 8),
+ .list = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ .max_sessions = max_sessions,
+ .max_age = max_age,
+ );
+
+ return &this->public;
+}
diff --git a/src/libtls/tls_cache.h b/src/libtls/tls_cache.h
new file mode 100644
index 000000000..ea4e2013e
--- /dev/null
+++ b/src/libtls/tls_cache.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <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 tls_cache tls_cache
+ * @{ @ingroup libtls
+ */
+
+#ifndef TLS_CACHE_H_
+#define TLS_CACHE_H_
+
+typedef struct tls_cache_t tls_cache_t;
+
+#include "tls_crypto.h"
+
+/**
+ * TLS session cache facility.
+ */
+struct tls_cache_t {
+
+ /**
+ * Create a new TLS session entry.
+ *
+ * @param session session identifier
+ * @param id identity the session is bound to
+ * @param master TLS master secret
+ * @param suite TLS cipher suite of the session
+ */
+ void (*create)(tls_cache_t *this, chunk_t session, identification_t *id,
+ chunk_t master, tls_cipher_suite_t suite);
+
+ /**
+ * Look up a TLS session entry.
+ *
+ * @param session session ID to find
+ * @param id identity the session is bound to
+ * @param master gets allocated master secret, if session found
+ * @return TLS suite of session, 0 if none found
+ */
+ tls_cipher_suite_t (*lookup)(tls_cache_t *this, chunk_t session,
+ identification_t *id, chunk_t* master);
+
+ /**
+ * Check if we have a session for a given identity.
+ *
+ * @param id identity to check
+ * @return allocated session ID, or chunk_empty
+ */
+ chunk_t (*check)(tls_cache_t *this, identification_t *id);
+
+ /**
+ * Destroy a tls_cache_t.
+ */
+ void (*destroy)(tls_cache_t *this);
+};
+
+/**
+ * Create a tls_cache instance.
+ *
+ * @param max_sessions maximum number of sessions to store
+ * @param max_age maximum age of a session, in seconds
+ * @return tls cache
+ */
+tls_cache_t *tls_cache_create(u_int max_sessions, u_int max_age);
+
+#endif /** TLS_CACHE_H_ @}*/
diff --git a/src/libtls/tls_compression.h b/src/libtls/tls_compression.h
index b4832ab06..b2c60d5d6 100644
--- a/src/libtls/tls_compression.h
+++ b/src/libtls/tls_compression.h
@@ -23,12 +23,12 @@
#include <library.h>
+typedef struct tls_compression_t tls_compression_t;
+
#include "tls.h"
#include "tls_alert.h"
#include "tls_fragmentation.h"
-typedef struct tls_compression_t tls_compression_t;
-
/**
* TLS record protocol compression layer.
*/
diff --git a/src/libtls/tls_crypto.c b/src/libtls/tls_crypto.c
index b000f9d47..4d84876d0 100644
--- a/src/libtls/tls_crypto.c
+++ b/src/libtls/tls_crypto.c
@@ -370,6 +370,11 @@ struct private_tls_crypto_t {
tls_t *tls;
/**
+ * TLS session cache
+ */
+ tls_cache_t *cache;
+
+ /**
* All handshake data concatentated
*/
chunk_t handshake;
@@ -437,7 +442,7 @@ typedef struct {
static suite_algs_t suite_algs[] = {
{ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
KEY_ECDSA, ECP_256_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
},
{ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
@@ -447,7 +452,7 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
KEY_ECDSA, ECP_384_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
},
{ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
@@ -457,7 +462,7 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
KEY_RSA, ECP_256_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
},
{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
@@ -467,7 +472,7 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
KEY_RSA, ECP_384_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
},
{ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
@@ -477,7 +482,7 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
KEY_RSA, MODP_2048_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256,PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
},
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
@@ -487,7 +492,7 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
KEY_RSA, MODP_3072_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
},
{ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
@@ -497,7 +502,7 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
KEY_RSA, MODP_2048_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16
},
{ TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
@@ -507,7 +512,7 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
KEY_RSA, MODP_3072_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32
},
{ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
@@ -517,12 +522,12 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
KEY_RSA, MODP_2048_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_3DES, 0
},
{ TLS_RSA_WITH_AES_128_CBC_SHA,
KEY_RSA, MODP_NONE,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16
},
{ TLS_RSA_WITH_AES_128_CBC_SHA256,
@@ -532,7 +537,7 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_RSA_WITH_AES_256_CBC_SHA,
KEY_RSA, MODP_NONE,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32
},
{ TLS_RSA_WITH_AES_256_CBC_SHA256,
@@ -542,7 +547,7 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
KEY_RSA, MODP_NONE,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16
},
{ TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
@@ -552,7 +557,7 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
KEY_RSA, MODP_NONE,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32
},
{ TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
@@ -562,32 +567,32 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
KEY_ECDSA, ECP_256_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_3DES, 0
},
{ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
KEY_RSA, ECP_256_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_3DES, 0
},
{ TLS_RSA_WITH_3DES_EDE_CBC_SHA,
KEY_RSA, MODP_NONE,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_3DES, 0
},
{ TLS_ECDHE_ECDSA_WITH_NULL_SHA,
KEY_ECDSA, ECP_256_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_NULL, 0
},
{ TLS_ECDHE_RSA_WITH_NULL_SHA,
KEY_ECDSA, ECP_256_BIT,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_NULL, 0
},
{ TLS_RSA_WITH_NULL_SHA,
KEY_RSA, MODP_NONE,
- HASH_SHA1, PRF_HMAC_SHA1,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_SHA1_160, ENCR_NULL, 0
},
{ TLS_RSA_WITH_NULL_SHA256,
@@ -597,13 +602,13 @@ static suite_algs_t suite_algs[] = {
},
{ TLS_RSA_WITH_NULL_MD5,
KEY_RSA, MODP_NONE,
- HASH_MD5, PRF_HMAC_MD5,
+ HASH_SHA256, PRF_HMAC_SHA2_256,
AUTH_HMAC_MD5_128, ENCR_NULL, 0
},
};
/**
- * Look up algoritms by a suite
+ * Look up algorithms by a suite
*/
static suite_algs_t *find_suite(tls_cipher_suite_t suite)
{
@@ -834,25 +839,25 @@ static void filter_mac_config_suites(private_tls_crypto_t *this,
while (enumerator->enumerate(enumerator, &token))
{
if (strcaseeq(token, "md5") &&
- suites[i].hash == HASH_MD5)
+ suites[i].mac == AUTH_HMAC_MD5_128)
{
suites[remaining++] = suites[i];
break;
}
if (strcaseeq(token, "sha1") &&
- suites[i].hash == HASH_SHA1)
+ suites[i].mac == AUTH_HMAC_SHA1_160)
{
suites[remaining++] = suites[i];
break;
}
if (strcaseeq(token, "sha256") &&
- suites[i].hash == HASH_SHA256)
+ suites[i].mac == AUTH_HMAC_SHA2_256_256)
{
suites[remaining++] = suites[i];
break;
}
if (strcaseeq(token, "sha384") &&
- suites[i].hash == HASH_SHA384)
+ suites[i].mac == AUTH_HMAC_SHA2_384_384)
{
suites[remaining++] = suites[i];
break;
@@ -1057,15 +1062,15 @@ METHOD(tls_crypto_t, get_dh_group, diffie_hellman_group_t,
}
METHOD(tls_crypto_t, get_signature_algorithms, void,
- private_tls_crypto_t *this, tls_writer_t *writer)
+ private_tls_crypto_t *this, bio_writer_t *writer)
{
- tls_writer_t *supported;
+ bio_writer_t *supported;
enumerator_t *enumerator;
hash_algorithm_t alg;
tls_hash_algorithm_t hash;
const char *plugin_name;
- supported = tls_writer_create(32);
+ supported = bio_writer_create(32);
enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
while (enumerator->enumerate(enumerator, &alg, &plugin_name))
{
@@ -1280,13 +1285,13 @@ static signature_scheme_t hashsig_to_scheme(key_type_t type,
}
METHOD(tls_crypto_t, sign, bool,
- private_tls_crypto_t *this, private_key_t *key, tls_writer_t *writer,
+ private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer,
chunk_t data, chunk_t hashsig)
{
if (this->tls->get_version(this->tls) >= TLS_1_2)
{
signature_scheme_t scheme;
- tls_reader_t *reader;
+ bio_reader_t *reader;
u_int8_t hash, alg;
chunk_t sig;
bool done = FALSE;
@@ -1296,7 +1301,7 @@ METHOD(tls_crypto_t, sign, bool,
hashsig = chunk_from_chars(
TLS_HASH_SHA1, TLS_SIG_RSA, TLS_HASH_SHA1, TLS_SIG_ECDSA);
}
- reader = tls_reader_create(hashsig);
+ reader = bio_reader_create(hashsig);
while (reader->remaining(reader) >= 2)
{
if (reader->read_uint8(reader, &hash) &&
@@ -1361,7 +1366,7 @@ METHOD(tls_crypto_t, sign, bool,
}
METHOD(tls_crypto_t, verify, bool,
- private_tls_crypto_t *this, public_key_t *key, tls_reader_t *reader,
+ private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader,
chunk_t data)
{
if (this->tls->get_version(this->tls) >= TLS_1_2)
@@ -1432,14 +1437,14 @@ METHOD(tls_crypto_t, verify, bool,
}
METHOD(tls_crypto_t, sign_handshake, bool,
- private_tls_crypto_t *this, private_key_t *key, tls_writer_t *writer,
+ private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer,
chunk_t hashsig)
{
return sign(this, key, writer, this->handshake, hashsig);
}
METHOD(tls_crypto_t, verify_handshake, bool,
- private_tls_crypto_t *this, public_key_t *key, tls_reader_t *reader)
+ private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader)
{
return verify(this, key, reader, this->handshake);
}
@@ -1462,13 +1467,15 @@ METHOD(tls_crypto_t, calculate_finished, bool,
return TRUE;
}
-METHOD(tls_crypto_t, derive_secrets, void,
- private_tls_crypto_t *this, chunk_t premaster,
- chunk_t client_random, chunk_t server_random)
+/**
+ * Derive master secret from premaster, optionally save session
+ */
+static void derive_master(private_tls_crypto_t *this, chunk_t premaster,
+ chunk_t session, identification_t *id,
+ chunk_t client_random, chunk_t server_random)
{
char master[48];
- chunk_t seed, block, client_write, server_write;
- int mks, eks = 0, ivs = 0;
+ chunk_t seed;
/* derive master secret */
seed = chunk_cata("cc", client_random, server_random);
@@ -1477,7 +1484,22 @@ METHOD(tls_crypto_t, derive_secrets, void,
sizeof(master), master);
this->prf->set_key(this->prf, chunk_from_thing(master));
- memset(master, 0, sizeof(master));
+ if (this->cache && session.len)
+ {
+ this->cache->create(this->cache, session, id, chunk_from_thing(master),
+ this->suite);
+ }
+ memwipe(master, sizeof(master));
+}
+
+/**
+ * Expand key material from master secret
+ */
+static void expand_keys(private_tls_crypto_t *this,
+ chunk_t client_random, chunk_t server_random)
+{
+ chunk_t seed, block, client_write, server_write;
+ int mks, eks = 0, ivs = 0;
/* derive key block for key expansion */
mks = this->signer_out->get_key_size(this->signer_out);
@@ -1546,6 +1568,57 @@ METHOD(tls_crypto_t, derive_secrets, void,
}
}
}
+
+ /* EAP-MSK */
+ if (this->msk_label)
+ {
+ seed = chunk_cata("cc", client_random, server_random);
+ this->msk = chunk_alloc(64);
+ this->prf->get_bytes(this->prf, this->msk_label, seed,
+ this->msk.len, this->msk.ptr);
+ }
+}
+
+METHOD(tls_crypto_t, derive_secrets, void,
+ private_tls_crypto_t *this, chunk_t premaster, chunk_t session,
+ identification_t *id, chunk_t client_random, chunk_t server_random)
+{
+ derive_master(this, premaster, session, id, client_random, server_random);
+ expand_keys(this, client_random, server_random);
+}
+
+METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t,
+ private_tls_crypto_t *this, chunk_t session, identification_t *id,
+ chunk_t client_random, chunk_t server_random)
+{
+ chunk_t master;
+
+ if (this->cache && session.len)
+ {
+ this->suite = this->cache->lookup(this->cache, session, id, &master);
+ if (this->suite)
+ {
+ this->suite = select_cipher_suite(this, &this->suite, 1, KEY_ANY);
+ if (this->suite)
+ {
+ this->prf->set_key(this->prf, master);
+ expand_keys(this, client_random, server_random);
+ }
+ chunk_clear(&master);
+ }
+ return this->suite;
+ }
+ return 0;
+}
+
+METHOD(tls_crypto_t, get_session, chunk_t,
+ private_tls_crypto_t *this, identification_t *server)
+{
+ if (this->cache)
+ {
+ return this->cache->check(this->cache, server);
+ }
+ return chunk_empty;
}
METHOD(tls_crypto_t, change_cipher, void,
@@ -1566,21 +1639,6 @@ METHOD(tls_crypto_t, change_cipher, void,
}
}
-METHOD(tls_crypto_t, derive_eap_msk, void,
- private_tls_crypto_t *this, chunk_t client_random, chunk_t server_random)
-{
- if (this->msk_label)
- {
- chunk_t seed;
-
- seed = chunk_cata("cc", client_random, server_random);
- free(this->msk.ptr);
- this->msk = chunk_alloc(64);
- this->prf->get_bytes(this->prf, this->msk_label, seed,
- this->msk.len, this->msk.ptr);
- }
-}
-
METHOD(tls_crypto_t, get_eap_msk, chunk_t,
private_tls_crypto_t *this)
{
@@ -1606,7 +1664,7 @@ METHOD(tls_crypto_t, destroy, void,
/**
* See header
*/
-tls_crypto_t *tls_crypto_create(tls_t *tls)
+tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache)
{
private_tls_crypto_t *this;
enumerator_t *enumerator;
@@ -1628,12 +1686,14 @@ tls_crypto_t *tls_crypto_create(tls_t *tls)
.verify_handshake = _verify_handshake,
.calculate_finished = _calculate_finished,
.derive_secrets = _derive_secrets,
+ .resume_session = _resume_session,
+ .get_session = _get_session,
.change_cipher = _change_cipher,
- .derive_eap_msk = _derive_eap_msk,
.get_eap_msk = _get_eap_msk,
.destroy = _destroy,
},
.tls = tls,
+ .cache = cache,
);
enumerator = lib->creds->create_builder_enumerator(lib->creds);
diff --git a/src/libtls/tls_crypto.h b/src/libtls/tls_crypto.h
index f57b8f3e1..7430aea66 100644
--- a/src/libtls/tls_crypto.h
+++ b/src/libtls/tls_crypto.h
@@ -54,13 +54,13 @@ enum tls_cipher_suite_t {
TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008,
TLS_RSA_WITH_DES_CBC_SHA = 0x0009,
TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A,
- TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000B,
+ TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000B,
TLS_DH_DSS_WITH_DES_CBC_SHA = 0x000C,
TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D,
TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x000E,
- TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000F,
+ TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000F,
TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010,
- TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011,
+ TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011,
TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012,
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013,
TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014,
@@ -110,7 +110,7 @@ enum tls_cipher_suite_t {
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0041,
TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0042,
TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0043,
- TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044,
+ TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044,
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0045,
TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA = 0x0046,
@@ -126,8 +126,8 @@ enum tls_cipher_suite_t {
TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0085,
TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0086,
TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0087,
- TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088,
- TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA = 0x0089,
+ TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088,
+ TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA = 0x0089,
TLS_PSK_WITH_RC4_128_SHA = 0x008A,
TLS_PSK_WITH_3DES_EDE_CBC_SHA = 0x008B,
TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C,
@@ -427,7 +427,7 @@ struct tls_crypto_t {
*
* @param writer writer to write supported hash/sig algorithms
*/
- void (*get_signature_algorithms)(tls_crypto_t *this, tls_writer_t *writer);
+ void (*get_signature_algorithms)(tls_crypto_t *this, bio_writer_t *writer);
/**
* Create an enumerator over supported ECDH groups.
@@ -464,7 +464,7 @@ struct tls_crypto_t {
* @return TRUE if signature create successfully
*/
bool (*sign)(tls_crypto_t *this, private_key_t *key,
- tls_writer_t *writer, chunk_t data, chunk_t hashsig);
+ bio_writer_t *writer, chunk_t data, chunk_t hashsig);
/**
* Verify a blob of data, read signature from a reader.
@@ -475,7 +475,7 @@ struct tls_crypto_t {
* @return TRUE if signature valid
*/
bool (*verify)(tls_crypto_t *this, public_key_t *key,
- tls_reader_t *reader, chunk_t data);
+ bio_reader_t *reader, chunk_t data);
/**
* Create a signature of the handshake data using a given private key.
@@ -486,7 +486,7 @@ struct tls_crypto_t {
* @return TRUE if signature create successfully
*/
bool (*sign_handshake)(tls_crypto_t *this, private_key_t *key,
- tls_writer_t *writer, chunk_t hashsig);
+ bio_writer_t *writer, chunk_t hashsig);
/**
* Verify the signature over handshake data using a given public key.
@@ -496,7 +496,7 @@ struct tls_crypto_t {
* @return TRUE if signature valid
*/
bool (*verify_handshake)(tls_crypto_t *this, public_key_t *key,
- tls_reader_t *reader);
+ bio_reader_t *reader);
/**
* Calculate the data of a TLS finished message.
@@ -511,27 +511,43 @@ struct tls_crypto_t {
* Derive the master secret, MAC and encryption keys.
*
* @param premaster premaster secret
+ * @param session session identifier to cache master secret
+ * @param id identity the session is bound to
* @param client_random random data from client hello
* @param server_random random data from server hello
*/
void (*derive_secrets)(tls_crypto_t *this, chunk_t premaster,
+ chunk_t session, identification_t *id,
chunk_t client_random, chunk_t server_random);
/**
- * Change the cipher used at protection layer.
+ * Try to resume a TLS session, derive key material.
*
- * @param inbound TRUE to change inbound cipher, FALSE for outbound
+ * @param session session identifier
+ * @param id identity the session is bound to
+ * @param client_random random data from client hello
+ * @param server_random random data from server hello
+ * @return selected suite
*/
- void (*change_cipher)(tls_crypto_t *this, bool inbound);
+ tls_cipher_suite_t (*resume_session)(tls_crypto_t *this, chunk_t session,
+ identification_t *id,
+ chunk_t client_random,
+ chunk_t server_random);
/**
- * Derive the EAP-TLS MSK.
+ * Check if we have a session to resume as a client.
*
- * @param client_random random data from client hello
- * @param server_random random data from server hello
+ * @param id server identity to get a session for
+ * @return allocated session identifier, or chunk_empty
*/
- void (*derive_eap_msk)(tls_crypto_t *this,
- chunk_t client_random, chunk_t server_random);
+ chunk_t (*get_session)(tls_crypto_t *this, identification_t *id);
+
+ /**
+ * Change the cipher used at protection layer.
+ *
+ * @param inbound TRUE to change inbound cipher, FALSE for outbound
+ */
+ void (*change_cipher)(tls_crypto_t *this, bool inbound);
/**
* Get the MSK to use in EAP-TLS.
@@ -548,7 +564,11 @@ struct tls_crypto_t {
/**
* Create a tls_crypto instance.
+ *
+ * @param tls TLS stack
+ * @param cache TLS session cache
+ * @return TLS crypto helper
*/
-tls_crypto_t *tls_crypto_create(tls_t *tls);
+tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache);
#endif /** TLS_CRYPTO_H_ @}*/
diff --git a/src/libtls/tls_fragmentation.c b/src/libtls/tls_fragmentation.c
index 5a598cfc4..62e36aaec 100644
--- a/src/libtls/tls_fragmentation.c
+++ b/src/libtls/tls_fragmentation.c
@@ -15,8 +15,7 @@
#include "tls_fragmentation.h"
-#include "tls_reader.h"
-
+#include <bio/bio_reader.h>
#include <debug.h>
typedef struct private_tls_fragmentation_t private_tls_fragmentation_t;
@@ -108,7 +107,7 @@ struct private_tls_fragmentation_t {
* Process a TLS alert
*/
static status_t process_alert(private_tls_fragmentation_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
u_int8_t level, description;
@@ -125,11 +124,11 @@ static status_t process_alert(private_tls_fragmentation_t *this,
* Process TLS handshake protocol data
*/
static status_t process_handshake(private_tls_fragmentation_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
while (reader->remaining(reader))
{
- tls_reader_t *msg;
+ bio_reader_t *msg;
u_int8_t type;
u_int32_t len;
status_t status;
@@ -178,7 +177,7 @@ static status_t process_handshake(private_tls_fragmentation_t *this,
if (this->input.len == this->inpos)
{ /* message completely defragmented, process */
- msg = tls_reader_create(this->input);
+ msg = bio_reader_create(this->input);
DBG2(DBG_TLS, "received TLS %N handshake (%u bytes)",
tls_handshake_type_names, this->type, this->input.len);
status = this->handshake->process(this->handshake, this->type, msg);
@@ -201,11 +200,12 @@ static status_t process_handshake(private_tls_fragmentation_t *this,
* Process TLS application data
*/
static status_t process_application(private_tls_fragmentation_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
while (reader->remaining(reader))
{
status_t status;
+ chunk_t data;
if (reader->remaining(reader) > MAX_TLS_FRAGMENT_LEN)
{
@@ -213,6 +213,8 @@ static status_t process_application(private_tls_fragmentation_t *this,
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
return NEED_MORE;
}
+ data = reader->peek(reader);
+ DBG3(DBG_TLS, "%B", &data);
status = this->application->process(this->application, reader);
switch (status)
{
@@ -233,24 +235,25 @@ static status_t process_application(private_tls_fragmentation_t *this,
METHOD(tls_fragmentation_t, process, status_t,
private_tls_fragmentation_t *this, tls_content_type_t type, chunk_t data)
{
- tls_reader_t *reader;
+ bio_reader_t *reader;
status_t status;
switch (this->state)
{
case ALERT_SENDING:
case ALERT_SENT:
- /* don't accept more input, fatal error ocurred */
+ /* don't accept more input, fatal error occurred */
return NEED_MORE;
case ALERT_NONE:
break;
}
- reader = tls_reader_create(data);
+ reader = bio_reader_create(data);
switch (type)
{
case TLS_CHANGE_CIPHER_SPEC:
- if (this->handshake->change_cipherspec(this->handshake))
+ if (this->handshake->cipherspec_changed(this->handshake, TRUE))
{
+ this->handshake->change_cipherspec(this->handshake, TRUE);
status = NEED_MORE;
break;
}
@@ -281,11 +284,11 @@ static bool check_alerts(private_tls_fragmentation_t *this, chunk_t *data)
{
tls_alert_level_t level;
tls_alert_desc_t desc;
- tls_writer_t *writer;
+ bio_writer_t *writer;
if (this->alert->get(this->alert, &level, &desc))
{
- writer = tls_writer_create(2);
+ writer = bio_writer_create(2);
writer->write_uint8(writer, level);
writer->write_uint8(writer, desc);
@@ -302,14 +305,14 @@ static bool check_alerts(private_tls_fragmentation_t *this, chunk_t *data)
*/
static status_t build_handshake(private_tls_fragmentation_t *this)
{
- tls_writer_t *hs, *msg;
+ bio_writer_t *hs, *msg;
tls_handshake_type_t type;
status_t status;
- msg = tls_writer_create(64);
+ msg = bio_writer_create(64);
while (TRUE)
{
- hs = tls_writer_create(64);
+ hs = bio_writer_create(64);
status = this->handshake->build(this->handshake, &type, hs);
switch (status)
{
@@ -322,8 +325,12 @@ static status_t build_handshake(private_tls_fragmentation_t *this)
msg->write_data24(msg, hs->get_buf(hs));
DBG2(DBG_TLS, "sending TLS %N handshake (%u bytes)",
tls_handshake_type_names, type, hs->get_buf(hs).len);
- hs->destroy(hs);
- continue;
+ if (!this->handshake->cipherspec_changed(this->handshake, FALSE))
+ {
+ hs->destroy(hs);
+ continue;
+ }
+ /* FALL */
case INVALID_STATE:
this->output_type = TLS_HANDSHAKE;
this->output = chunk_clone(msg->get_buf(msg));
@@ -343,10 +350,10 @@ static status_t build_handshake(private_tls_fragmentation_t *this)
*/
static status_t build_application(private_tls_fragmentation_t *this)
{
- tls_writer_t *msg;
+ bio_writer_t *msg;
status_t status;
- msg = tls_writer_create(64);
+ msg = bio_writer_create(64);
while (TRUE)
{
status = this->application->build(this->application, msg);
@@ -395,8 +402,9 @@ METHOD(tls_fragmentation_t, build, status_t,
}
if (!this->output.len)
{
- if (this->handshake->cipherspec_changed(this->handshake))
+ if (this->handshake->cipherspec_changed(this->handshake, FALSE))
{
+ this->handshake->change_cipherspec(this->handshake, FALSE);
*type = TLS_CHANGE_CIPHER_SPEC;
*data = chunk_clone(chunk_from_chars(0x01));
return NEED_MORE;
diff --git a/src/libtls/tls_fragmentation.h b/src/libtls/tls_fragmentation.h
index d80278916..f650e7be8 100644
--- a/src/libtls/tls_fragmentation.h
+++ b/src/libtls/tls_fragmentation.h
@@ -23,12 +23,12 @@
#include <library.h>
+typedef struct tls_fragmentation_t tls_fragmentation_t;
+
#include "tls.h"
#include "tls_alert.h"
#include "tls_handshake.h"
-typedef struct tls_fragmentation_t tls_fragmentation_t;
-
/**
* TLS record protocol fragmentation layer.
*/
diff --git a/src/libtls/tls_handshake.h b/src/libtls/tls_handshake.h
index 6703b341b..bea0024eb 100644
--- a/src/libtls/tls_handshake.h
+++ b/src/libtls/tls_handshake.h
@@ -24,8 +24,9 @@
typedef struct tls_handshake_t tls_handshake_t;
#include "tls.h"
-#include "tls_reader.h"
-#include "tls_writer.h"
+
+#include <bio/bio_reader.h>
+#include <bio/bio_writer.h>
/**
* TLS handshake state machine interface.
@@ -44,7 +45,7 @@ struct tls_handshake_t {
* - DESTROY_ME if a fatal TLS alert received
*/
status_t (*process)(tls_handshake_t *this,
- tls_handshake_type_t type, tls_reader_t *reader);
+ tls_handshake_type_t type, bio_reader_t *reader);
/**
* Build TLS handshake messages to send out.
@@ -58,21 +59,22 @@ struct tls_handshake_t {
* - INVALID_STATE if more input to process() required
*/
status_t (*build)(tls_handshake_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer);
+ tls_handshake_type_t *type, bio_writer_t *writer);
/**
- * Check if the cipher spec for outgoing messages has changed.
+ * Check if the cipher spec should be changed for outgoing messages.
*
- * @return TRUE if cipher spec changed
+ * @param inbound TRUE to check for inbound cipherspec change
+ * @return TRUE if cipher spec should be changed
*/
- bool (*cipherspec_changed)(tls_handshake_t *this);
+ bool (*cipherspec_changed)(tls_handshake_t *this, bool inbound);
/**
- * Change the cipher spec for incoming messages.
+ * Change the cipher for a direction.
*
- * @return TRUE if cipher spec changed
+ * @param inbound TRUE to change inbound cipherspec, FALSE for outbound
*/
- bool (*change_cipherspec)(tls_handshake_t *this);
+ void (*change_cipherspec)(tls_handshake_t *this, bool inbound);
/**
* Check if the finished message was decoded successfully.
diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c
index 621f1729d..6091702cf 100644
--- a/src/libtls/tls_peer.c
+++ b/src/libtls/tls_peer.c
@@ -36,7 +36,7 @@ typedef enum {
STATE_CIPHERSPEC_CHANGED_OUT,
STATE_FINISHED_SENT,
STATE_CIPHERSPEC_CHANGED_IN,
- STATE_COMPLETE,
+ STATE_FINISHED_RECEIVED,
} peer_state_t;
/**
@@ -110,6 +110,16 @@ struct private_tls_peer_t {
diffie_hellman_t *dh;
/**
+ * Resuming a session?
+ */
+ bool resume;
+
+ /**
+ * TLS session identifier
+ */
+ chunk_t session;
+
+ /**
* List of server-supported hashsig algorithms
*/
chunk_t hashsig;
@@ -124,12 +134,12 @@ struct private_tls_peer_t {
* Process a server hello message
*/
static status_t process_server_hello(private_tls_peer_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
u_int8_t compression;
u_int16_t version, cipher;
chunk_t random, session, ext = chunk_empty;
- tls_cipher_suite_t suite;
+ tls_cipher_suite_t suite = 0;
this->crypto->append_handshake(this->crypto,
TLS_SERVER_HELLO, reader->peek(reader));
@@ -155,16 +165,34 @@ static status_t process_server_hello(private_tls_peer_t *this,
this->alert->add(this->alert, TLS_FATAL, TLS_PROTOCOL_VERSION);
return NEED_MORE;
}
- suite = cipher;
- if (!this->crypto->select_cipher_suite(this->crypto, &suite, 1, KEY_ANY))
+
+ if (chunk_equals(this->session, session))
{
- DBG1(DBG_TLS, "received TLS cipher suite %N inacceptable",
- tls_cipher_suite_names, suite);
- this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
- return NEED_MORE;
+ suite = this->crypto->resume_session(this->crypto, session, this->server,
+ chunk_from_thing(this->client_random),
+ chunk_from_thing(this->server_random));
+ if (suite)
+ {
+ DBG1(DBG_TLS, "resumed %N using suite %N",
+ tls_version_names, version, tls_cipher_suite_names, suite);
+ this->resume = TRUE;
+ }
+ }
+ if (!suite)
+ {
+ suite = cipher;
+ if (!this->crypto->select_cipher_suite(this->crypto, &suite, 1, KEY_ANY))
+ {
+ DBG1(DBG_TLS, "received TLS cipher suite %N inacceptable",
+ tls_cipher_suite_names, suite);
+ this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
+ return NEED_MORE;
+ }
+ DBG1(DBG_TLS, "negotiated %N using suite %N",
+ tls_version_names, version, tls_cipher_suite_names, suite);
+ free(this->session.ptr);
+ this->session = chunk_clone(session);
}
- DBG1(DBG_TLS, "negotiated TLS version %N with suite %N",
- tls_version_names, version, tls_cipher_suite_names, suite);
this->state = STATE_HELLO_RECEIVED;
return NEED_MORE;
}
@@ -209,10 +237,10 @@ static bool check_certificate(private_tls_peer_t *this, certificate_t *cert)
* Process a Certificate message
*/
static status_t process_certificate(private_tls_peer_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
certificate_t *cert;
- tls_reader_t *certs;
+ bio_reader_t *certs;
chunk_t data;
bool first = TRUE;
@@ -225,7 +253,7 @@ static status_t process_certificate(private_tls_peer_t *this,
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
return NEED_MORE;
}
- certs = tls_reader_create(data);
+ certs = bio_reader_create(data);
while (certs->remaining(certs))
{
if (!certs->read_data24(certs, &data))
@@ -302,7 +330,7 @@ static public_key_t *find_public_key(private_tls_peer_t *this)
* Process a Key Exchange message using MODP Diffie Hellman
*/
static status_t process_modp_key_exchange(private_tls_peer_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
chunk_t prime, generator, pub, chunk;
public_key_t *public;
@@ -379,7 +407,7 @@ static diffie_hellman_group_t curve_to_ec_group(private_tls_peer_t *this,
* Process a Key Exchange message using EC Diffie Hellman
*/
static status_t process_ec_key_exchange(private_tls_peer_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
diffie_hellman_group_t group;
public_key_t *public;
@@ -466,7 +494,7 @@ static status_t process_ec_key_exchange(private_tls_peer_t *this,
* Process a Server Key Exchange
*/
static status_t process_key_exchange(private_tls_peer_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
diffie_hellman_group_t group;
@@ -491,10 +519,10 @@ static status_t process_key_exchange(private_tls_peer_t *this,
/**
* Process a Certificate Request message
*/
-static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
+static status_t process_certreq(private_tls_peer_t *this, bio_reader_t *reader)
{
chunk_t types, hashsig, data;
- tls_reader_t *authorities;
+ bio_reader_t *authorities;
identification_t *id;
certificate_t *cert;
@@ -529,7 +557,7 @@ static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
return NEED_MORE;
}
- authorities = tls_reader_create(data);
+ authorities = bio_reader_create(data);
while (authorities->remaining(authorities))
{
if (!authorities->read_data16(authorities, &data))
@@ -565,7 +593,7 @@ static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
* Process Hello Done message
*/
static status_t process_hello_done(private_tls_peer_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
this->crypto->append_handshake(this->crypto,
TLS_SERVER_HELLO_DONE, reader->peek(reader));
@@ -576,7 +604,7 @@ static status_t process_hello_done(private_tls_peer_t *this,
/**
* Process finished message
*/
-static status_t process_finished(private_tls_peer_t *this, tls_reader_t *reader)
+static status_t process_finished(private_tls_peer_t *this, bio_reader_t *reader)
{
chunk_t received;
char buf[12];
@@ -599,15 +627,14 @@ static status_t process_finished(private_tls_peer_t *this, tls_reader_t *reader)
this->alert->add(this->alert, TLS_FATAL, TLS_DECRYPT_ERROR);
return NEED_MORE;
}
- this->state = STATE_COMPLETE;
- this->crypto->derive_eap_msk(this->crypto,
- chunk_from_thing(this->client_random),
- chunk_from_thing(this->server_random));
+ this->state = STATE_FINISHED_RECEIVED;
+ this->crypto->append_handshake(this->crypto, TLS_FINISHED, received);
+
return NEED_MORE;
}
METHOD(tls_handshake_t, process, status_t,
- private_tls_peer_t *this, tls_handshake_type_t type, tls_reader_t *reader)
+ private_tls_peer_t *this, tls_handshake_type_t type, bio_reader_t *reader)
{
tls_handshake_type_t expected;
@@ -670,10 +697,10 @@ METHOD(tls_handshake_t, process, status_t,
* Send a client hello
*/
static status_t send_client_hello(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
tls_cipher_suite_t *suites;
- tls_writer_t *extensions, *curves = NULL;
+ bio_writer_t *extensions, *curves = NULL;
tls_version_t version;
tls_named_curve_t curve;
enumerator_t *enumerator;
@@ -696,8 +723,9 @@ static status_t send_client_hello(private_tls_peer_t *this,
writer->write_uint16(writer, version);
writer->write_data(writer, chunk_from_thing(this->client_random));
- /* session identifier => none */
- writer->write_data8(writer, chunk_empty);
+ /* session identifier */
+ this->session = this->crypto->get_session(this->crypto, this->server);
+ writer->write_data8(writer, this->session);
/* add TLS cipher suites */
count = this->crypto->get_cipher_suites(this->crypto, &suites);
@@ -711,7 +739,7 @@ static status_t send_client_hello(private_tls_peer_t *this,
writer->write_uint8(writer, 1);
writer->write_uint8(writer, 0);
- extensions = tls_writer_create(32);
+ extensions = bio_writer_create(32);
extensions->write_uint16(extensions, TLS_EXT_SIGNATURE_ALGORITHMS);
this->crypto->get_signature_algorithms(this->crypto, extensions);
@@ -723,7 +751,7 @@ static status_t send_client_hello(private_tls_peer_t *this,
if (!curves)
{
extensions->write_uint16(extensions, TLS_EXT_ELLIPTIC_CURVES);
- curves = tls_writer_create(16);
+ curves = bio_writer_create(16);
}
curves->write_uint16(curves, curve);
}
@@ -741,11 +769,11 @@ static status_t send_client_hello(private_tls_peer_t *this,
}
if (this->server->get_type(this->server) == ID_FQDN)
{
- tls_writer_t *names;
+ bio_writer_t *names;
DBG2(DBG_TLS, "sending Server Name Indication for '%Y'", this->server);
- names = tls_writer_create(8);
+ names = bio_writer_create(8);
names->write_uint8(names, TLS_NAME_TYPE_HOST_NAME);
names->write_data16(names, this->server->get_encoding(this->server));
names->wrap16(names);
@@ -769,7 +797,7 @@ static status_t send_client_hello(private_tls_peer_t *this,
static private_key_t *find_private_key(private_tls_peer_t *this)
{
private_key_t *key = NULL;
- tls_reader_t *reader;
+ bio_reader_t *reader;
key_type_t type;
u_int8_t cert;
@@ -777,7 +805,7 @@ static private_key_t *find_private_key(private_tls_peer_t *this)
{
return NULL;
}
- reader = tls_reader_create(this->cert_types);
+ reader = bio_reader_create(this->cert_types);
while (reader->remaining(reader) && reader->read_uint8(reader, &cert))
{
switch (cert)
@@ -806,12 +834,12 @@ static private_key_t *find_private_key(private_tls_peer_t *this)
* Send Certificate
*/
static status_t send_certificate(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
enumerator_t *enumerator;
certificate_t *cert;
auth_rule_t rule;
- tls_writer_t *certs;
+ bio_writer_t *certs;
chunk_t data;
this->private = find_private_key(this);
@@ -823,7 +851,7 @@ static status_t send_certificate(private_tls_peer_t *this,
}
/* generate certificate payload */
- certs = tls_writer_create(256);
+ certs = bio_writer_create(256);
if (this->peer)
{
cert = this->peer_auth->get(this->peer_auth, AUTH_RULE_SUBJECT_CERT);
@@ -867,7 +895,7 @@ static status_t send_certificate(private_tls_peer_t *this,
* Send client key exchange, using premaster encryption
*/
static status_t send_key_exchange_encrypt(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
public_key_t *public;
rng_t *rng;
@@ -886,6 +914,7 @@ static status_t send_key_exchange_encrypt(private_tls_peer_t *this,
htoun16(premaster, TLS_1_2);
this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
+ this->session, this->server,
chunk_from_thing(this->client_random),
chunk_from_thing(this->server_random));
@@ -919,7 +948,7 @@ static status_t send_key_exchange_encrypt(private_tls_peer_t *this,
* Send client key exchange, using DHE exchange
*/
static status_t send_key_exchange_dhe(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
chunk_t premaster, pub;
@@ -930,6 +959,7 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this,
return NEED_MORE;
}
this->crypto->derive_secrets(this->crypto, premaster,
+ this->session, this->server,
chunk_from_thing(this->client_random),
chunk_from_thing(this->server_random));
chunk_clear(&premaster);
@@ -957,7 +987,7 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this,
* Send client key exchange, depending on suite
*/
static status_t send_key_exchange(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
if (this->dh)
{
@@ -970,7 +1000,7 @@ static status_t send_key_exchange(private_tls_peer_t *this,
* Send certificate verify
*/
static status_t send_certificate_verify(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
if (!this->private ||
!this->crypto->sign_handshake(this->crypto, this->private,
@@ -991,7 +1021,7 @@ static status_t send_certificate_verify(private_tls_peer_t *this,
* Send Finished
*/
static status_t send_finished(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
char buf[12];
@@ -1011,7 +1041,7 @@ static status_t send_finished(private_tls_peer_t *this,
}
METHOD(tls_handshake_t, build, status_t,
- private_tls_peer_t *this, tls_handshake_type_t *type, tls_writer_t *writer)
+ private_tls_peer_t *this, tls_handshake_type_t *type, bio_writer_t *writer)
{
switch (this->state)
{
@@ -1042,34 +1072,52 @@ METHOD(tls_handshake_t, build, status_t,
}
METHOD(tls_handshake_t, cipherspec_changed, bool,
- private_tls_peer_t *this)
+ private_tls_peer_t *this, bool inbound)
{
- if ((this->peer && this->state == STATE_VERIFY_SENT) ||
- (!this->peer && this->state == STATE_KEY_EXCHANGE_SENT))
+ if (inbound)
{
- this->crypto->change_cipher(this->crypto, FALSE);
- this->state = STATE_CIPHERSPEC_CHANGED_OUT;
- return TRUE;
+ if (this->resume)
+ {
+ return this->state == STATE_HELLO_RECEIVED;
+ }
+ return this->state == STATE_FINISHED_SENT;
+ }
+ else
+ {
+ if (this->resume)
+ {
+ return this->state == STATE_FINISHED_RECEIVED;
+ }
+ if (this->peer)
+ {
+ return this->state == STATE_VERIFY_SENT;
+ }
+ return this->state == STATE_KEY_EXCHANGE_SENT;
}
- return FALSE;
}
-METHOD(tls_handshake_t, change_cipherspec, bool,
- private_tls_peer_t *this)
+METHOD(tls_handshake_t, change_cipherspec, void,
+ private_tls_peer_t *this, bool inbound)
{
- if (this->state == STATE_FINISHED_SENT)
+ this->crypto->change_cipher(this->crypto, inbound);
+ if (inbound)
{
- this->crypto->change_cipher(this->crypto, TRUE);
this->state = STATE_CIPHERSPEC_CHANGED_IN;
- return TRUE;
}
- return FALSE;
+ else
+ {
+ this->state = STATE_CIPHERSPEC_CHANGED_OUT;
+ }
}
METHOD(tls_handshake_t, finished, bool,
private_tls_peer_t *this)
{
- return this->state == STATE_COMPLETE;
+ if (this->resume)
+ {
+ return this->state == STATE_FINISHED_SENT;
+ }
+ return this->state == STATE_FINISHED_RECEIVED;
}
METHOD(tls_handshake_t, destroy, void,
@@ -1081,6 +1129,7 @@ METHOD(tls_handshake_t, destroy, void,
this->server_auth->destroy(this->server_auth);
free(this->hashsig.ptr);
free(this->cert_types.ptr);
+ free(this->session.ptr);
free(this);
}
diff --git a/src/libtls/tls_protection.c b/src/libtls/tls_protection.c
index d823bae04..dc734545c 100644
--- a/src/libtls/tls_protection.c
+++ b/src/libtls/tls_protection.c
@@ -91,28 +91,33 @@ struct private_tls_protection_t {
};
/**
- * Create the header to append to the record data to create the MAC
+ * Create the header and feed it into a signer for MAC verification
*/
-static chunk_t sigheader(u_int32_t seq, u_int8_t type,
- u_int16_t version, u_int16_t length)
+static void sigheader(signer_t *signer, u_int32_t seq, u_int8_t type,
+ u_int16_t version, u_int16_t length)
{
/* we only support 32 bit sequence numbers, but TLS uses 64 bit */
- u_int32_t seq_high = 0;
-
- seq = htonl(seq);
- version = htons(version);
- length = htons(length);
-
- return chunk_cat("ccccc", chunk_from_thing(seq_high),
- chunk_from_thing(seq), chunk_from_thing(type),
- chunk_from_thing(version), chunk_from_thing(length));
+ struct __attribute__((__packed__)) {
+ u_int32_t seq_high;
+ u_int32_t seq_low;
+ u_int8_t type;
+ u_int16_t version;
+ u_int16_t length;
+ } header = {
+ .type = type,
+ };
+ htoun32(&header.seq_low, seq);
+ htoun16(&header.version, version);
+ htoun16(&header.length, length);
+
+ signer->get_signature(signer, chunk_from_thing(header), NULL);
}
METHOD(tls_protection_t, process, status_t,
private_tls_protection_t *this, tls_content_type_t type, chunk_t data)
{
if (this->alert->fatal(this->alert))
- { /* don't accept more input, fatal error ocurred */
+ { /* don't accept more input, fatal error occurred */
return NEED_MORE;
}
@@ -154,17 +159,15 @@ METHOD(tls_protection_t, process, status_t,
}
padding_length = data.ptr[data.len - 1];
- if (padding_length >= data.len)
- {
- DBG1(DBG_TLS, "invalid TLS record padding");
- this->alert->add(this->alert, TLS_FATAL, TLS_BAD_RECORD_MAC);
- return NEED_MORE;
+ if (padding_length < data.len)
+ { /* remove padding if it looks valid. Continue with no padding, try
+ * to prevent timing attacks. */
+ data.len -= padding_length + 1;
}
- data.len -= padding_length + 1;
}
if (this->signer_in)
{
- chunk_t mac, macdata, header;
+ chunk_t mac;
u_int8_t bs;
bs = this->signer_in->get_block_size(this->signer_in);
@@ -177,16 +180,13 @@ METHOD(tls_protection_t, process, status_t,
mac = chunk_skip(data, data.len - bs);
data.len -= bs;
- header = sigheader(this->seq_in, type, this->version, data.len);
- macdata = chunk_cat("mc", header, data);
- if (!this->signer_in->verify_signature(this->signer_in, macdata, mac))
+ sigheader(this->signer_in, this->seq_in, type, this->version, data.len);
+ if (!this->signer_in->verify_signature(this->signer_in, data, mac))
{
DBG1(DBG_TLS, "TLS record MAC verification failed");
- free(macdata.ptr);
this->alert->add(this->alert, TLS_FATAL, TLS_BAD_RECORD_MAC);
return NEED_MORE;
}
- free(macdata.ptr);
}
if (type == TLS_CHANGE_CIPHER_SPEC)
@@ -216,11 +216,10 @@ METHOD(tls_protection_t, build, status_t,
{
if (this->signer_out)
{
- chunk_t mac, header;
+ chunk_t mac;
- header = sigheader(this->seq_out, *type, this->version, data->len);
- this->signer_out->get_signature(this->signer_out, header, NULL);
- free(header.ptr);
+ sigheader(this->signer_out, this->seq_out, *type,
+ this->version, data->len);
this->signer_out->allocate_signature(this->signer_out, *data, &mac);
if (this->crypter_out)
{
diff --git a/src/libtls/tls_protection.h b/src/libtls/tls_protection.h
index 99c94e935..05cf3df45 100644
--- a/src/libtls/tls_protection.h
+++ b/src/libtls/tls_protection.h
@@ -23,12 +23,12 @@
#include <library.h>
+typedef struct tls_protection_t tls_protection_t;
+
#include "tls.h"
#include "tls_alert.h"
#include "tls_compression.h"
-typedef struct tls_protection_t tls_protection_t;
-
/**
* TLS record protocol protection layer.
*/
diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c
index b0417f6cb..e3617dc9a 100644
--- a/src/libtls/tls_server.c
+++ b/src/libtls/tls_server.c
@@ -22,6 +22,10 @@
typedef struct private_tls_server_t private_tls_server_t;
+/**
+ * Size of a session ID
+ */
+#define SESSION_ID_SIZE 16
typedef enum {
STATE_INIT,
@@ -121,6 +125,16 @@ struct private_tls_server_t {
tls_version_t client_version;
/**
+ * TLS session identifier
+ */
+ chunk_t session;
+
+ /**
+ * Do we resume a session?
+ */
+ bool resume;
+
+ /**
* Hash and signature algorithms supported by peer
*/
chunk_t hashsig;
@@ -192,13 +206,14 @@ static bool select_suite_and_key(private_tls_server_t *this,
* Process client hello message
*/
static status_t process_client_hello(private_tls_server_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
u_int16_t version, extension;
chunk_t random, session, ciphers, compression, ext = chunk_empty;
- tls_reader_t *extensions;
+ bio_reader_t *extensions;
tls_cipher_suite_t *suites;
int count, i;
+ rng_t *rng;
this->crypto->append_handshake(this->crypto,
TLS_CLIENT_HELLO, reader->peek(reader));
@@ -217,7 +232,7 @@ static status_t process_client_hello(private_tls_server_t *this,
if (ext.len)
{
- extensions = tls_reader_create(ext);
+ extensions = bio_reader_create(ext);
while (extensions->remaining(extensions))
{
if (!extensions->read_uint16(extensions, &extension) ||
@@ -228,7 +243,7 @@ static status_t process_client_hello(private_tls_server_t *this,
extensions->destroy(extensions);
return NEED_MORE;
}
- DBG1(DBG_TLS, "received TLS '%N' extension",
+ DBG2(DBG_TLS, "received TLS '%N' extension",
tls_extension_names, extension);
DBG3(DBG_TLS, "%B", &ext);
switch (extension)
@@ -249,6 +264,17 @@ static status_t process_client_hello(private_tls_server_t *this,
memcpy(this->client_random, random.ptr, sizeof(this->client_random));
+ htoun32(&this->server_random, time(NULL));
+ rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+ if (!rng)
+ {
+ DBG1(DBG_TLS, "no suitable RNG found to generate server random");
+ this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+ return NEED_MORE;
+ }
+ rng->get_bytes(rng, sizeof(this->server_random) - 4, this->server_random + 4);
+ rng->destroy(rng);
+
if (!this->tls->set_version(this->tls, version))
{
DBG1(DBG_TLS, "negotiated version %N not supported",
@@ -256,24 +282,44 @@ static status_t process_client_hello(private_tls_server_t *this,
this->alert->add(this->alert, TLS_FATAL, TLS_PROTOCOL_VERSION);
return NEED_MORE;
}
- count = ciphers.len / sizeof(u_int16_t);
- suites = alloca(count * sizeof(tls_cipher_suite_t));
- DBG2(DBG_TLS, "received %d TLS cipher suites:", count);
- for (i = 0; i < count; i++)
+
+ this->client_version = version;
+ this->suite = this->crypto->resume_session(this->crypto, session, this->peer,
+ chunk_from_thing(this->client_random),
+ chunk_from_thing(this->server_random));
+ if (this->suite)
{
- suites[i] = untoh16(&ciphers.ptr[i * sizeof(u_int16_t)]);
- DBG2(DBG_TLS, " %N", tls_cipher_suite_names, suites[i]);
+ this->session = chunk_clone(session);
+ this->resume = TRUE;
+ DBG1(DBG_TLS, "resumed %N using suite %N",
+ tls_version_names, this->tls->get_version(this->tls),
+ tls_cipher_suite_names, this->suite);
}
-
- if (!select_suite_and_key(this, suites, count))
+ else
{
- this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
- return NEED_MORE;
+ count = ciphers.len / sizeof(u_int16_t);
+ suites = alloca(count * sizeof(tls_cipher_suite_t));
+ DBG2(DBG_TLS, "received %d TLS cipher suites:", count);
+ for (i = 0; i < count; i++)
+ {
+ suites[i] = untoh16(&ciphers.ptr[i * sizeof(u_int16_t)]);
+ DBG2(DBG_TLS, " %N", tls_cipher_suite_names, suites[i]);
+ }
+ if (!select_suite_and_key(this, suites, count))
+ {
+ this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
+ return NEED_MORE;
+ }
+ rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
+ if (rng)
+ {
+ rng->allocate_bytes(rng, SESSION_ID_SIZE, &this->session);
+ rng->destroy(rng);
+ }
+ DBG1(DBG_TLS, "negotiated %N using suite %N",
+ tls_version_names, this->tls->get_version(this->tls),
+ tls_cipher_suite_names, this->suite);
}
- DBG1(DBG_TLS, "negotiated TLS version %N with suite %N",
- tls_version_names, this->tls->get_version(this->tls),
- tls_cipher_suite_names, this->suite);
- this->client_version = version;
this->state = STATE_HELLO_RECEIVED;
return NEED_MORE;
}
@@ -282,10 +328,10 @@ static status_t process_client_hello(private_tls_server_t *this,
* Process certificate
*/
static status_t process_certificate(private_tls_server_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
certificate_t *cert;
- tls_reader_t *certs;
+ bio_reader_t *certs;
chunk_t data;
bool first = TRUE;
@@ -298,7 +344,7 @@ static status_t process_certificate(private_tls_server_t *this,
this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR);
return NEED_MORE;
}
- certs = tls_reader_create(data);
+ certs = bio_reader_create(data);
while (certs->remaining(certs))
{
if (!certs->read_data24(certs, &data))
@@ -342,7 +388,7 @@ static status_t process_certificate(private_tls_server_t *this,
* Process Client Key Exchange, using premaster encryption
*/
static status_t process_key_exchange_encrypted(private_tls_server_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
chunk_t encrypted, decrypted;
char premaster[48];
@@ -391,6 +437,7 @@ static status_t process_key_exchange_encrypted(private_tls_server_t *this,
}
this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
+ this->session, this->peer,
chunk_from_thing(this->client_random),
chunk_from_thing(this->server_random));
@@ -402,7 +449,7 @@ static status_t process_key_exchange_encrypted(private_tls_server_t *this,
* Process client key exchange, using DHE exchange
*/
static status_t process_key_exchange_dhe(private_tls_server_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
chunk_t premaster, pub;
bool ec;
@@ -439,6 +486,7 @@ static status_t process_key_exchange_dhe(private_tls_server_t *this,
}
this->crypto->derive_secrets(this->crypto, premaster,
+ this->session, this->peer,
chunk_from_thing(this->client_random),
chunk_from_thing(this->server_random));
chunk_clear(&premaster);
@@ -451,7 +499,7 @@ static status_t process_key_exchange_dhe(private_tls_server_t *this,
* Process Client Key Exchange
*/
static status_t process_key_exchange(private_tls_server_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
if (this->dh)
{
@@ -464,19 +512,19 @@ static status_t process_key_exchange(private_tls_server_t *this,
* Process Certificate verify
*/
static status_t process_cert_verify(private_tls_server_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
bool verified = FALSE;
enumerator_t *enumerator;
public_key_t *public;
auth_cfg_t *auth;
- tls_reader_t *sig;
+ bio_reader_t *sig;
enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
KEY_ANY, this->peer, this->peer_auth);
while (enumerator->enumerate(enumerator, &public, &auth))
{
- sig = tls_reader_create(reader->peek(reader));
+ sig = bio_reader_create(reader->peek(reader));
verified = this->crypto->verify_handshake(this->crypto, public, sig);
sig->destroy(sig);
if (verified)
@@ -505,7 +553,7 @@ static status_t process_cert_verify(private_tls_server_t *this,
* Process finished message
*/
static status_t process_finished(private_tls_server_t *this,
- tls_reader_t *reader)
+ bio_reader_t *reader)
{
chunk_t received;
char buf[12];
@@ -535,7 +583,7 @@ static status_t process_finished(private_tls_server_t *this,
}
METHOD(tls_handshake_t, process, status_t,
- private_tls_server_t *this, tls_handshake_type_t type, tls_reader_t *reader)
+ private_tls_server_t *this, tls_handshake_type_t type, bio_reader_t *reader)
{
tls_handshake_type_t expected;
@@ -576,10 +624,7 @@ METHOD(tls_handshake_t, process, status_t,
expected = TLS_CERTIFICATE_VERIFY;
break;
}
- else
- {
- return INVALID_STATE;
- }
+ return INVALID_STATE;
case STATE_CIPHERSPEC_CHANGED_IN:
if (type == TLS_FINISHED)
{
@@ -603,29 +648,14 @@ METHOD(tls_handshake_t, process, status_t,
* Send ServerHello message
*/
static status_t send_server_hello(private_tls_server_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
- tls_version_t version;
- rng_t *rng;
-
- htoun32(&this->server_random, time(NULL));
- rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- if (!rng)
- {
- DBG1(DBG_TLS, "no suitable RNG found to generate server random");
- this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
- return FAILED;
- }
- rng->get_bytes(rng, sizeof(this->server_random) - 4, this->server_random + 4);
- rng->destroy(rng);
-
/* TLS version */
- version = this->tls->get_version(this->tls);
- writer->write_uint16(writer, version);
+ writer->write_uint16(writer, this->tls->get_version(this->tls));
writer->write_data(writer, chunk_from_thing(this->server_random));
- /* session identifier => none, we don't support session resumption */
- writer->write_data8(writer, chunk_empty);
+ /* session identifier if we have one */
+ writer->write_data8(writer, this->session);
/* add selected TLS cipher suite */
writer->write_uint16(writer, this->suite);
@@ -643,16 +673,16 @@ static status_t send_server_hello(private_tls_server_t *this,
* Send Certificate
*/
static status_t send_certificate(private_tls_server_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
enumerator_t *enumerator;
certificate_t *cert;
auth_rule_t rule;
- tls_writer_t *certs;
+ bio_writer_t *certs;
chunk_t data;
/* generate certificate payload */
- certs = tls_writer_create(256);
+ certs = bio_writer_create(256);
cert = this->server_auth->get(this->server_auth, AUTH_RULE_SUBJECT_CERT);
if (cert)
{
@@ -693,15 +723,15 @@ static status_t send_certificate(private_tls_server_t *this,
* Send Certificate Request
*/
static status_t send_certificate_request(private_tls_server_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
- tls_writer_t *authorities, *supported;
+ bio_writer_t *authorities, *supported;
enumerator_t *enumerator;
certificate_t *cert;
x509_t *x509;
identification_t *id;
- supported = tls_writer_create(4);
+ supported = bio_writer_create(4);
/* we propose both RSA and ECDSA */
supported->write_uint8(supported, TLS_RSA_SIGN);
supported->write_uint8(supported, TLS_ECDSA_SIGN);
@@ -712,7 +742,7 @@ static status_t send_certificate_request(private_tls_server_t *this,
this->crypto->get_signature_algorithms(this->crypto, writer);
}
- authorities = tls_writer_create(64);
+ authorities = bio_writer_create(64);
enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
CERT_X509, KEY_RSA, NULL, TRUE);
while (enumerator->enumerate(enumerator, &cert))
@@ -763,14 +793,14 @@ static tls_named_curve_t ec_group_to_curve(private_tls_server_t *this,
*/
bool peer_supports_curve(private_tls_server_t *this, tls_named_curve_t curve)
{
- tls_reader_t *reader;
+ bio_reader_t *reader;
u_int16_t current;
if (!this->curves_received)
{ /* none received, assume yes */
return TRUE;
}
- reader = tls_reader_create(this->curves);
+ reader = bio_reader_create(this->curves);
while (reader->remaining(reader) && reader->read_uint16(reader, &current))
{
if (current == curve)
@@ -810,7 +840,7 @@ static bool find_supported_curve(private_tls_server_t *this,
* Send Server key Exchange
*/
static status_t send_server_key_exchange(private_tls_server_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer,
+ tls_handshake_type_t *type, bio_writer_t *writer,
diffie_hellman_group_t group)
{
diffie_hellman_params_t *params = NULL;
@@ -887,7 +917,7 @@ static status_t send_server_key_exchange(private_tls_server_t *this,
* Send Hello Done
*/
static status_t send_hello_done(private_tls_server_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
*type = TLS_SERVER_HELLO_DONE;
this->state = STATE_HELLO_DONE;
@@ -899,7 +929,7 @@ static status_t send_hello_done(private_tls_server_t *this,
* Send Finished
*/
static status_t send_finished(private_tls_server_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
+ tls_handshake_type_t *type, bio_writer_t *writer)
{
char buf[12];
@@ -914,14 +944,13 @@ static status_t send_finished(private_tls_server_t *this,
*type = TLS_FINISHED;
this->state = STATE_FINISHED_SENT;
- this->crypto->derive_eap_msk(this->crypto,
- chunk_from_thing(this->client_random),
- chunk_from_thing(this->server_random));
+ this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
+
return NEED_MORE;
}
METHOD(tls_handshake_t, build, status_t,
- private_tls_server_t *this, tls_handshake_type_t *type, tls_writer_t *writer)
+ private_tls_server_t *this, tls_handshake_type_t *type, bio_writer_t *writer)
{
diffie_hellman_group_t group;
@@ -956,33 +985,52 @@ METHOD(tls_handshake_t, build, status_t,
}
METHOD(tls_handshake_t, cipherspec_changed, bool,
- private_tls_server_t *this)
+ private_tls_server_t *this, bool inbound)
{
- if (this->state == STATE_FINISHED_RECEIVED)
+ if (inbound)
{
- this->crypto->change_cipher(this->crypto, FALSE);
- this->state = STATE_CIPHERSPEC_CHANGED_OUT;
- return TRUE;
+ if (this->resume)
+ {
+ return this->state == STATE_FINISHED_SENT;
+ }
+ if (this->peer)
+ {
+ return this->state == STATE_CERT_VERIFY_RECEIVED;
+ }
+ return this->state == STATE_KEY_EXCHANGE_RECEIVED;
+ }
+ else
+ {
+ if (this->resume)
+ {
+ return this->state == STATE_HELLO_SENT;
+ }
+ return this->state == STATE_FINISHED_RECEIVED;
}
return FALSE;
}
-METHOD(tls_handshake_t, change_cipherspec, bool,
- private_tls_server_t *this)
+METHOD(tls_handshake_t, change_cipherspec, void,
+ private_tls_server_t *this, bool inbound)
{
- if ((this->peer && this->state == STATE_CERT_VERIFY_RECEIVED) ||
- (!this->peer && this->state == STATE_KEY_EXCHANGE_RECEIVED))
+ this->crypto->change_cipher(this->crypto, inbound);
+ if (inbound)
{
- this->crypto->change_cipher(this->crypto, TRUE);
this->state = STATE_CIPHERSPEC_CHANGED_IN;
- return TRUE;
}
- return FALSE;
+ else
+ {
+ this->state = STATE_CIPHERSPEC_CHANGED_OUT;
+ }
}
METHOD(tls_handshake_t, finished, bool,
private_tls_server_t *this)
{
+ if (this->resume)
+ {
+ return this->state == STATE_FINISHED_RECEIVED;
+ }
return this->state == STATE_FINISHED_SENT;
}
@@ -995,6 +1043,7 @@ METHOD(tls_handshake_t, destroy, void,
this->server_auth->destroy(this->server_auth);
free(this->hashsig.ptr);
free(this->curves.ptr);
+ free(this->session.ptr);
free(this);
}
diff --git a/src/libtls/tls_socket.c b/src/libtls/tls_socket.c
index e0c440a4c..3abff596d 100644
--- a/src/libtls/tls_socket.c
+++ b/src/libtls/tls_socket.c
@@ -16,8 +16,20 @@
#include "tls_socket.h"
#include <unistd.h>
+#include <errno.h>
#include <debug.h>
+#include <threading/thread.h>
+
+/**
+ * Buffer size for plain side I/O
+ */
+#define PLAIN_BUF_SIZE 4096
+
+/**
+ * Buffer size for encrypted side I/O
+ */
+#define CRYPTO_BUF_SIZE 4096
typedef struct private_tls_socket_t private_tls_socket_t;
typedef struct private_tls_application_t private_tls_application_t;
@@ -67,7 +79,7 @@ struct private_tls_socket_t {
};
METHOD(tls_application_t, process, status_t,
- private_tls_application_t *this, tls_reader_t *reader)
+ private_tls_application_t *this, bio_reader_t *reader)
{
chunk_t data;
@@ -80,7 +92,7 @@ METHOD(tls_application_t, process, status_t,
}
METHOD(tls_application_t, build, status_t,
- private_tls_application_t *this, tls_writer_t *writer)
+ private_tls_application_t *this, bio_writer_t *writer)
{
if (this->out.len)
{
@@ -96,8 +108,8 @@ METHOD(tls_application_t, build, status_t,
*/
static bool exchange(private_tls_socket_t *this, bool wr)
{
- char buf[1024];
- ssize_t len;
+ char buf[CRYPTO_BUF_SIZE], *pos;
+ ssize_t len, out;
int round = 0;
for (round = 0; TRUE; round++)
@@ -109,10 +121,18 @@ static bool exchange(private_tls_socket_t *this, bool wr)
{
case NEED_MORE:
case ALREADY_DONE:
- len = write(this->fd, buf, len);
- if (len == -1)
+ pos = buf;
+ while (len)
{
- return FALSE;
+ out = write(this->fd, pos, len);
+ if (out == -1)
+ {
+ DBG1(DBG_TLS, "TLS crypto write error: %s",
+ strerror(errno));
+ return FALSE;
+ }
+ len -= out;
+ pos += out;
}
continue;
case INVALID_STATE:
@@ -175,6 +195,81 @@ METHOD(tls_socket_t, write_, bool,
return FALSE;
}
+METHOD(tls_socket_t, splice, bool,
+ private_tls_socket_t *this, int rfd, int wfd)
+{
+ char buf[PLAIN_BUF_SIZE], *pos;
+ fd_set set;
+ chunk_t data;
+ ssize_t len;
+ bool old;
+
+ while (TRUE)
+ {
+ FD_ZERO(&set);
+ FD_SET(rfd, &set);
+ FD_SET(this->fd, &set);
+
+ old = thread_cancelability(TRUE);
+ len = select(max(rfd, this->fd) + 1, &set, NULL, NULL, NULL);
+ thread_cancelability(old);
+ if (len == -1)
+ {
+ DBG1(DBG_TLS, "TLS select error: %s", strerror(errno));
+ return FALSE;
+ }
+ if (FD_ISSET(this->fd, &set))
+ {
+ if (!read_(this, &data))
+ {
+ DBG2(DBG_TLS, "TLS read error/disconnect");
+ return TRUE;
+ }
+ pos = data.ptr;
+ while (data.len)
+ {
+ len = write(wfd, pos, data.len);
+ if (len == -1)
+ {
+ free(data.ptr);
+ DBG1(DBG_TLS, "TLS plain write error: %s", strerror(errno));
+ return FALSE;
+ }
+ data.len -= len;
+ pos += len;
+ }
+ free(data.ptr);
+ }
+ if (FD_ISSET(rfd, &set))
+ {
+ len = read(rfd, buf, sizeof(buf));
+ if (len > 0)
+ {
+ if (!write_(this, chunk_create(buf, len)))
+ {
+ DBG1(DBG_TLS, "TLS write error");
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (len < 0)
+ {
+ DBG1(DBG_TLS, "TLS plain read error: %s", strerror(errno));
+ return FALSE;
+ }
+ return TRUE;
+ }
+ }
+ }
+}
+
+METHOD(tls_socket_t, get_fd, int,
+ private_tls_socket_t *this)
+{
+ return this->fd;
+}
+
METHOD(tls_socket_t, destroy, void,
private_tls_socket_t *this)
{
@@ -187,7 +282,7 @@ METHOD(tls_socket_t, destroy, void,
* See header
*/
tls_socket_t *tls_socket_create(bool is_server, identification_t *server,
- identification_t *peer, int fd)
+ identification_t *peer, int fd, tls_cache_t *cache)
{
private_tls_socket_t *this;
@@ -195,6 +290,8 @@ tls_socket_t *tls_socket_create(bool is_server, identification_t *server,
.public = {
.read = _read_,
.write = _write_,
+ .splice = _splice,
+ .get_fd = _get_fd,
.destroy = _destroy,
},
.app = {
@@ -208,7 +305,7 @@ tls_socket_t *tls_socket_create(bool is_server, identification_t *server,
);
this->tls = tls_create(is_server, server, peer, TLS_PURPOSE_GENERIC,
- &this->app.application);
+ &this->app.application, cache);
if (!this->tls)
{
free(this);
diff --git a/src/libtls/tls_socket.h b/src/libtls/tls_socket.h
index ac714a385..edd05fd29 100644
--- a/src/libtls/tls_socket.h
+++ b/src/libtls/tls_socket.h
@@ -55,6 +55,25 @@ struct tls_socket_t {
bool (*write)(tls_socket_t *this, chunk_t data);
/**
+ * Read/write plain data from file descriptor.
+ *
+ * This call is blocking, but a thread cancellation point. Data is
+ * exchanged until one of the sockets gets closed or an error occurs.
+ *
+ * @param rfd file descriptor to read plain data from
+ * @param wfd file descriptor to write plain data to
+ * @return TRUE if data exchanged successfully
+ */
+ bool (*splice)(tls_socket_t *this, int rfd, int wfd);
+
+ /**
+ * Get the underlying file descriptor passed to the constructor.
+ *
+ * @return file descriptor
+ */
+ int (*get_fd)(tls_socket_t *this);
+
+ /**
* Destroy a tls_socket_t.
*/
void (*destroy)(tls_socket_t *this);
@@ -67,9 +86,10 @@ struct tls_socket_t {
* @param server server identity
* @param peer client identity, NULL for no client authentication
* @param fd socket to read/write from
+ * @param cache session cache to use, or NULL
* @return TLS socket wrapper
*/
tls_socket_t *tls_socket_create(bool is_server, identification_t *server,
- identification_t *peer, int fd);
+ identification_t *peer, int fd, tls_cache_t *cache);
#endif /** TLS_SOCKET_H_ @}*/
diff --git a/src/libtnccs/Android.mk b/src/libtnccs/Android.mk
new file mode 100644
index 000000000..a4bbc13f5
--- /dev/null
+++ b/src/libtnccs/Android.mk
@@ -0,0 +1,33 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# copy-n-paste from Makefile.am
+LOCAL_SRC_FILES := \
+tnc/tnc.h tnc/tnc.c \
+tnc/imc/imc.h tnc/imc/imc_manager.h \
+tnc/imv/imv.h tnc/imv/imv_manager.h \
+tnc/imv/imv_recommendations.h tnc/imv/imv_recommendations.c \
+tnc/tnccs/tnccs.h tnc/tnccs/tnccs.c \
+tnc/tnccs/tnccs_manager.h tnc/tnccs/tnccs_manager.c
+
+# build libtncif ---------------------------------------------------------------
+
+LOCAL_C_INCLUDES += \
+ $(libvstr_PATH) \
+ $(strongswan_PATH)/src/libtncif \
+ $(strongswan_PATH)/src/libstrongswan
+
+LOCAL_CFLAGS := $(strongswan_CFLAGS)
+
+LOCAL_MODULE := libtnccs
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_SHARED_LIBRARIES += libstrongswan
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/src/libtnccs/Makefile.am b/src/libtnccs/Makefile.am
new file mode 100644
index 000000000..449d32d92
--- /dev/null
+++ b/src/libtnccs/Makefile.am
@@ -0,0 +1,16 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libtncif
+
+ipseclib_LTLIBRARIES = libtnccs.la
+
+libtnccs_la_LIBADD = $(top_builddir)/src/libtncif/libtncif.la
+
+libtnccs_la_SOURCES = \
+tnc/tnc.h tnc/tnc.c \
+tnc/imc/imc.h tnc/imc/imc_manager.h \
+tnc/imv/imv.h tnc/imv/imv_manager.h \
+tnc/imv/imv_recommendations.h tnc/imv/imv_recommendations.c \
+tnc/tnccs/tnccs.h tnc/tnccs/tnccs.c \
+tnc/tnccs/tnccs_manager.h tnc/tnccs/tnccs_manager.c
+
+EXTRA_DIST = Android.mk
diff --git a/src/libtnccs/Makefile.in b/src/libtnccs/Makefile.in
new file mode 100644
index 000000000..61a51fb4c
--- /dev/null
+++ b/src/libtnccs/Makefile.in
@@ -0,0 +1,629 @@
+# 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/libtnccs
+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)$(ipseclibdir)"
+LTLIBRARIES = $(ipseclib_LTLIBRARIES)
+libtnccs_la_DEPENDENCIES = $(top_builddir)/src/libtncif/libtncif.la
+am_libtnccs_la_OBJECTS = tnc.lo imv_recommendations.lo tnccs.lo \
+ tnccs_manager.lo
+libtnccs_la_OBJECTS = $(am_libtnccs_la_OBJECTS)
+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 = $(libtnccs_la_SOURCES)
+DIST_SOURCES = $(libtnccs_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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/libtncif
+ipseclib_LTLIBRARIES = libtnccs.la
+libtnccs_la_LIBADD = $(top_builddir)/src/libtncif/libtncif.la
+libtnccs_la_SOURCES = \
+tnc/tnc.h tnc/tnc.c \
+tnc/imc/imc.h tnc/imc/imc_manager.h \
+tnc/imv/imv.h tnc/imv/imv_manager.h \
+tnc/imv/imv_recommendations.h tnc/imv/imv_recommendations.c \
+tnc/tnccs/tnccs.h tnc/tnccs/tnccs.c \
+tnc/tnccs/tnccs_manager.h tnc/tnccs/tnccs_manager.c
+
+EXTRA_DIST = Android.mk
+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/libtnccs/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libtnccs/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):
+install-ipseclibLTLIBRARIES: $(ipseclib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipseclibdir)" || $(MKDIR_P) "$(DESTDIR)$(ipseclibdir)"
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || 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)$(ipseclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ipseclibdir)"; \
+ }
+
+uninstall-ipseclibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipseclib_LTLIBRARIES)'; test -n "$(ipseclibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ipseclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ipseclibdir)/$$f"; \
+ done
+
+clean-ipseclibLTLIBRARIES:
+ -test -z "$(ipseclib_LTLIBRARIES)" || rm -f $(ipseclib_LTLIBRARIES)
+ @list='$(ipseclib_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
+libtnccs.la: $(libtnccs_la_OBJECTS) $(libtnccs_la_DEPENDENCIES)
+ $(LINK) -rpath $(ipseclibdir) $(libtnccs_la_OBJECTS) $(libtnccs_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imv_recommendations.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnc.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@
+
+.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 $@ $<
+
+tnc.lo: tnc/tnc.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnc.lo -MD -MP -MF $(DEPDIR)/tnc.Tpo -c -o tnc.lo `test -f 'tnc/tnc.c' || echo '$(srcdir)/'`tnc/tnc.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnc.Tpo $(DEPDIR)/tnc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/tnc.c' object='tnc.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 tnc.lo `test -f 'tnc/tnc.c' || echo '$(srcdir)/'`tnc/tnc.c
+
+imv_recommendations.lo: tnc/imv/imv_recommendations.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imv_recommendations.lo -MD -MP -MF $(DEPDIR)/imv_recommendations.Tpo -c -o imv_recommendations.lo `test -f 'tnc/imv/imv_recommendations.c' || echo '$(srcdir)/'`tnc/imv/imv_recommendations.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/imv_recommendations.Tpo $(DEPDIR)/imv_recommendations.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/imv/imv_recommendations.c' object='imv_recommendations.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 imv_recommendations.lo `test -f 'tnc/imv/imv_recommendations.c' || echo '$(srcdir)/'`tnc/imv/imv_recommendations.c
+
+tnccs.lo: tnc/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 'tnc/tnccs/tnccs.c' || echo '$(srcdir)/'`tnc/tnccs/tnccs.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs.Tpo $(DEPDIR)/tnccs.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/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 'tnc/tnccs/tnccs.c' || echo '$(srcdir)/'`tnc/tnccs/tnccs.c
+
+tnccs_manager.lo: tnc/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 'tnc/tnccs/tnccs_manager.c' || echo '$(srcdir)/'`tnc/tnccs/tnccs_manager.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_manager.Tpo $(DEPDIR)/tnccs_manager.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tnc/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 'tnc/tnccs/tnccs_manager.c' || echo '$(srcdir)/'`tnc/tnccs/tnccs_manager.c
+
+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)$(ipseclibdir)"; 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-ipseclibLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-ipseclibLTLIBRARIES
+
+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-ipseclibLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-ipseclibLTLIBRARIES clean-libtool 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-ipseclibLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-ipseclibLTLIBRARIES
+
+
+# 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/tnc/imc/imc.h b/src/libtnccs/tnc/imc/imc.h
index fe8f25b0f..3ff7d5194 100644
--- a/src/libcharon/tnc/imc/imc.h
+++ b/src/libtnccs/tnc/imc/imc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010-2011 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -24,7 +24,8 @@
#ifndef IMC_H_
#define IMC_H_
-#include <tnc/tncifimc.h>
+#include <tncifimc.h>
+
#include <library.h>
typedef struct imc_t imc_t;
@@ -39,11 +40,11 @@ struct imc_t {
* the API version number to be used. It also supplies the IMC ID, an IMC
* identifier that the IMC must use when calling TNC Client callback functions.
*
- * @param imcID IMC ID assigned by TNCC
- * @param minVersion minimum API version supported by TNCC
- * @param maxVersion maximum API version supported by TNCC
- * @param OutActualVersion mutually supported API version number
- * @return TNC result code
+ * @param imcID IMC ID assigned by TNCC
+ * @param minVersion minimum API version supported by TNCC
+ * @param maxVersion maximum API version supported by TNCC
+ * @param OutActualVersion mutually supported API version number
+ * @return TNC result code
*/
TNC_Result (*initialize)(TNC_IMCID imcID,
TNC_Version minVersion,
@@ -54,10 +55,10 @@ struct imc_t {
* The TNC Client calls this function to inform the IMC that the state of
* the network connection identified by connectionID has changed to newState.
*
- * @param imcID IMC ID assigned by TNCC
- * @param connectionID network connection ID assigned by TNCC
- * @param newState new network connection state
- * @return TNC result code
+ * @param imcID IMC ID assigned by TNCC
+ * @param connectionID network connection ID assigned by TNCC
+ * @param newState new network connection state
+ * @return TNC result code
*/
TNC_Result (*notify_connection_change)(TNC_IMCID imcID,
TNC_ConnectionID connectionID,
@@ -67,9 +68,9 @@ struct imc_t {
* The TNC Client calls this function to indicate that an Integrity Check
* Handshake is beginning and solicit messages from IMCs for the first batch.
*
- * @param imcID IMC ID assigned by TNCC
- * @param connectionID network connection ID assigned by TNCC
- * @return TNC result code
+ * @param imcID IMC ID assigned by TNCC
+ * @param connectionID network connection ID assigned by TNCC
+ * @return TNC result code
*/
TNC_Result (*begin_handshake)(TNC_IMCID imcID,
TNC_ConnectionID connectionID);
@@ -80,12 +81,12 @@ struct imc_t {
* the number of octets indicated by messageLength. The type of the message
* is indicated by messageType.
*
- * @param imcID IMC ID assigned by TNCS
- * @param connectionID network connection ID assigned by TNCC
- * @param message reference to buffer containing message
- * @param messageLength number of octets in message
- * @param messageType message type of message
- * @return TNC result code
+ * @param imcID IMC ID assigned by TNCS
+ * @param connectionID network connection ID assigned by TNCC
+ * @param message reference to buffer containing message
+ * @param messageLength number of octets in message
+ * @param messageType message type of message
+ * @return TNC result code
*/
TNC_Result (*receive_message)(TNC_IMCID imcID,
TNC_ConnectionID connectionID,
@@ -94,13 +95,40 @@ struct imc_t {
TNC_MessageType messageType);
/**
+ * The TNC Client calls this function to deliver a message to the IMC.
+ * The message is contained in the buffer referenced by message and contains
+ * the number of octets indicated by messageLength. The type of the message
+ * is indicated by the message Vendor ID and message subtype.
+ *
+ * @param imcID IMC ID assigned by TNCS
+ * @param connectionID network connection ID assigned by TNCC
+ * @param messageFlags message flags
+ * @param message reference to buffer containing message
+ * @param messageLength number of octets in message
+ * @param messageVendorID message Vendor ID
+ * @param messageSubtype message subtype
+ * @param sourceIMVID source IMV ID
+ * @param destinationIMCID destination IMC ID
+ * @return TNC result code
+ */
+ TNC_Result (*receive_message_long)(TNC_IMCID imcID,
+ TNC_ConnectionID connectionID,
+ TNC_UInt32 messageFlags,
+ TNC_BufferReference message,
+ TNC_UInt32 messageLength,
+ TNC_VendorID messageVendorID,
+ TNC_MessageSubtype messageSubtype,
+ TNC_UInt32 sourceIMVID,
+ TNC_UInt32 destinationIMCID);
+
+ /**
* The TNC Client calls this function to notify IMCs that all IMV messages
* received in a batch have been delivered and this is the IMC’s last chance
* to send a message in the batch of IMC messages currently being collected.
*
- * @param imcID IMC ID assigned by TNCC
- * @param connectionID network connection ID assigned by TNCC
- * @return TNC result code
+ * @param imcID IMC ID assigned by TNCC
+ * @param connectionID network connection ID assigned by TNCC
+ * @return TNC result code
*/
TNC_Result (*batch_ending)(TNC_IMCID imcID,
TNC_ConnectionID connectionID);
@@ -109,8 +137,8 @@ struct imc_t {
* The TNC Client calls this function to close down the IMC when all work is
* complete or the IMC reports TNC_RESULT_FATAL.
*
- * @param imcID IMC ID assigned by TNCC
- * @return TNC result code
+ * @param imcID IMC ID assigned by TNCC
+ * @return TNC result code
*/
TNC_Result (*terminate)(TNC_IMCID imcID);
@@ -121,9 +149,9 @@ struct imc_t {
* TNCS bind function. The IMV can then use the TNCS bind function to obtain
* pointers to any other TNCS functions.
*
- * @param imcID IMC ID assigned by TNCC
- * @param bindFunction pointer to TNC_TNCC_BindFunction
- * @return TNC result code
+ * @param imcID IMC ID assigned by TNCC
+ * @param bindFunction pointer to TNC_TNCC_BindFunction
+ * @return TNC result code
*/
TNC_Result (*provide_bind_function)(TNC_IMCID imcID,
TNC_TNCC_BindFunctionPointer bindFunction);
@@ -131,40 +159,67 @@ struct imc_t {
/**
* Sets the ID of an imc_t object.
*
- * @param id IMC ID to be assigned
+ * @param id IMC ID to be assigned
*/
void (*set_id)(imc_t *this, TNC_IMCID id);
/**
* Returns the ID of an imc_t object.
*
- * @return assigned IMC ID
+ * @return assigned IMC ID
*/
TNC_IMCID (*get_id)(imc_t *this);
/**
+ * Assign an additional ID to an imc_t object.
+ *
+ * @param id additional IMC ID to be assigned
+ */
+ void (*add_id)(imc_t *this, TNC_IMCID id);
+
+ /**
+ * Checks if the ID is assigned to the imc_t object.
+ *
+ * @return TRUE if IMC ID is assigned to imc_t object
+ */
+ bool (*has_id)(imc_t *this, TNC_IMCID id);
+
+ /**
* Returns the name of an imc_t object.
*
- * @return name of IMC
+ * @return name of IMC
*/
char* (*get_name)(imc_t *this);
/**
* Sets the supported message types of an imc_t object.
*
- * @param supported_types list of messages type supported by IMC
- * @param type_count number of supported message types
+ * @param supported_types list of messages type supported by IMC
+ * @param type_count number of supported message types
*/
void (*set_message_types)(imc_t *this, TNC_MessageTypeList supported_types,
TNC_UInt32 type_count);
/**
+ * Sets the supported long message types of an imc_t object.
+ *
+ * @param supported_vids list of vendor IDs supported by IMC
+ * @param supported_subtypes list of messages type supported by IMC
+ * @param type_count number of supported message types
+ */
+ void (*set_message_types_long)(imc_t *this, TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count);
+
+ /**
* Check if the IMC supports a given message type.
*
- * @param message_type message type
- * @return TRUE if supported
+ * @param msg_vid message vendor ID
+ * @param msg_subtype message subtype
+ * @return TRUE if supported
*/
- bool (*type_supported)(imc_t *this, TNC_MessageType message_type);
+ bool (*type_supported)(imc_t *this, TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype);
/**
* Destroys an imc_t object.
diff --git a/src/libcharon/tnc/imc/imc_manager.h b/src/libtnccs/tnc/imc/imc_manager.h
index ad83cf552..25e0efe9d 100644
--- a/src/libcharon/tnc/imc/imc_manager.h
+++ b/src/libtnccs/tnc/imc/imc_manager.h
@@ -21,12 +21,12 @@
#ifndef IMC_MANAGER_H_
#define IMC_MANAGER_H_
+typedef struct imc_manager_t imc_manager_t;
+
#include "imc.h"
#include <library.h>
-typedef struct imc_manager_t imc_manager_t;
-
/**
* The IMC manager controls all IMC instances.
*/
@@ -49,6 +49,15 @@ struct imc_manager_t {
imc_t* (*remove)(imc_manager_t *this, TNC_IMCID id);
/**
+ * Load and initialize an IMC as a dynamic library and add it to the list
+ *
+ * @param name name of the IMC to be loaded
+ * @param path path of the IMC dynamic library file
+ * @return TRUE if loading succeeded
+ */
+ bool (*load)(imc_manager_t *this, char *name, char *path);
+
+ /**
* Check if an IMC with a given ID is registered with the IMC manager
*
* @param id ID of IMC instance
@@ -57,6 +66,15 @@ struct imc_manager_t {
bool (*is_registered)(imc_manager_t *this, TNC_IMCID id);
/**
+ * Reserve an additional ID for an IMC
+ *
+ * @param id ID of IMC instance
+ * @param new_id reserved ID assigned to IMC
+ * @return TRUE if primary IMC ID was used
+ */
+ bool (*reserve_id)(imc_manager_t *this, TNC_IMCID id, TNC_UInt32 *new_id);
+
+ /**
* Return the preferred language for recommendations
*
* @return preferred language string
@@ -75,17 +93,17 @@ struct imc_manager_t {
/**
* Begin a handshake between the IMCs and a connection
*
- * @param id connection ID
+ * @param id connection ID
*/
void (*begin_handshake)(imc_manager_t *this, TNC_ConnectionID id);
/**
* Sets the supported message types reported by a given IMC
*
- * @param id ID of reporting IMC
- * @param supported_types list of messages type supported by IMC
- * @param type_count number of supported message types
- * @return TNC result code
+ * @param id ID of reporting IMC
+ * @param supported_types list of messages type supported by IMC
+ * @param type_count number of supported message types
+ * @return TNC result code
*/
TNC_Result (*set_message_types)(imc_manager_t *this,
TNC_IMCID id,
@@ -93,18 +111,41 @@ struct imc_manager_t {
TNC_UInt32 type_count);
/**
+ * Sets the supported long message types reported by a given IMC
+ *
+ * @param id ID of reporting IMC
+ * @param supported_vids list of vendor IDs supported by IMC
+ * @param supported_subtypes list of messages type supported by IMC
+ * @param type_count number of supported message types
+ * @return TNC result code
+ */
+ TNC_Result (*set_message_types_long)(imc_manager_t *this,
+ TNC_IMCID id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count);
+
+ /**
* Delivers a message to interested IMCs.
*
- * @param connection_id ID of connection over which message was received
- * @param message message
- * @param message_len message length
- * @param message_type message type
+ * @param connection_id connection ID
+ * @param excl exclusive message flag
+ * @param msg message
+ * @param msg_len message length
+ * @param msg_vid message Vendor ID
+ * @param msg_subtype message subtype
+ * @param src_imv_id source IMV ID
+ * @param dst_imc_id destination IMC ID
*/
void (*receive_message)(imc_manager_t *this,
TNC_ConnectionID connection_id,
- TNC_BufferReference message,
- TNC_UInt32 message_len,
- TNC_MessageType message_type);
+ bool excl,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imv_id,
+ TNC_UInt32 dst_imc_id);
/**
* Notify all IMCs that all IMV messages received in a batch have been
diff --git a/src/libcharon/tnc/imv/imv.h b/src/libtnccs/tnc/imv/imv.h
index 26874ab0b..3716532d6 100644
--- a/src/libcharon/tnc/imv/imv.h
+++ b/src/libtnccs/tnc/imv/imv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010-2011 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -24,7 +24,8 @@
#ifndef IMV_H_
#define IMV_H_
-#include <tnc/tncifimv.h>
+#include <tncifimv.h>
+
#include <library.h>
typedef struct imv_t imv_t;
@@ -39,11 +40,11 @@ struct imv_t {
* the API version number to be used. It also supplies the IMV ID, an IMV
* identifier that the IMV must use when calling TNC Server callback functions.
*
- * @param imvID IMV ID assigned by TNCS
- * @param minVersion minimum API version supported
- * @param maxVersion maximum API version supported by TNCS
- * @param OutActualVersion mutually supported API version number
- * @return TNC result code
+ * @param imvID IMV ID assigned by TNCS
+ * @param minVersion minimum API version supported
+ * @param maxVersion maximum API version supported by TNCS
+ * @param OutActualVersion mutually supported API version number
+ * @return TNC result code
*/
TNC_Result (*initialize)(TNC_IMVID imvID,
TNC_Version minVersion,
@@ -54,10 +55,10 @@ struct imv_t {
* The TNC Server calls this function to inform the IMV that the state of
* the network connection identified by connectionID has changed to newState.
*
- * @param imvID IMV ID assigned by TNCS
- * @param connectionID network connection ID assigned by TNCS
- * @param newState new network connection state
- * @return TNC result code
+ * @param imvID IMV ID assigned by TNCS
+ * @param connectionID network connection ID assigned by TNCS
+ * @param newState new network connection state
+ * @return TNC result code
*/
TNC_Result (*notify_connection_change)(TNC_IMVID imvID,
TNC_ConnectionID connectionID,
@@ -68,9 +69,9 @@ struct imv_t {
* Handshake (after all IMC-IMV messages have been delivered) to solicit
* recommendations from IMVs that have not yet provided a recommendation.
*
- * @param imvID IMV ID assigned by TNCS
- * @param connectionID network connection ID assigned by TNCS
- * @return TNC result code
+ * @param imvID IMV ID assigned by TNCS
+ * @param connectionID network connection ID assigned by TNCS
+ * @return TNC result code
*/
TNC_Result (*solicit_recommendation)(TNC_IMVID imvID,
TNC_ConnectionID connectionID);
@@ -81,12 +82,12 @@ struct imv_t {
* the number of octets indicated by messageLength. The type of the message
* is indicated by messageType.
*
- * @param imvID IMV ID assigned by TNCS
- * @param connectionID network connection ID assigned by TNCS
- * @param message reference to buffer containing message
- * @param messageLength number of octets in message
- * @param messageType message type of message
- * @return TNC result code
+ * @param imvID IMV ID assigned by TNCS
+ * @param connectionID network connection ID assigned by TNCS
+ * @param message reference to buffer containing message
+ * @param messageLength number of octets in message
+ * @param messageType message type of message
+ * @return TNC result code
*/
TNC_Result (*receive_message)(TNC_IMVID imvID,
TNC_ConnectionID connectionID,
@@ -95,13 +96,40 @@ struct imv_t {
TNC_MessageType messageType);
/**
+ * The TNC Server calls this function to deliver a message to the IMV.
+ * The message is contained in the buffer referenced by message and contains
+ * the number of octets indicated by messageLength. The type of the message
+ * is indicated by the message Vendor ID and message subtype.
+ *
+ * @param imvID IMV ID assigned by TNCS
+ * @param connectionID network connection ID assigned by TNCS
+ * @param messageFlags message flags
+ * @param message reference to buffer containing message
+ * @param messageLength number of octets in message
+ * @param messageVendorID message Vendor ID
+ * @param messageSubtype message subtype
+ * @param sourceIMCID source IMC ID
+ * @param destinationIMVID destination IMV ID
+ * @return TNC result code
+ */
+ TNC_Result (*receive_message_long)(TNC_IMVID imvID,
+ TNC_ConnectionID connectionID,
+ TNC_UInt32 messageFlags,
+ TNC_BufferReference message,
+ TNC_UInt32 messageLength,
+ TNC_VendorID messageVendorID,
+ TNC_MessageSubtype messageSubtype,
+ TNC_UInt32 sourceIMCID,
+ TNC_UInt32 destinationIMVID);
+
+ /**
* The TNC Server calls this function to notify IMVs that all IMC messages
* received in a batch have been delivered and this is the IMV’s last chance
* to send a message in the batch of IMV messages currently being collected.
*
- * @param imvID IMV ID assigned by TNCS
- * @param connectionID network connection ID assigned by TNCS
- * @return TNC result code
+ * @param imvID IMV ID assigned by TNCS
+ * @param connectionID network connection ID assigned by TNCS
+ * @return TNC result code
*/
TNC_Result (*batch_ending)(TNC_IMVID imvID,
TNC_ConnectionID connectionID);
@@ -109,8 +137,8 @@ struct imv_t {
/**
* The TNC Server calls this function to close down the IMV.
*
- * @param imvID IMV ID assigned by TNCS
- * @return TNC result code
+ * @param imvID IMV ID assigned by TNCS
+ * @return TNC result code
*/
TNC_Result (*terminate)(TNC_IMVID imvID);
@@ -121,9 +149,9 @@ struct imv_t {
* TNCS bind function. The IMV can then use the TNCS bind function to obtain
* pointers to any other TNCS functions.
*
- * @param imvID IMV ID assigned by TNCS
- * @param bindFunction pointer to TNC_TNCS_BindFunction
- * @return TNC result code
+ * @param imvID IMV ID assigned by TNCS
+ * @param bindFunction pointer to TNC_TNCS_BindFunction
+ * @return TNC result code
*/
TNC_Result (*provide_bind_function)(TNC_IMVID imvID,
TNC_TNCS_BindFunctionPointer bindFunction);
@@ -131,40 +159,67 @@ struct imv_t {
/**
* Sets the ID of an imv_t object.
*
- * @param id IMV ID to be assigned
+ * @param id IMV ID to be assigned
*/
void (*set_id)(imv_t *this, TNC_IMVID id);
/**
* Returns the ID of an imv_t object.
*
- * @return IMV ID assigned by TNCS
+ * @return IMV ID assigned by TNCS
*/
TNC_IMVID (*get_id)(imv_t *this);
/**
+ * Assign an additional ID to an imv_t object.
+ *
+ * @param id additional IMV ID to be assigned
+ */
+ void (*add_id)(imv_t *this, TNC_IMVID id);
+
+ /**
+ * Checks if the ID is assigned to the imv_t object.
+ *
+ * @return TRUE if IMV ID is assigned to imv_t object
+ */
+ bool (*has_id)(imv_t *this, TNC_IMVID id);
+
+ /**
* Returns the name of an imv_t object.
*
- * @return name of IMV
+ * @return name of IMV
*/
char* (*get_name)(imv_t *this);
/**
* Sets the supported message types of an imv_t object.
*
- * @param supported_types list of messages type supported by IMV
- * @param type_count number of supported message types
+ * @param supported_types list of messages type supported by IMV
+ * @param type_count number of supported message types
*/
void (*set_message_types)(imv_t *this, TNC_MessageTypeList supported_types,
TNC_UInt32 type_count);
/**
+ * Sets the supported long message types of an imv_t object.
+ *
+ * @param supported_vids list of vendor IDs supported by IMC
+ * @param supported_subtypes list of messages type supported by IMC
+ * @param type_count number of supported message types
+ */
+ void (*set_message_types_long)(imv_t *this, TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count);
+
+ /**
* Check if the IMV supports a given message type.
*
- * @param message_type message type
- * @return TRUE if supported
+ * @param msg_vid message vendor ID
+ * @param msg_subtype message subtype
+ * @return TRUE if supported
*/
- bool (*type_supported)(imv_t *this, TNC_MessageType message_type);
+ bool (*type_supported)(imv_t *this, TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype);
/**
* Destroys an imv_t object.
diff --git a/src/libcharon/tnc/imv/imv_manager.h b/src/libtnccs/tnc/imv/imv_manager.h
index 0dd2d6253..43f40973c 100644
--- a/src/libcharon/tnc/imv/imv_manager.h
+++ b/src/libtnccs/tnc/imv/imv_manager.h
@@ -21,13 +21,13 @@
#ifndef IMV_MANAGER_H_
#define IMV_MANAGER_H_
+typedef struct imv_manager_t imv_manager_t;
+
#include "imv.h"
#include "imv_recommendations.h"
#include <library.h>
-typedef struct imv_manager_t imv_manager_t;
-
/**
* The IMV manager controls all IMV instances.
*/
@@ -50,6 +50,16 @@ struct imv_manager_t {
imv_t* (*remove)(imv_manager_t *this, TNC_IMVID id);
/**
+ * Load and initialize an IMV as a dynamic library and add it to the list
+ *
+ * @param name name of the IMV to be loaded
+ * @param path path of the IMV dynamic library file
+ * @return TRUE if loading succeeded
+ */
+ bool (*load)(imv_manager_t *this, char *name, char *path);
+
+
+ /**
* Check if an IMV with a given ID is registered with the IMV manager
*
* @param id ID of IMV instance
@@ -57,6 +67,14 @@ struct imv_manager_t {
*/
bool (*is_registered)(imv_manager_t *this, TNC_IMVID id);
+ /**
+ * Reserve an additional ID for an IMV
+ *
+ * @param id ID of IMV instance
+ * @param new_id reserved ID assigned to IMV
+ * @return TRUE if primary IMV ID was used
+ */
+ bool (*reserve_id)(imv_manager_t *this, TNC_IMVID id, TNC_UInt32 *new_id);
/**
* Get the configured recommendation policy
@@ -96,10 +114,10 @@ struct imv_manager_t {
/**
* Sets the supported message types reported by a given IMV
*
- * @param id ID of reporting IMV
- * @param supported_types list of messages type supported by IMV
- * @param type_count number of supported message types
- * @return TNC result code
+ * @param id ID of reporting IMV
+ * @param supported_types list of messages type supported by IMV
+ * @param type_count number of supported message types
+ * @return TNC result code
*/
TNC_Result (*set_message_types)(imv_manager_t *this,
TNC_IMVID id,
@@ -107,25 +125,48 @@ struct imv_manager_t {
TNC_UInt32 type_count);
/**
+ * Sets the supported long message types reported by a given IMV
+ *
+ * @param id ID of reporting IMV
+ * @param supported_vids list of vendor IDs supported by IMV
+ * @param supported_subtypes list of messages type supported by IMV
+ * @param type_count number of supported message types
+ * @return TNC result code
+ */
+ TNC_Result (*set_message_types_long)(imv_manager_t *this,
+ TNC_IMVID id,
+ TNC_VendorIDList supported_vids,
+ TNC_MessageSubtypeList supported_subtypes,
+ TNC_UInt32 type_count);
+
+ /**
* Solicit recommendations from IMVs that have not yet provided one
*
- * @param id connection ID
+ * @param id connection ID
*/
void (*solicit_recommendation)(imv_manager_t *this, TNC_ConnectionID id);
/**
* Delivers a message to interested IMVs.
*
- * @param connection_id ID of connection over which message was received
- * @param message message
- * @param message_len message length
- * @param message_type message type
+ * @param connection_id connection ID
+ * @param excl exclusive message flag
+ * @param msg message
+ * @param msg_len message length
+ * @param msg_vid message Vendor ID
+ * @param msg_subtype message subtype
+ * @param src_imc_id source IMC ID
+ * @param dst_imv_id destination IMV ID
*/
void (*receive_message)(imv_manager_t *this,
TNC_ConnectionID connection_id,
- TNC_BufferReference message,
- TNC_UInt32 message_len,
- TNC_MessageType message_type);
+ bool excl,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype,
+ TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id);
/**
* Notify all IMVs that all IMC messages received in a batch have been
diff --git a/src/libcharon/tnc/imv/imv_recommendations.c b/src/libtnccs/tnc/imv/imv_recommendations.c
index 9daaca16c..9daaca16c 100644
--- a/src/libcharon/tnc/imv/imv_recommendations.c
+++ b/src/libtnccs/tnc/imv/imv_recommendations.c
diff --git a/src/libcharon/tnc/imv/imv_recommendations.h b/src/libtnccs/tnc/imv/imv_recommendations.h
index 3a6e25c9f..d694e16ae 100644
--- a/src/libcharon/tnc/imv/imv_recommendations.h
+++ b/src/libtnccs/tnc/imv/imv_recommendations.h
@@ -21,7 +21,7 @@
#ifndef IMV_RECOMMENDATIONS_H_
#define IMV_RECOMMENDATIONS_H_
-#include <tnc/tncifimv.h>
+#include <tncifimv.h>
#include <library.h>
typedef enum recommendation_policy_t recommendation_policy_t;
@@ -108,6 +108,12 @@ struct recommendations_t {
* @return enumerator
*/
enumerator_t* (*create_reason_enumerator)(recommendations_t *this);
+
+ /**
+ * Clears all reason entries
+ */
+ void (*clear_reasons)(recommendations_t *this);
+
/**
* Destroys an imv_t object.
*/
diff --git a/src/libtnccs/tnc/tnc.c b/src/libtnccs/tnc/tnc.c
new file mode 100644
index 000000000..652afc291
--- /dev/null
+++ b/src/libtnccs/tnc/tnc.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2011 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.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <utils/lexparser.h>
+#include <debug.h>
+
+typedef struct private_tnc_t private_tnc_t;
+
+typedef tnccs_manager_t *(*tnc_create_tnccs_manager_t)(void);
+typedef imc_manager_t *(*tnc_create_imc_manager_t)(void);
+typedef imv_manager_t *(*tnc_create_imv_manager_t)(void);
+
+/**
+ * Private additions to tnc_t.
+ */
+struct private_tnc_t {
+
+ /**
+ * Public members of tnc_t.
+ */
+ tnc_t public;
+};
+
+/**
+ * Single instance of tnc_t.
+ */
+tnc_t *tnc;
+
+/**
+ * Described in header.
+ */
+void libtnccs_init(void)
+{
+ private_tnc_t *this;
+
+ INIT(this,
+ .public = {
+ },
+ );
+
+ tnc = &this->public;
+}
+
+/**
+ * Described in header.
+ */
+void libtnccs_deinit(void)
+{
+ private_tnc_t *this = (private_tnc_t*)tnc;
+
+ free(this);
+ tnc = NULL;
+}
+
+static bool load_imcvs_from_config(char *filename, bool is_imc)
+{
+ int fd, line_nr = 0;
+ chunk_t src, line;
+ struct stat sb;
+ void *addr;
+ char *label;
+
+ label = is_imc ? "IMC" : "IMV";
+
+ DBG1(DBG_TNC, "loading %ss from '%s'", label, filename);
+ fd = open(filename, O_RDONLY);
+ if (fd == -1)
+ {
+ DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
+ strerror(errno));
+ return FALSE;
+ }
+ if (fstat(fd, &sb) == -1)
+ {
+ DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
+ strerror(errno));
+ close(fd);
+ return FALSE;
+ }
+ 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", filename, strerror(errno));
+ close(fd);
+ return FALSE;
+ }
+ src = chunk_create(addr, sb.st_size);
+
+ while (fetchline(&src, &line))
+ {
+ char *name, *path;
+ bool success;
+ chunk_t token;
+
+ line_nr++;
+
+ /* skip comments or empty lines */
+ if (*line.ptr == '#' || !eat_whitespace(&line))
+ {
+ continue;
+ }
+
+ /* determine keyword */
+ if (!extract_token(&token, ' ', &line))
+ {
+ DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
+ line_nr);
+ return FALSE;
+ }
+
+ /* only interested in IMCs or IMVs depending on label */
+ if (!match(label, &token))
+ {
+ continue;
+ }
+
+ /* advance to the IMC/IMV name and extract it */
+ if (!extract_token(&token, '"', &line) ||
+ !extract_token(&token, '"', &line))
+ {
+ DBG1(DBG_TNC, "line %d: %s name must be set in double quotes",
+ line_nr, label);
+ return FALSE;
+ }
+
+ /* copy the IMC/IMV name */
+ name = malloc(token.len + 1);
+ memcpy(name, token.ptr, token.len);
+ name[token.len] = '\0';
+
+ /* advance to the IMC/IMV path and extract it */
+ if (!eat_whitespace(&line))
+ {
+ DBG1(DBG_TNC, "line %d: %s path is missing", line_nr, label);
+ free(name);
+ return FALSE;
+ }
+ if (!extract_token(&token, ' ', &line))
+ {
+ token = line;
+ }
+
+ /* copy the IMC/IMV path */
+ path = malloc(token.len + 1);
+ memcpy(path, token.ptr, token.len);
+ path[token.len] = '\0';
+
+ /* load and register an IMC/IMV instance */
+ if (is_imc)
+ {
+ success = tnc->imcs->load(tnc->imcs, name, path);
+ }
+ else
+ {
+ success = tnc->imvs->load(tnc->imvs, name, path);
+ }
+ if (!success)
+ {
+ return FALSE;
+ }
+ }
+ munmap(addr, sb.st_size);
+ close(fd);
+ return TRUE;
+}
+
+/**
+ * Described in header.
+ */
+bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data)
+{
+ bool load_imcvs = FALSE;
+ bool is_imc = FALSE;
+
+ if (feature->type == FEATURE_CUSTOM)
+ {
+ if (streq(feature->arg.custom, "tnccs-manager"))
+ {
+ if (reg)
+ {
+ tnc->tnccs = ((tnc_create_tnccs_manager_t)data)();
+ }
+ else
+ {
+ tnc->tnccs->destroy(tnc->tnccs);
+ tnc->tnccs = NULL;
+ }
+ }
+ else if (streq(feature->arg.custom, "imc-manager"))
+ {
+ if (reg)
+ {
+ tnc->imcs = ((tnc_create_imc_manager_t)data)();
+ is_imc = TRUE;
+ load_imcvs = TRUE;
+ }
+ else
+ {
+ tnc->imcs->destroy(tnc->imcs);
+ tnc->imcs = NULL;
+ }
+ }
+ else if (streq(feature->arg.custom, "imv-manager"))
+ {
+ if (reg)
+ {
+ tnc->imvs = ((tnc_create_imv_manager_t)data)();
+ is_imc = FALSE;
+ load_imcvs = TRUE;
+ }
+ else
+ {
+ tnc->imvs->destroy(tnc->imvs);
+ tnc->imvs = NULL;
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ if (load_imcvs)
+ {
+ char *tnc_config;
+
+ tnc_config = lib->settings->get_str(lib->settings,
+ "libtnccs.tnc_config", "/etc/tnc_config");
+ if (!load_imcvs_from_config(tnc_config, is_imc))
+ {
+ if (is_imc)
+ {
+ tnc->imcs->destroy(tnc->imcs);
+ tnc->imcs = NULL;
+ }
+ else
+ {
+ tnc->imvs->destroy(tnc->imvs);
+ tnc->imvs = NULL;
+ }
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
diff --git a/src/libtnccs/tnc/tnc.h b/src/libtnccs/tnc/tnc.h
new file mode 100644
index 000000000..e5a4a2959
--- /dev/null
+++ b/src/libtnccs/tnc/tnc.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 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 tnc
+ *
+ * @addtogroup tnc
+ * @{
+ */
+
+#ifndef TNC_H_
+#define TNC_H_
+
+typedef struct tnc_t tnc_t;
+
+#include "tnc/imc/imc_manager.h"
+#include "tnc/imv/imv_manager.h"
+#include "tnc/tnccs/tnccs_manager.h"
+
+#include <library.h>
+
+/**
+ * TNC management support object.
+ */
+struct tnc_t {
+
+ /**
+ * TNC-IMC manager controlling Integrity Measurement Collectors
+ */
+ imc_manager_t *imcs;
+
+ /**
+ * TNC-IMV manager controlling Integrity Measurement Verifiers
+ */
+ imv_manager_t *imvs;
+
+ /**
+ * TNC-TNCCS manager controlling the TNC Server and Client protocols
+ */
+ tnccs_manager_t *tnccs;
+
+};
+
+/**
+ * The single instance of tnc_t.
+ *
+ * Exists between calls to libtnccs_init() and libtnccs_deinit().
+ */
+extern tnc_t *tnc;
+
+/**
+ * Initialize libtnccs.
+ */
+void libtnccs_init(void);
+
+/**
+ * Deinitialize libtnccs
+ */
+void libtnccs_deinit(void);
+
+/**
+ * Helper function to (un-)register TNC managers from plugin features.
+ *
+ * This function is a plugin_feature_callback_t and can be used with the
+ * PLUGIN_CALLBACK macro to register a TNC manager constructor.
+ *
+ * @param plugin plugin registering the TNC manager
+ * @param feature associated plugin feature
+ * @param reg TRUE to register, FALSE to unregister.
+ * @param data data passed to callback, a TNC manager constructor
+ */
+bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data);
+
+#endif /** TNC_H_ @}*/
diff --git a/src/libcharon/tnc/tnccs/tnccs.c b/src/libtnccs/tnc/tnccs/tnccs.c
index 575b850f5..80d0f497c 100644
--- a/src/libcharon/tnc/tnccs/tnccs.c
+++ b/src/libtnccs/tnc/tnccs/tnccs.c
@@ -21,3 +21,4 @@ ENUM(tnccs_type_names, TNCCS_UNKNOWN, TNCCS_2_0,
"TNCCS SOH",
"TNCCS 2.0",
);
+
diff --git a/src/libcharon/tnc/tnccs/tnccs.h b/src/libtnccs/tnc/tnccs/tnccs.h
index 32f065f67..c3020d7c3 100644
--- a/src/libcharon/tnc/tnccs/tnccs.h
+++ b/src/libtnccs/tnc/tnccs/tnccs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 Andreas Steffen
+ * Copyright (C) 2010-2011 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -24,19 +24,15 @@
#ifndef TNCCS_H_
#define TNCCS_H_
-#include <tnc/tncif.h>
-#include <tnc/tncifimc.h>
-#include <tnc/tncifimv.h>
-#include <library.h>
+typedef struct tnccs_t tnccs_t;
+typedef enum tnccs_type_t tnccs_type_t;
-#define IETF_VENDOR_ID 0x000000 /* 0 */
-#define MICROSOFT_VENDOR_ID 0x000137 /* 311 */
-#define OSC_VENDOR_ID 0x002358 /* 9048 */
-#define FHH_VENDOR_ID 0x0080ab /* 32939 */
-#define ITA_VENDOR_ID 0x00902a /* 36906 */
-#define RESERVED_VENDOR_ID 0xffffff /* 16777215 */
+#include <tncif.h>
+#include <tncifimc.h>
+#include <tncifimv.h>
-typedef enum tnccs_type_t tnccs_type_t;
+#include <library.h>
+#include <plugins/plugin.h>
/**
* Type of TNC Client/Server protocol
@@ -54,30 +50,33 @@ enum 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);
+typedef tnccs_t *(*tnccs_constructor_t)(bool is_server);
/**
* Callback function adding a message to a TNCCS batch
*
* @param imc_id ID of IMC or TNC_IMCID_ANY
* @param imc_id ID of IMV or TNC_IMVID_ANY
+ * @param msg_flags message flags
* @param msg message to be added
* @param msg_len message length
- * @param msg_type message type
- * @return result code
+ * @param msg_vid message vendor ID
+ * @param msg_subtype message subtype
+ * @return return code
*/
-typedef TNC_Result (*tnccs_send_message_t)(tnccs_t* tncss, TNC_IMCID imc_id,
- TNC_IMVID imv_id,
- TNC_BufferReference msg,
- TNC_UInt32 msg_len,
- TNC_MessageType msg_type);
+typedef TNC_Result (*tnccs_send_message_t)(tnccs_t* tncss,
+ TNC_IMCID imc_id,
+ TNC_IMVID imv_id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype);
#endif /** TNCCS_H_ @}*/
diff --git a/src/libtnccs/tnc/tnccs/tnccs_manager.c b/src/libtnccs/tnc/tnccs/tnccs_manager.c
new file mode 100644
index 000000000..fa91bfb21
--- /dev/null
+++ b/src/libtnccs/tnc/tnccs/tnccs_manager.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 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 "tnc/tnc.h"
+
+#include <debug.h>
+
+/**
+ * See header
+ */
+bool tnccs_method_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data)
+{
+ if (!tnc || !tnc->tnccs)
+ {
+ DBG1(DBG_TNC, "TNC TNCCS manager does not exist");
+ return FALSE;
+ }
+ if (reg)
+ {
+ if (feature->type == FEATURE_CUSTOM)
+ {
+ tnccs_type_t type = TNCCS_UNKNOWN;
+
+ if (streq(feature->arg.custom, "tnccs-2.0"))
+ {
+ type = TNCCS_2_0;
+ }
+ else if (streq(feature->arg.custom, "tnccs-1.1"))
+ {
+ type = TNCCS_1_1;
+ }
+ else if (streq(feature->arg.custom, "tnccs-dynamic"))
+ {
+ type = TNCCS_DYNAMIC;
+ }
+ else
+ {
+ return FALSE;
+ }
+ tnc->tnccs->add_method(tnc->tnccs, type, (tnccs_constructor_t)data);
+ }
+ }
+ else
+ {
+ tnc->tnccs->remove_method(tnc->tnccs, (tnccs_constructor_t)data);
+ }
+ return TRUE;
+}
diff --git a/src/libcharon/tnc/tnccs/tnccs_manager.h b/src/libtnccs/tnc/tnccs/tnccs_manager.h
index 34f60029d..9ca450468 100644
--- a/src/libcharon/tnc/tnccs/tnccs_manager.h
+++ b/src/libtnccs/tnc/tnccs/tnccs_manager.h
@@ -21,12 +21,11 @@
#ifndef TNCCS_MANAGER_H_
#define TNCCS_MANAGER_H_
-#include "tnccs.h"
-
-#include <tnc/imv/imv_recommendations.h>
-
typedef struct tnccs_manager_t tnccs_manager_t;
+#include "tnccs.h"
+#include "tnc/imv/imv_recommendations.h"
+
/**
* The TNCCS manager manages all TNCCS implementations and creates instances.
*
@@ -67,16 +66,18 @@ struct tnccs_manager_t {
* callback function for adding a message to a TNCCS batch and create
* an empty set for collecting IMV recommendations
*
+ * @param type TNCCS protocol type
* @param tnccs TNCCS connection instance
* @param send_message TNCCS callback function
* @param request_handshake_retry pointer to boolean variable
* @param recs pointer to IMV recommendation set
* @return assigned connection ID
*/
- TNC_ConnectionID (*create_connection)(tnccs_manager_t *this, tnccs_t *tnccs,
+ TNC_ConnectionID (*create_connection)(tnccs_manager_t *this,
+ tnccs_type_t type, tnccs_t *tnccs,
tnccs_send_message_t send_message,
bool *request_handshake_retry,
- recommendations_t **recs);
+ recommendations_t **recs);
/**
* Remove a TNCCS connection using its connection ID.
@@ -107,17 +108,22 @@ struct tnccs_manager_t {
* @param imc_id ID of IMC or TNC_IMCID_ANY
* @param imv_id ID of IMV or TNC_IMVID_ANY
* @param id ID of target connection
+ * @param msg_flags message flags
* @param msg message to be added
* @param msg_len message length
- * @param msg_type message type
+ * @param msg_vid message vendor ID
+ * @param msg_subtype message subtype
* @return return code
*/
- TNC_Result (*send_message)(tnccs_manager_t *this, TNC_IMCID imc_id,
- TNC_IMVID imv_id,
- TNC_ConnectionID id,
- TNC_BufferReference msg,
- TNC_UInt32 msg_len,
- TNC_MessageType msg_type);
+ TNC_Result (*send_message)(tnccs_manager_t *this,
+ TNC_IMCID imc_id,
+ TNC_IMVID imv_id,
+ TNC_ConnectionID id,
+ TNC_UInt32 msg_flags,
+ TNC_BufferReference msg,
+ TNC_UInt32 msg_len,
+ TNC_VendorID msg_vid,
+ TNC_MessageSubtype msg_subtype);
/**
* Deliver an IMV Action Recommendation and IMV Evaluation Result to the TNCS
@@ -138,35 +144,37 @@ struct tnccs_manager_t {
* Get the value of an attribute associated with a connection or with the
* TNCS as a whole.
*
- * @param imv_id ID of the IMV requesting the attribute
+ * @param is_imc TRUE if IMC, FALSE if IMV
+ * @param imcv_id ID of the IMC/IMV requesting the attribute
* @param id ID of target connection
* @param attribute_id ID of the requested attribute
* @param buffer_len length of the buffer in bytes
* @param buffer pointer to the buffer
- * @param out_value_len actual length of the returned attribute
+ * @param value_len actual length of the returned attribute
* @return return code
*/
- TNC_Result (*get_attribute)(tnccs_manager_t *this,
- TNC_IMVID imv_id,
+ TNC_Result (*get_attribute)(tnccs_manager_t *this, bool is_imc,
+ TNC_UInt32 imcv_id,
TNC_ConnectionID id,
TNC_AttributeID attribute_id,
TNC_UInt32 buffer_len,
TNC_BufferReference buffer,
- TNC_UInt32 *out_value_len);
+ TNC_UInt32 *value_len);
/**
* Set the value of an attribute associated with a connection or with the
* TNCS as a whole.
*
- * @param imv_id ID of the IMV setting the attribute
+ * @param is_imc TRUE if IMC, FALSE if IMV
+ * @param imcv_id ID of the IMC/IMV setting the attribute
* @param id ID of target connection
* @param attribute_id ID of the attribute to be set
* @param buffer_len length of the buffer in bytes
* @param buffer pointer to the buffer
* @return return code
*/
- TNC_Result (*set_attribute)(tnccs_manager_t *this,
- TNC_IMVID imv_id,
+ TNC_Result (*set_attribute)(tnccs_manager_t *this, bool is_imc,
+ TNC_UInt32 imcv_id,
TNC_ConnectionID id,
TNC_AttributeID attribute_id,
TNC_UInt32 buffer_len,
@@ -179,8 +187,17 @@ struct tnccs_manager_t {
};
/**
- * Create a tnccs_manager instance.
+ * Helper function to (un-)register TNCCS methods from plugin features.
+ *
+ * This function is a plugin_feature_callback_t and can be used with the
+ * PLUGIN_CALLBACK macro to register a TNCCS method constructor.
+ *
+ * @param plugin plugin registering the TNCCS method constructor
+ * @param feature associated plugin feature
+ * @param reg TRUE to register, FALSE to unregister.
+ * @param data data passed to callback, a tnccs_constructor_t
*/
-tnccs_manager_t *tnccs_manager_create();
+bool tnccs_method_register(plugin_t *plugin, plugin_feature_t *feature,
+ bool reg, void *data);
#endif /** TNCCS_MANAGER_H_ @}*/
diff --git a/src/libtncif/Android.mk b/src/libtncif/Android.mk
new file mode 100644
index 000000000..ef406dd59
--- /dev/null
+++ b/src/libtncif/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# copy-n-paste from Makefile.am
+LOCAL_SRC_FILES := \
+tncif.h tncifimc.h tncifimv.h tncif_names.h tncif_names.c \
+tncif_pa_subtypes.h tncif_pa_subtypes.c
+
+# build libtncif ---------------------------------------------------------------
+
+LOCAL_C_INCLUDES += \
+ $(libvstr_PATH) \
+ $(strongswan_PATH)/src/libstrongswan
+
+LOCAL_CFLAGS := $(strongswan_CFLAGS)
+
+LOCAL_MODULE := libtncif
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_SHARED_LIBRARIES += libstrongswan
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/src/libtncif/Makefile.am b/src/libtncif/Makefile.am
new file mode 100644
index 000000000..cc262ffca
--- /dev/null
+++ b/src/libtncif/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I$(top_srcdir)/src/libstrongswan
+
+noinst_LTLIBRARIES = libtncif.la
+
+libtncif_la_SOURCES = \
+tncif.h tncifimc.h tncifimv.h tncif_names.h tncif_names.c \
+tncif_pa_subtypes.h tncif_pa_subtypes.c
+
+EXTRA_DIST = Android.mk
diff --git a/src/libtncif/Makefile.in b/src/libtncif/Makefile.in
new file mode 100644
index 000000000..462b8bd3f
--- /dev/null
+++ b/src/libtncif/Makefile.in
@@ -0,0 +1,545 @@
+# 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/libtncif
+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 =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libtncif_la_LIBADD =
+am_libtncif_la_OBJECTS = tncif_names.lo tncif_pa_subtypes.lo
+libtncif_la_OBJECTS = $(am_libtncif_la_OBJECTS)
+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 = $(libtncif_la_SOURCES)
+DIST_SOURCES = $(libtncif_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@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
+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@
+clearsilver_LIBS = @clearsilver_LIBS@
+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@
+imcvdir = @imcvdir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+ipsecdir = @ipsecdir@
+ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
+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@
+pcsclite_CFLAGS = @pcsclite_CFLAGS@
+pcsclite_LIBS = @pcsclite_LIBS@
+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@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
+srcdir = @srcdir@
+starter_plugins = @starter_plugins@
+strongswan_conf = @strongswan_conf@
+sysconfdir = @sysconfdir@
+systemdsystemunitdir = @systemdsystemunitdir@
+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
+noinst_LTLIBRARIES = libtncif.la
+libtncif_la_SOURCES = \
+tncif.h tncifimc.h tncifimv.h tncif_names.h tncif_names.c \
+tncif_pa_subtypes.h tncif_pa_subtypes.c
+
+EXTRA_DIST = Android.mk
+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/libtncif/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/libtncif/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
+libtncif.la: $(libtncif_la_OBJECTS) $(libtncif_la_DEPENDENCIES)
+ $(LINK) $(libtncif_la_OBJECTS) $(libtncif_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tncif_names.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tncif_pa_subtypes.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:
+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 \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES 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-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
+
+
+# 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/tnc/tncif.h b/src/libtncif/tncif.h
index 99441a9a9..f904bc600 100644
--- a/src/libcharon/tnc/tncif.h
+++ b/src/libtncif/tncif.h
@@ -1,22 +1,25 @@
/* tncif.h
*
- * Trusted Network Connect IF-IMV API version 1.20
+ * Trusted Network Connect IF-IMC/IMV API version 1.30
* Microsoft Windows DLL Platform Binding C Header
- * February 5, 2007
+ * October 14, 2011
*
- * Copyright(c) 2005-2007, Trusted Computing Group, Inc. All rights
+ * Common definitions for IF-IMC and IF-IMV
+ * extracted from tncifimc.h and tncifimv.h
+ *
+ * Copyright(c) 2005-2011, Trusted Computing Group, Inc. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * o Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
+ * o Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
- * - Neither the name of the Trusted Computing Group nor the names of
+ * o Neither the name of the Trusted Computing Group nor the names of
* its contributors may be used to endorse or promote products
* derived from this software without specific prior written
* permission.
@@ -41,40 +44,38 @@
* Any marks and brands contained herein are the property of their
* respective owners.
*
- * Trusted Network Connect IF-IMC/IF-IMV API version 1.00 Revision 3
- * Microsoft Windows DLL Platform Binding C Header
- * Common definitions for IF-IMC and IF-IMV
- * extracted from tncifimc.h and tncifimv.h
- * Feb 12, 2007
*/
/**
- * @defgroup tnc tnc
- * @ingroup libcharon
- *
* @defgroup tncif tncif
- * @{ @ingroup tnc
+ * @{ @ingroup libtncif
*/
#ifndef TNCIF_H_
#define TNCIF_H_
/* Basic Types */
+
typedef unsigned long TNC_UInt32;
typedef unsigned char *TNC_BufferReference;
/* Derived Types */
+
typedef TNC_UInt32 TNC_ConnectionID;
typedef TNC_UInt32 TNC_ConnectionState;
typedef TNC_UInt32 TNC_RetryReason;
typedef TNC_UInt32 TNC_MessageType;
typedef TNC_MessageType *TNC_MessageTypeList;
typedef TNC_UInt32 TNC_VendorID;
+typedef TNC_VendorID *TNC_VendorIDList;
typedef TNC_UInt32 TNC_MessageSubtype;
+typedef TNC_MessageSubtype *TNC_MessageSubtypeList;
typedef TNC_UInt32 TNC_Version;
typedef TNC_UInt32 TNC_Result;
+typedef TNC_UInt32 TNC_AttributeID;
/* Result Codes */
+
#define TNC_RESULT_SUCCESS 0
#define TNC_RESULT_NOT_INITIALIZED 1
#define TNC_RESULT_ALREADY_INITIALIZED 2
@@ -86,10 +87,17 @@ typedef TNC_UInt32 TNC_Result;
#define TNC_RESULT_ILLEGAL_OPERATION 8
#define TNC_RESULT_OTHER 9
#define TNC_RESULT_FATAL 10
+#define TNC_RESULT_EXCEEDED_MAX_ROUND_TRIPS 0x00559700
+#define TNC_RESULT_EXCEEDED_MAX_MESSAGE_SIZE 0x00559701
+#define TNC_RESULT_NO_LONG_MESSAGE_TYPES 0x00559702
+#define TNC_RESULT_NO_SOH_SUPPORT 0x00559703
/* Network Connection ID Values */
+
#define TNC_CONNECTIONID_ANY 0xFFFFFFFF
+
/* Network Connection State Values */
+
#define TNC_CONNECTION_STATE_CREATE 0
#define TNC_CONNECTION_STATE_HANDSHAKE 1
#define TNC_CONNECTION_STATE_ACCESS_ALLOWED 2
@@ -97,10 +105,38 @@ typedef TNC_UInt32 TNC_Result;
#define TNC_CONNECTION_STATE_ACCESS_NONE 4
#define TNC_CONNECTION_STATE_DELETE 5
+/* IMC/IMV ID Values */
+
+#define TNC_IMVID_ANY ((TNC_UInt32) 0xffff)
+#define TNC_IMCID_ANY ((TNC_UInt32) 0xffff)
+
/* Vendor ID Values */
+
#define TNC_VENDORID_TCG 0
+#define TNC_VENDORID_TCG_NEW 0x005597
#define TNC_VENDORID_ANY ((TNC_VendorID) 0xffffff)
+
/* Message Subtype Values */
+
#define TNC_SUBTYPE_ANY ((TNC_MessageSubtype) 0xff)
+/* Message Flags Values */
+
+#define TNC_MESSAGE_FLAGS_EXCLUSIVE ((TNC_UInt32) 0x80000000)
+
+/* Message Attribute ID Values */
+
+#define TNC_ATTRIBUTEID_PREFERRED_LANGUAGE ((TNC_AttributeID) 0x00000001)
+#define TNC_ATTRIBUTEID_MAX_ROUND_TRIPS ((TNC_AttributeID) 0x00559700)
+#define TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE ((TNC_AttributeID) 0x00559701)
+#define TNC_ATTRIBUTEID_DHPN ((TNC_AttributeID) 0x00559702)
+#define TNC_ATTRIBUTEID_HAS_LONG_TYPES ((TNC_AttributeID) 0x00559703)
+#define TNC_ATTRIBUTEID_HAS_EXCLUSIVE ((TNC_AttributeID) 0x00559704)
+#define TNC_ATTRIBUTEID_HAS_SOH ((TNC_AttributeID) 0x00559705)
+#define TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL ((TNC_AttributeID) 0x0055970A)
+#define TNC_ATTRIBUTEID_IFTNCCS_VERSION ((TNC_AttributeID) 0x0055970B)
+#define TNC_ATTRIBUTEID_IFT_PROTOCOL ((TNC_AttributeID) 0x0055970C)
+#define TNC_ATTRIBUTEID_IFT_VERSION ((TNC_AttributeID) 0x0055970D)
+#define TNC_ATTRIBUTEID_TLS_UNIQUE ((TNC_AttributeID) 0x0055970E)
+
#endif /** TNCIF_H_ @}*/
diff --git a/src/libcharon/tnc/tncifimv.c b/src/libtncif/tncif_names.c
index fbfd56566..c108776ec 100644
--- a/src/libcharon/tnc/tncifimv.c
+++ b/src/libtncif/tncif_names.c
@@ -13,7 +13,19 @@
* for more details.
*/
+#include "tncif.h"
#include "tncifimv.h"
+#include "tncif_names.h"
+
+ENUM(TNC_Connection_State_names,
+ TNC_CONNECTION_STATE_CREATE, TNC_CONNECTION_STATE_DELETE,
+ "Create",
+ "Handshake",
+ "Allowed",
+ "Isolated",
+ "None",
+ "Delete",
+);
ENUM(TNC_IMV_Action_Recommendation_names,
TNC_IMV_ACTION_RECOMMENDATION_ALLOW,
@@ -33,4 +45,3 @@ ENUM(TNC_IMV_Evaluation_Result_names,
"error",
"don't know"
);
-
diff --git a/src/libtncif/tncif_names.h b/src/libtncif/tncif_names.h
new file mode 100644
index 000000000..9b50a34e9
--- /dev/null
+++ b/src/libtncif/tncif_names.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 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 libtncif libtncif
+ *
+ * @addtogroup libtncif
+ * TNC interface definitions
+ *
+ * @defgroup tncif_names tncif_names
+ * @{ @ingroup libtncif
+ */
+
+#ifndef TNCIF_NAMES_H_
+#define TNCIF_NAMES_H_
+
+#include <library.h>
+
+extern enum_name_t *TNC_Connection_State_names;
+extern enum_name_t *TNC_IMV_Action_Recommendation_names;
+extern enum_name_t *TNC_IMV_Evaluation_Result_names;
+
+#endif /** TNCIF_NAME_H_ @}*/
diff --git a/src/libtncif/tncif_pa_subtypes.c b/src/libtncif/tncif_pa_subtypes.c
new file mode 100644
index 000000000..d15a1c864
--- /dev/null
+++ b/src/libtncif/tncif_pa_subtypes.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010-2011 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 "tncif_pa_subtypes.h"
+
+ENUM_BEGIN(pa_subtype_ietf_names, PA_SUBTYPE_IETF_TESTING, PA_SUBTYPE_IETF_NEA_CLIENT,
+ "Testing",
+ "Operating System",
+ "Anti-Virus",
+ "Anti-Spyware",
+ "Anti-Malware",
+ "Firewall",
+ "IDPS",
+ "VPN",
+ "NEA Client"
+);
+ENUM_NEXT(pa_subtype_ietf_names, PA_SUBTYPE_IETF_ANY, PA_SUBTYPE_IETF_ANY,
+ PA_SUBTYPE_IETF_NEA_CLIENT,
+ "ANY"
+);
+ENUM_END(pa_subtype_ietf_names, PA_SUBTYPE_IETF_ANY);
+
+ENUM_BEGIN(pa_subtype_tcg_names, PA_SUBTYPE_TCG_PTS, PA_SUBTYPE_TCG_PTS,
+ "PTS"
+);
+ENUM_NEXT(pa_subtype_tcg_names, PA_SUBTYPE_TCG_ANY, PA_SUBTYPE_TCG_ANY,
+ PA_SUBTYPE_TCG_PTS,
+ "ANY"
+);
+ENUM_END(pa_subtype_tcg_names, PA_SUBTYPE_TCG_ANY);
+
+ENUM_BEGIN(pa_subtype_fhh_names, PA_SUBTYPE_FHH_HOSTSCANNER, PA_SUBTYPE_FHH_DUMMY,
+ "HostScanner",
+ "Dummy"
+);
+ENUM_NEXT(pa_subtype_fhh_names, PA_SUBTYPE_FHH_PLATID, PA_SUBTYPE_FHH_ATTESTATION,
+ PA_SUBTYPE_FHH_DUMMY,
+ "PlatformID",
+ "Attestation"
+);
+ENUM_NEXT(pa_subtype_fhh_names, PA_SUBTYPE_FHH_CLAMAV, PA_SUBTYPE_FHH_CLAMAV,
+ PA_SUBTYPE_FHH_ATTESTATION,
+ "ClamAV"
+);
+ENUM_NEXT(pa_subtype_fhh_names, PA_SUBTYPE_FHH_ANY, PA_SUBTYPE_FHH_ANY,
+ PA_SUBTYPE_FHH_CLAMAV,
+ "ANY"
+);
+ENUM_END(pa_subtype_fhh_names, PA_SUBTYPE_FHH_ANY);
+
+ENUM_BEGIN(pa_subtype_ita_names, PA_SUBTYPE_ITA_TEST, PA_SUBTYPE_ITA_SCANNER,
+ "Test",
+ "Scanner"
+);
+ENUM_NEXT(pa_subtype_ita_names, PA_SUBTYPE_ITA_ANY, PA_SUBTYPE_ITA_ANY,
+ PA_SUBTYPE_ITA_SCANNER,
+ "ANY"
+);
+ENUM_END(pa_subtype_ita_names, PA_SUBTYPE_ITA_ANY);
+
+/**
+ * See header
+ */
+enum_name_t* get_pa_subtype_names(pen_t pen)
+{
+ switch (pen)
+ {
+ case PEN_IETF:
+ return pa_subtype_ietf_names;
+ case PEN_TCG:
+ return pa_subtype_tcg_names;
+ case PEN_FHH:
+ return pa_subtype_fhh_names;
+ case PEN_ITA:
+ return pa_subtype_ita_names;
+ default:
+ break;
+ }
+ return NULL;
+}
diff --git a/src/libtncif/tncif_pa_subtypes.h b/src/libtncif/tncif_pa_subtypes.h
new file mode 100644
index 000000000..0be495bfc
--- /dev/null
+++ b/src/libtncif/tncif_pa_subtypes.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2011 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 tncif_pa_subtypes tncif_pa_subtypes
+ * @{ @ingroup libtncif
+ */
+
+#ifndef TNCIF_PA_SUBTYPES_H_
+#define TNCIF_PA_SUBTYPES_H_
+
+typedef enum pa_subtype_ietf_t pa_subtype_ietf_t;
+typedef enum pa_subtype_tcg_t pa_subtype_tcg_t;
+typedef enum pa_subtype_fhh_t pa_subtype_fhh_t;
+typedef enum pa_subtype_ita_t pa_subtype_ita_t;
+
+#include <library.h>
+#include <pen/pen.h>
+
+/**
+ * PA-TNC IETF Standard Subtypes as defined in section 3.5 of RFC 5792
+ */
+ enum pa_subtype_ietf_t {
+ PA_SUBTYPE_IETF_TESTING = 0x00,
+ PA_SUBTYPE_IETF_OPERATING_SYSTEM = 0x01,
+ PA_SUBTYPE_IETF_ANTI_VIRUS = 0x02,
+ PA_SUBTYPE_IETF_ANTI_SPYWARE = 0x03,
+ PA_SUBTYPE_IETF_ANTI_MALWARE = 0x04,
+ PA_SUBTYPE_IETF_FIREWALL = 0x05,
+ PA_SUBTYPE_IETF_IDPS = 0x06,
+ PA_SUBTYPE_IETF_VPN = 0x07,
+ PA_SUBTYPE_IETF_NEA_CLIENT = 0x08,
+ PA_SUBTYPE_IETF_ANY = 0xff
+};
+
+/**
+ * enum name for pa_subtype_ietf_t.
+ */
+extern enum_name_t *pa_subtype_ietf_names;
+
+/**
+ * PA-TNC TCG Subtypes
+ */
+ enum pa_subtype_tcg_t {
+ PA_SUBTYPE_TCG_PTS = 0x01,
+ PA_SUBTYPE_TCG_ANY = 0xff
+};
+
+/**
+ * enum name for pa_subtype_tcg_t.
+ */
+extern enum_name_t *pa_subtype_tcg_names;
+
+/**
+ * PA-TNC FHH Subtypes
+ */
+ enum pa_subtype_fhh_t {
+ PA_SUBTYPE_FHH_HOSTSCANNER = 0x30,
+ PA_SUBTYPE_FHH_DUMMY = 0x31,
+ PA_SUBTYPE_FHH_PLATID = 0x33,
+ PA_SUBTYPE_FHH_ATTESTATION = 0x34,
+ PA_SUBTYPE_FHH_CLAMAV = 0x41,
+ PA_SUBTYPE_FHH_ANY = 0xff
+};
+
+/**
+ * enum name for pa_subtype_fhh_t.
+ */
+extern enum_name_t *pa_subtype_fhh_names;
+
+/**
+ * PA-TNC ITA-HSR Subtypes
+ */
+ enum pa_subtype_ita_t {
+ PA_SUBTYPE_ITA_TEST = 0x01,
+ PA_SUBTYPE_ITA_SCANNER = 0x02,
+ PA_SUBTYPE_ITA_ANY = 0xff
+};
+
+/**
+ * enum name for pa_subtype_ita_t.
+ */
+extern enum_name_t *pa_subtype_ita_names;
+
+/**
+ * Return the pa_subtype_names for a given PEN
+ *
+ * @param pen Private Enterprise Number (PEN)
+ * @return pa_subtype_names if found, NULL else
+ */
+extern enum_name_t* get_pa_subtype_names(pen_t pen);
+
+#endif /** TNCIF_PA_SUBTYPES_H_ @}*/
diff --git a/src/libcharon/tnc/tncifimc.h b/src/libtncif/tncifimc.h
index c6ddabd45..45af913df 100644
--- a/src/libcharon/tnc/tncifimc.h
+++ b/src/libtncif/tncifimc.h
@@ -1,22 +1,22 @@
/* tncifimc.h
*
- * Trusted Network Connect IF-IMC API version 1.20 Revision 8
+ * Trusted Network Connect IF-IMC API version 1.30
* Microsoft Windows DLL Platform Binding C Header
- * February 5, 2007
+ * October 14, 2011
*
- * Copyright(c) 2005-2007, Trusted Computing Group, Inc. All rights
+ * Copyright(c) 2005-2011, Trusted Computing Group, Inc. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * o Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
+ * o Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
- * - Neither the name of the Trusted Computing Group nor the names of
+ * o Neither the name of the Trusted Computing Group nor the names of
* its contributors may be used to endorse or promote products
* derived from this software without specific prior written
* permission.
@@ -45,7 +45,7 @@
/**
* @defgroup tncifimc tncifimc
- * @{ @ingroup tnc
+ * @{ @ingroup libtncif
*/
#ifndef TNCIFIMC_H_
@@ -53,6 +53,16 @@
#include "tncif.h"
+#ifdef WIN32
+#ifdef TNC_IMC_EXPORTS
+#define TNC_IMC_API __declspec(dllexport)
+#else
+#define TNC_IMC_API __declspec(dllimport)
+#endif
+#else
+#define TNC_IMC_API
+#endif
+
/* Derived Types */
typedef TNC_UInt32 TNC_IMCID;
@@ -77,6 +87,22 @@ typedef TNC_Result (*TNC_IMC_ReceiveMessagePointer)(
TNC_BufferReference message,
TNC_UInt32 messageLength,
TNC_MessageType messageType);
+typedef TNC_Result (*TNC_IMC_ReceiveMessageSOHPointer)(
+ TNC_IMCID imcID,
+ TNC_ConnectionID connectionID,
+ TNC_BufferReference sohrReportEntry,
+ TNC_UInt32 sohrRELength,
+ TNC_MessageType systemHealthID);
+typedef TNC_Result (*TNC_IMC_ReceiveMessageLongPointer)(
+ TNC_IMCID imcID,
+ TNC_ConnectionID connectionID,
+ TNC_UInt32 messageFlags,
+ TNC_BufferReference message,
+ TNC_UInt32 messageLength,
+ TNC_VendorID messageVendorID,
+ TNC_MessageSubtype messageSubtype,
+ TNC_UInt32 sourceIMVID,
+ TNC_UInt32 destinationIMCID);
typedef TNC_Result (*TNC_IMC_BatchEndingPointer)(
TNC_IMCID imcID,
TNC_ConnectionID connectionID);
@@ -86,16 +112,51 @@ typedef TNC_Result (*TNC_TNCC_ReportMessageTypesPointer)(
TNC_IMCID imcID,
TNC_MessageTypeList supportedTypes,
TNC_UInt32 typeCount);
+typedef TNC_Result (*TNC_TNCC_ReportMessageTypesLongPointer)(
+ TNC_IMCID imcID,
+ TNC_VendorIDList supportedVendorIDs,
+ TNC_MessageSubtypeList supportedSubtypes,
+ TNC_UInt32 typeCount);
typedef TNC_Result (*TNC_TNCC_SendMessagePointer)(
TNC_IMCID imcID,
TNC_ConnectionID connectionID,
TNC_BufferReference message,
TNC_UInt32 messageLength,
TNC_MessageType messageType);
+typedef TNC_Result (*TNC_TNCC_SendMessageSOHPointer)(
+ TNC_IMCID imcID,
+ TNC_ConnectionID connectionID,
+ TNC_BufferReference sohReportEntry,
+ TNC_UInt32 sohRELength);
+typedef TNC_Result (*TNC_TNCC_SendMessageLongPointer)(
+ TNC_IMCID imcID,
+ TNC_ConnectionID connectionID,
+ TNC_UInt32 messageFlags,
+ TNC_BufferReference message,
+ TNC_UInt32 messageLength,
+ TNC_VendorID messageVendorID,
+ TNC_MessageSubtype messageSubtype,
+ TNC_UInt32 destinationIMVID);
typedef TNC_Result (*TNC_TNCC_RequestHandshakeRetryPointer)(
TNC_IMCID imcID,
TNC_ConnectionID connectionID,
TNC_RetryReason reason);
+typedef TNC_Result (*TNC_TNCC_GetAttributePointer)(
+ TNC_IMCID imcID,
+ TNC_ConnectionID connectionID,
+ TNC_AttributeID attributeID,
+ TNC_UInt32 bufferLength,
+ TNC_BufferReference buffer,
+ TNC_UInt32 *pOutValueLength);
+typedef TNC_Result (*TNC_TNCC_SetAttributePointer)(
+ TNC_IMCID imcID,
+ TNC_ConnectionID connectionID,
+ TNC_AttributeID attributeID,
+ TNC_UInt32 bufferLength,
+ TNC_BufferReference buffer);
+typedef TNC_Result (*TNC_TNCC_ReserveAdditionalIMCIDPointer)(
+ TNC_IMCID imcID,
+ TNC_UInt32 *pOutIMCID);
typedef TNC_Result (*TNC_TNCC_BindFunctionPointer)(
TNC_IMCID imcID,
char *functionName,
@@ -104,6 +165,8 @@ typedef TNC_Result (*TNC_IMC_ProvideBindFunctionPointer)(
TNC_IMCID imcID,
TNC_TNCC_BindFunctionPointer bindFunction);
+/* Version Numbers */
+
#define TNC_IFIMC_VERSION_1 1
/* Handshake Retry Reason Values */
@@ -118,38 +181,62 @@ typedef TNC_Result (*TNC_IMC_ProvideBindFunctionPointer)(
/* reserved for TNC_RETRY_REASON_IMV_MINOR_EVENT: 7 */
/* reserved for TNC_RETRY_REASON_IMV_PERIODIC: 8 */
+/* Message Attribute ID Values */
+
+#define TNC_ATTRIBUTEID_SOHR ((TNC_AttributeID) 0x00559708)
+#define TNC_ATTRIBUTEID_SSOHR ((TNC_AttributeID) 0x00559709)
+#define TNC_ATTRIBUTEID_PRIMARY_IMC_ID ((TNC_AttributeID) 0x00559711)
+
/* IMC Functions */
-TNC_Result TNC_IMC_Initialize(
+TNC_IMC_API TNC_Result TNC_IMC_Initialize(
/*in*/ TNC_IMCID imcID,
/*in*/ TNC_Version minVersion,
/*in*/ TNC_Version maxVersion,
/*out*/ TNC_Version *pOutActualVersion);
-TNC_Result TNC_IMC_NotifyConnectionChange(
+TNC_IMC_API TNC_Result TNC_IMC_NotifyConnectionChange(
/*in*/ TNC_IMCID imcID,
/*in*/ TNC_ConnectionID connectionID,
/*in*/ TNC_ConnectionState newState);
-TNC_Result TNC_IMC_BeginHandshake(
+TNC_IMC_API TNC_Result TNC_IMC_BeginHandshake(
/*in*/ TNC_IMCID imcID,
/*in*/ TNC_ConnectionID connectionID);
-TNC_Result TNC_IMC_ReceiveMessage(
+TNC_IMC_API TNC_Result TNC_IMC_ReceiveMessage(
/*in*/ TNC_IMCID imcID,
/*in*/ TNC_ConnectionID connectionID,
/*in*/ TNC_BufferReference messageBuffer,
/*in*/ TNC_UInt32 messageLength,
/*in*/ TNC_MessageType messageType);
-TNC_Result TNC_IMC_BatchEnding(
+TNC_IMC_API TNC_Result TNC_IMC_ReceiveMessageSOH(
+/*in*/ TNC_IMCID imcID,
+/*in*/ TNC_ConnectionID connectionID,
+/*in*/ TNC_BufferReference sohrReportEntry,
+/*in*/ TNC_UInt32 sohrRELength,
+/*in*/ TNC_MessageType systemHealthID);
+
+TNC_IMC_API TNC_Result TNC_IMC_ReceiveMessageLong(
+/*in*/ TNC_IMCID imcID,
+/*in*/ TNC_ConnectionID connectionID,
+/*in*/ TNC_UInt32 messageFlags,
+/*in*/ TNC_BufferReference message,
+/*in*/ TNC_UInt32 messageLength,
+/*in*/ TNC_VendorID messageVendorID,
+/*in*/ TNC_MessageSubtype messageSubtype,
+/*in*/ TNC_UInt32 sourceIMVID,
+/*in*/ TNC_UInt32 destinationIMCID);
+
+TNC_IMC_API TNC_Result TNC_IMC_BatchEnding(
/*in*/ TNC_IMCID imcID,
/*in*/ TNC_ConnectionID connectionID);
-TNC_Result TNC_IMC_Terminate(
+TNC_IMC_API TNC_Result TNC_IMC_Terminate(
/*in*/ TNC_IMCID imcID);
-TNC_Result TNC_IMC_ProvideBindFunction(
+TNC_IMC_API TNC_Result TNC_IMC_ProvideBindFunction(
/*in*/ TNC_IMCID imcID,
/*in*/ TNC_TNCC_BindFunctionPointer bindFunction);
@@ -160,6 +247,12 @@ TNC_Result TNC_TNCC_ReportMessageTypes(
/*in*/ TNC_MessageTypeList supportedTypes,
/*in*/ TNC_UInt32 typeCount);
+TNC_Result TNC_TNCC_ReportMessageTypesLong(
+/*in*/ TNC_IMCID imcID,
+/*in*/ TNC_VendorIDList supportedVendorIDs,
+/*in*/ TNC_MessageSubtypeList supportedSubtypes,
+/*in*/ TNC_UInt32 typeCount);
+
TNC_Result TNC_TNCC_SendMessage(
/*in*/ TNC_IMCID imcID,
/*in*/ TNC_ConnectionID connectionID,
@@ -167,11 +260,45 @@ TNC_Result TNC_TNCC_SendMessage(
/*in*/ TNC_UInt32 messageLength,
/*in*/ TNC_MessageType messageType);
+TNC_Result TNC_TNCC_SendMessageSOH(
+/*in*/ TNC_IMCID imcID,
+/*in*/ TNC_ConnectionID connectionID,
+/*in*/ TNC_BufferReference sohReportEntry,
+/*in*/ TNC_UInt32 sohRELength);
+
+TNC_Result TNC_TNCC_SendMessageLong(
+/*in*/ TNC_IMCID imcID,
+/*in*/ TNC_ConnectionID connectionID,
+/*in*/ TNC_UInt32 messageFlags,
+/*in*/ TNC_BufferReference message,
+/*in*/ TNC_UInt32 messageLength,
+/*in*/ TNC_VendorID messageVendorID,
+/*in*/ TNC_MessageSubtype messageSubtype,
+/*in*/ TNC_UInt32 destinationIMVID);
TNC_Result TNC_TNCC_RequestHandshakeRetry(
/*in*/ TNC_IMCID imcID,
/*in*/ TNC_ConnectionID connectionID,
/*in*/ TNC_RetryReason reason);
+TNC_Result TNC_TNCC_GetAttribute(
+/*in*/ TNC_IMCID imcID,
+/*in*/ TNC_ConnectionID connectionID,
+/*in*/ TNC_AttributeID attributeID,
+/*in*/ TNC_UInt32 bufferLength,
+/*out*/ TNC_BufferReference buffer,
+/*out*/ TNC_UInt32 *pOutValueLength);
+
+TNC_Result TNC_TNCC_SetAttribute(
+/*in*/ TNC_IMCID imcID,
+/*in*/ TNC_ConnectionID connectionID,
+/*in*/ TNC_AttributeID attributeID,
+/*in*/ TNC_UInt32 bufferLength,
+/*in*/ TNC_BufferReference buffer);
+
+TNC_Result TNC_TNCS_ReserveAdditionalIMCID(
+/*in*/ TNC_IMCID imcID,
+/*out*/ TNC_UInt32 *pOutIMCID);
+
TNC_Result TNC_TNCC_BindFunction(
/*in*/ TNC_IMCID imcID,
/*in*/ char *functionName,
diff --git a/src/libcharon/tnc/tncifimv.h b/src/libtncif/tncifimv.h
index 4ec101337..3c9db0055 100644
--- a/src/libcharon/tnc/tncifimv.h
+++ b/src/libtncif/tncifimv.h
@@ -1,22 +1,22 @@
/* tncifimv.h
*
- * Trusted Network Connect IF-IMV API version 1.20
+ * Trusted Network Connect IF-IMV API version 1.30
* Microsoft Windows DLL Platform Binding C Header
- * February 5, 2007
+ * October 14, 2011
*
- * Copyright(c) 2005-2007, Trusted Computing Group, Inc. All rights
+ * Copyright(c) 2005-2011, Trusted Computing Group, Inc. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * o Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
+ * o Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
- * - Neither the name of the Trusted Computing Group nor the names of
+ * o Neither the name of the Trusted Computing Group nor the names of
* its contributors may be used to endorse or promote products
* derived from this software without specific prior written
* permission.
@@ -44,7 +44,7 @@
/**
* @defgroup tncifimv tncifimv
- * @{ @ingroup tnc
+ * @{ @ingroup libtncif
*/
#ifndef TNCIFIMV_H_
@@ -52,77 +52,124 @@
#include "tncif.h"
-#include <library.h>
+#ifdef WIN32
+#ifdef TNC_IMV_EXPORTS
+#define TNC_IMV_API __declspec(dllexport)
+#else
+#define TNC_IMV_API __declspec(dllimport)
+#endif
+#else
+#define TNC_IMV_API
+#endif
+
+/* Derived Types */
typedef TNC_UInt32 TNC_IMVID;
typedef TNC_UInt32 TNC_IMV_Action_Recommendation;
typedef TNC_UInt32 TNC_IMV_Evaluation_Result;
-typedef TNC_UInt32 TNC_AttributeID;
/* Function pointers */
typedef TNC_Result (*TNC_IMV_InitializePointer)(
- TNC_IMVID imvID,
- TNC_Version minVersion,
- TNC_Version maxVersion,
- TNC_Version *pOutActualVersion);
+ TNC_IMVID imvID,
+ TNC_Version minVersion,
+ TNC_Version maxVersion,
+ TNC_Version *pOutActualVersion);
typedef TNC_Result (*TNC_IMV_NotifyConnectionChangePointer)(
- TNC_IMVID imvID,
- TNC_ConnectionID connectionID,
- TNC_ConnectionState newState);
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID,
+ TNC_ConnectionState newState);
typedef TNC_Result (*TNC_IMV_ReceiveMessagePointer)(
- TNC_IMVID imvID,
- TNC_ConnectionID connectionID,
- TNC_BufferReference message,
- TNC_UInt32 messageLength,
- TNC_MessageType messageType);
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID,
+ TNC_BufferReference message,
+ TNC_UInt32 messageLength,
+ TNC_MessageType messageType);
+typedef TNC_Result (*TNC_IMV_ReceiveMessageSOHPointer)(
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID,
+ TNC_BufferReference sohReportEntry,
+ TNC_UInt32 sohRELength,
+ TNC_MessageType systemHealthID);
+typedef TNC_Result (*TNC_IMV_ReceiveMessageLongPointer)(
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID,
+ TNC_UInt32 messageFlags,
+ TNC_BufferReference message,
+ TNC_UInt32 messageLength,
+ TNC_VendorID messageVendorID,
+ TNC_MessageSubtype messageSubtype,
+ TNC_UInt32 sourceIMCID,
+ TNC_UInt32 destinationIMVID);
typedef TNC_Result (*TNC_IMV_SolicitRecommendationPointer)(
- TNC_IMVID imvID,
- TNC_ConnectionID connectionID);
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID);
typedef TNC_Result (*TNC_IMV_BatchEndingPointer)(
- TNC_IMVID imvID,
- TNC_ConnectionID connectionID);
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID);
typedef TNC_Result (*TNC_IMV_TerminatePointer)(
- TNC_IMVID imvID);
+ TNC_IMVID imvID);
typedef TNC_Result (*TNC_TNCS_ReportMessageTypesPointer)(
- TNC_IMVID imvID,
- TNC_MessageTypeList supportedTypes,
- TNC_UInt32 typeCount);
+ TNC_IMVID imvID,
+ TNC_MessageTypeList supportedTypes,
+ TNC_UInt32 typeCount);
+typedef TNC_Result (*TNC_TNCS_ReportMessageTypesLongPointer)(
+ TNC_IMVID imvID,
+ TNC_VendorIDList supportedVendorIDs,
+ TNC_MessageSubtypeList supportedSubtypes,
+ TNC_UInt32 typeCount);
typedef TNC_Result (*TNC_TNCS_SendMessagePointer)(
- TNC_IMVID imvID,
- TNC_ConnectionID connectionID,
- TNC_BufferReference message,
- TNC_UInt32 messageLength,
- TNC_MessageType messageType);
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID,
+ TNC_BufferReference message,
+ TNC_UInt32 messageLength,
+ TNC_MessageType messageType);
+typedef TNC_Result (*TNC_TNCS_SendMessageSOHPointer)(
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID,
+ TNC_BufferReference sohrReportEntry,
+ TNC_UInt32 sohrRELength);
+typedef TNC_Result (*TNC_TNCS_SendMessageLongPointer)(
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID,
+ TNC_UInt32 messageFlags,
+ TNC_BufferReference message,
+ TNC_UInt32 messageLength,
+ TNC_VendorID messageVendorID,
+ TNC_MessageSubtype messageSubtype,
+ TNC_UInt32 destinationIMCID);
typedef TNC_Result (*TNC_TNCS_RequestHandshakeRetryPointer)(
- TNC_IMVID imvID,
- TNC_ConnectionID connectionID,
- TNC_RetryReason reason);
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID,
+ TNC_RetryReason reason);
typedef TNC_Result (*TNC_TNCS_ProvideRecommendationPointer)(
- TNC_IMVID imvID,
- TNC_ConnectionID connectionID,
- TNC_IMV_Action_Recommendation recommendation,
- TNC_IMV_Evaluation_Result evaluation);
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID,
+ TNC_IMV_Action_Recommendation recommendation,
+ TNC_IMV_Evaluation_Result evaluation);
typedef TNC_Result (*TNC_TNCS_GetAttributePointer)(
- TNC_IMVID imvID,
-TNC_ConnectionID connectionID,
-TNC_AttributeID attributeID,
- TNC_UInt32 bufferLength,
- TNC_BufferReference buffer,
- TNC_UInt32 *pOutValueLength);
-typedef TNC_Result (*TNC_TNCS_SetAttributePointer)(
- TNC_IMVID imvID,
+ TNC_IMVID imvID,
TNC_ConnectionID connectionID,
-TNC_AttributeID attributeID,
- TNC_UInt32 bufferLength,
- TNC_BufferReference buffer);
+ TNC_AttributeID attributeID,
+ TNC_UInt32 bufferLength,
+ TNC_BufferReference buffer,
+ TNC_UInt32 *pOutValueLength);
+typedef TNC_Result (*TNC_TNCS_SetAttributePointer)(
+ TNC_IMVID imvID,
+ TNC_ConnectionID connectionID,
+ TNC_AttributeID attributeID,
+ TNC_UInt32 bufferLength,
+ TNC_BufferReference buffer);
+typedef TNC_Result (*TNC_TNCS_ReserveAdditionalIMVIDPointer)(
+ TNC_IMVID imvID,
+ TNC_UInt32 *pOutIMVID);
typedef TNC_Result (*TNC_TNCS_BindFunctionPointer)(
- TNC_IMVID imvID,
- char *functionName,
- void **pOutfunctionPointer);
+ TNC_IMVID imvID,
+ char *functionName,
+ void **pOutfunctionPointer);
typedef TNC_Result (*TNC_IMV_ProvideBindFunctionPointer)(
- TNC_IMVID imvID,
- TNC_TNCS_BindFunctionPointer bindFunction);
+ TNC_IMVID imvID,
+ TNC_TNCS_BindFunctionPointer bindFunction);
/* Version Numbers */
@@ -147,8 +194,6 @@ typedef TNC_Result (*TNC_IMV_ProvideBindFunctionPointer)(
#define TNC_IMV_ACTION_RECOMMENDATION_ISOLATE 2
#define TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION 3
-extern enum_name_t *TNC_IMV_Action_Recommendation_names;
-
/* IMV Evaluation Result Values */
#define TNC_IMV_EVALUATION_RESULT_COMPLIANT 0
@@ -157,46 +202,64 @@ extern enum_name_t *TNC_IMV_Action_Recommendation_names;
#define TNC_IMV_EVALUATION_RESULT_ERROR 3
#define TNC_IMV_EVALUATION_RESULT_DONT_KNOW 4
-extern enum_name_t *TNC_IMV_Evaluation_Result_names;
-
/* Message Attribute ID Values */
-#define TNC_ATTRIBUTEID_PREFERRED_LANGUAGE ((TNC_AttributeID) 0x00000001)
#define TNC_ATTRIBUTEID_REASON_STRING ((TNC_AttributeID) 0x00000002)
#define TNC_ATTRIBUTEID_REASON_LANGUAGE ((TNC_AttributeID) 0x00000003)
+#define TNC_ATTRIBUTEID_SOH ((TNC_AttributeID) 0x00559706)
+#define TNC_ATTRIBUTEID_SSOH ((TNC_AttributeID) 0x00559707)
+#define TNC_ATTRIBUTEID_PRIMARY_IMV_ID ((TNC_AttributeID) 0x00559710)
/* IMV Functions */
-TNC_Result TNC_IMV_Initialize(
+TNC_IMV_API TNC_Result TNC_IMV_Initialize(
/*in*/ TNC_IMVID imvID,
/*in*/ TNC_Version minVersion,
/*in*/ TNC_Version maxVersion,
/*in*/ TNC_Version *pOutActualVersion);
-TNC_Result TNC_IMV_NotifyConnectionChange(
+TNC_IMV_API TNC_Result TNC_IMV_NotifyConnectionChange(
/*in*/ TNC_IMVID imvID,
/*in*/ TNC_ConnectionID connectionID,
/*in*/ TNC_ConnectionState newState);
-TNC_Result TNC_IMV_ReceiveMessage(
+TNC_IMV_API TNC_Result TNC_IMV_ReceiveMessage(
/*in*/ TNC_IMVID imvID,
/*in*/ TNC_ConnectionID connectionID,
/*in*/ TNC_BufferReference messageBuffer,
/*in*/ TNC_UInt32 messageLength,
/*in*/ TNC_MessageType messageType);
-TNC_Result TNC_IMV_SolicitRecommendation(
+TNC_IMV_API TNC_Result TNC_IMV_ReceiveMessageSOH(
+/*in*/ TNC_IMVID imvID,
+/*in*/ TNC_ConnectionID connectionID,
+/*in*/ TNC_BufferReference sohReportEntry,
+/*in*/ TNC_UInt32 sohRELength,
+/*in*/ TNC_MessageType systemHealthID);
+
+TNC_IMV_API TNC_Result TNC_IMV_ReceiveMessageLong(
+/*in*/ TNC_IMVID imvID,
+/*in*/ TNC_ConnectionID connectionID,
+/*in*/ TNC_UInt32 messageFlags,
+/*in*/ TNC_BufferReference message,
+/*in*/ TNC_UInt32 messageLength,
+/*in*/ TNC_VendorID messageVendorID,
+/*in*/ TNC_MessageSubtype messageSubtype,
+/*in*/ TNC_UInt32 sourceIMCID,
+/*in*/ TNC_UInt32 destinationIMVID);
+
+TNC_IMV_API TNC_Result TNC_IMV_SolicitRecommendation(
/*in*/ TNC_IMVID imvID,
/*in*/ TNC_ConnectionID connectionID);
-TNC_Result TNC_IMV_BatchEnding(
+TNC_IMV_API TNC_Result TNC_IMV_BatchEnding(
/*in*/ TNC_IMVID imvID,
/*in*/ TNC_ConnectionID connectionID);
-TNC_Result TNC_IMV_Terminate(
+TNC_IMV_API TNC_Result TNC_IMV_Terminate(
/*in*/ TNC_IMVID imvID);
-TNC_Result TNC_IMV_ProvideBindFunction(
+TNC_IMV_API TNC_Result TNC_IMV_ProvideBindFunction(
/*in*/ TNC_IMVID imvID,
/*in*/ TNC_TNCS_BindFunctionPointer bindFunction);
@@ -207,6 +270,12 @@ TNC_Result TNC_TNCS_ReportMessageTypes(
/*in*/ TNC_MessageTypeList supportedTypes,
/*in*/ TNC_UInt32 typeCount);
+TNC_Result TNC_TNCS_ReportMessageTypesLong(
+/*in*/ TNC_IMVID imvID,
+/*in*/ TNC_VendorIDList supportedVendorIDs,
+/*in*/ TNC_MessageSubtypeList supportedSubtypes,
+/*in*/ TNC_UInt32 typeCount);
+
TNC_Result TNC_TNCS_SendMessage(
/*in*/ TNC_IMVID imvID,
/*in*/ TNC_ConnectionID connectionID,
@@ -214,6 +283,22 @@ TNC_Result TNC_TNCS_SendMessage(
/*in*/ TNC_UInt32 messageLength,
/*in*/ TNC_MessageType messageType);
+TNC_Result TNC_TNCS_SendMessageSOH(
+/*in*/ TNC_IMVID imvID,
+/*in*/ TNC_ConnectionID connectionID,
+/*in*/ TNC_BufferReference sohrReportEntry,
+/*in*/ TNC_UInt32 sohrRELength);
+
+TNC_Result TNC_TNCS_SendMessageLong(
+/*in*/ TNC_IMVID imvID,
+/*in*/ TNC_ConnectionID connectionID,
+/*in*/ TNC_UInt32 messageFlags,
+/*in*/ TNC_BufferReference message,
+/*in*/ TNC_UInt32 messageLength,
+/*in*/ TNC_VendorID messageVendorID,
+/*in*/ TNC_MessageSubtype messageSubtype,
+/*in*/ TNC_UInt32 destinationIMCID);
+
TNC_Result TNC_TNCS_RequestHandshakeRetry(
/*in*/ TNC_IMVID imvID,
/*in*/ TNC_ConnectionID connectionID,
@@ -233,13 +318,16 @@ TNC_Result TNC_TNCS_GetAttribute(
/*out*/ TNC_BufferReference buffer,
/*out*/ TNC_UInt32 *pOutValueLength);
-TNC_Result TNC_TNCS_SetAttribute(
+TNC_Result TNC_TNCS_ReserveAdditionalIMVID(
/*in*/ TNC_IMVID imvID,
-/*in*/ TNC_ConnectionID connectionID,
-/*in*/ TNC_AttributeID attributeID,
-/*in*/ TNC_UInt32 bufferLength,
-/*in*/ TNC_BufferReference buffer);
+/*out*/ TNC_UInt32 *pOutIMVID);
+TNC_Result TNC_TNCS_SetAttribute(
+/*in*/ TNC_IMVID imvID,
+/*in*/ TNC_ConnectionID connectionID,
+/*in*/ TNC_AttributeID attributeID,
+/*in*/ TNC_UInt32 bufferLength,
+/*in*/ TNC_BufferReference buffer);
TNC_Result TNC_TNCS_BindFunction(
/*in*/ TNC_IMVID imvID,
/*in*/ char *functionName,
diff --git a/src/manager/Makefile.in b/src/manager/Makefile.in
index 4b9c0ebae..8ae5ebf36 100644
--- a/src/manager/Makefile.in
+++ b/src/manager/Makefile.in
@@ -208,6 +208,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -216,6 +219,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -232,11 +236,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -280,6 +286,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/manager/controller/auth_controller.c b/src/manager/controller/auth_controller.c
index dd469cee4..c9a9b5461 100644
--- a/src/manager/controller/auth_controller.c
+++ b/src/manager/controller/auth_controller.c
@@ -67,19 +67,15 @@ static void logout(private_auth_controller_t *this, request_t *request)
request->redirect(request, "auth/login");
}
-/**
- * Implementation of controller_t.get_name
- */
-static char* get_name(private_auth_controller_t *this)
+METHOD(controller_t, get_name, char*,
+ private_auth_controller_t *this)
{
return "auth";
}
-/**
- * Implementation of controller_t.handle
- */
-static void handle(private_auth_controller_t *this,
- request_t *request, char *action)
+METHOD(controller_t, handle, void,
+ private_auth_controller_t *this, request_t *request, char *action,
+ char *p2, char *p3, char *p4, char *p5)
{
if (action)
{
@@ -99,10 +95,8 @@ static void handle(private_auth_controller_t *this,
request->redirect(request, "auth/login");
}
-/**
- * Implementation of controller_t.destroy
- */
-static void destroy(private_auth_controller_t *this)
+METHOD(controller_t, destroy, void,
+ private_auth_controller_t *this)
{
free(this);
}
@@ -112,13 +106,18 @@ static void destroy(private_auth_controller_t *this)
*/
controller_t *auth_controller_create(context_t *context, void *param)
{
- private_auth_controller_t *this = malloc_thing(private_auth_controller_t);
-
- this->public.controller.get_name = (char*(*)(controller_t*))get_name;
- this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle;
- this->public.controller.destroy = (void(*)(controller_t*))destroy;
-
- this->manager = (manager_t*)context;
+ private_auth_controller_t *this;
+
+ INIT(this,
+ .public = {
+ .controller = {
+ .get_name = _get_name,
+ .handle = _handle,
+ .destroy = _destroy,
+ },
+ },
+ .manager = (manager_t*)context,
+ );
return &this->public.controller;
}
diff --git a/src/manager/controller/config_controller.c b/src/manager/controller/config_controller.c
index 828a4ac97..154ab615e 100644
--- a/src/manager/controller/config_controller.c
+++ b/src/manager/controller/config_controller.c
@@ -149,19 +149,15 @@ static void list(private_config_controller_t *this, request_t *r)
}
}
-/**
- * Implementation of controller_t.get_name
- */
-static char* get_name(private_config_controller_t *this)
+METHOD(controller_t, get_name, char*,
+ private_config_controller_t *this)
{
return "config";
}
-/**
- * Implementation of controller_t.handle
- */
-static void handle(private_config_controller_t *this,
- request_t *request, char *action)
+METHOD(controller_t, handle, void,
+ private_config_controller_t *this, request_t *request, char *action,
+ char *p2, char *p3, char *p4, char *p5)
{
if (!this->manager->logged_in(this->manager))
{
@@ -181,10 +177,8 @@ static void handle(private_config_controller_t *this,
return request->redirect(request, "config/list");
}
-/**
- * Implementation of controller_t.destroy
- */
-static void destroy(private_config_controller_t *this)
+METHOD(controller_t, destroy, void,
+ private_config_controller_t *this)
{
free(this);
}
@@ -194,13 +188,18 @@ static void destroy(private_config_controller_t *this)
*/
controller_t *config_controller_create(context_t *context, void *param)
{
- private_config_controller_t *this = malloc_thing(private_config_controller_t);
-
- this->public.controller.get_name = (char*(*)(controller_t*))get_name;
- this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle;
- this->public.controller.destroy = (void(*)(controller_t*))destroy;
-
- this->manager = (manager_t*)context;
+ private_config_controller_t *this;
+
+ INIT(this,
+ .public = {
+ .controller = {
+ .get_name = _get_name,
+ .handle = _handle,
+ .destroy = _destroy,
+ },
+ },
+ .manager = (manager_t*)context,
+ );
return &this->public.controller;
}
diff --git a/src/manager/controller/control_controller.c b/src/manager/controller/control_controller.c
index fdf66bf14..68238d02f 100644
--- a/src/manager/controller/control_controller.c
+++ b/src/manager/controller/control_controller.c
@@ -120,19 +120,15 @@ static void terminate(private_control_controller_t *this, request_t *r,
handle_result(this, r, e);
}
-/**
- * Implementation of controller_t.get_name
- */
-static char* get_name(private_control_controller_t *this)
+METHOD(controller_t, get_name, char*,
+ private_control_controller_t *this)
{
return "control";
}
-/**
- * Implementation of controller_t.handle
- */
-static void handle(private_control_controller_t *this,
- request_t *request, char *action, char *str)
+METHOD(controller_t, handle, void,
+ private_control_controller_t *this, request_t *request, char *action,
+ char *str, char *p3, char *p4, char *p5)
{
if (!this->manager->logged_in(this->manager))
{
@@ -178,10 +174,8 @@ static void handle(private_control_controller_t *this,
return request->redirect(request, "ikesa/list");
}
-/**
- * Implementation of controller_t.destroy
- */
-static void destroy(private_control_controller_t *this)
+METHOD(controller_t, destroy, void,
+ private_control_controller_t *this)
{
free(this);
}
@@ -191,13 +185,18 @@ static void destroy(private_control_controller_t *this)
*/
controller_t *control_controller_create(context_t *context, void *param)
{
- private_control_controller_t *this = malloc_thing(private_control_controller_t);
-
- this->public.controller.get_name = (char*(*)(controller_t*))get_name;
- this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle;
- this->public.controller.destroy = (void(*)(controller_t*))destroy;
-
- this->manager = (manager_t*)context;
+ private_control_controller_t *this;
+
+ INIT(this,
+ .public = {
+ .controller = {
+ .get_name = _get_name,
+ .handle = _handle,
+ .destroy = _destroy,
+ },
+ },
+ .manager = (manager_t*)context,
+ );
return &this->public.controller;
}
diff --git a/src/manager/controller/gateway_controller.c b/src/manager/controller/gateway_controller.c
index 9fca220e9..39d344502 100644
--- a/src/manager/controller/gateway_controller.c
+++ b/src/manager/controller/gateway_controller.c
@@ -82,19 +82,15 @@ static void _select(private_gateway_controller_t *this, request_t *request)
request->redirect(request, "gateway/list");
}
-/**
- * Implementation of controller_t.get_name
- */
-static char* get_name(private_gateway_controller_t *this)
+METHOD(controller_t, get_name, char*,
+ private_gateway_controller_t *this)
{
return "gateway";
}
-/**
- * Implementation of controller_t.handle
- */
-static void handle(private_gateway_controller_t *this,
- request_t *request, char *action)
+METHOD(controller_t, handle, void,
+ private_gateway_controller_t *this, request_t *request, char *action,
+ char *p2, char *p3, char *p4, char *p5)
{
if (!this->manager->logged_in(this->manager))
{
@@ -114,11 +110,8 @@ static void handle(private_gateway_controller_t *this,
request->redirect(request, "gateway/list");
}
-
-/**
- * Implementation of controller_t.destroy
- */
-static void destroy(private_gateway_controller_t *this)
+METHOD(controller_t, destroy, void,
+ private_gateway_controller_t *this)
{
free(this);
}
@@ -128,13 +121,18 @@ static void destroy(private_gateway_controller_t *this)
*/
controller_t *gateway_controller_create(context_t *context, void *param)
{
- private_gateway_controller_t *this = malloc_thing(private_gateway_controller_t);
-
- this->public.controller.get_name = (char*(*)(controller_t*))get_name;
- this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle;
- this->public.controller.destroy = (void(*)(controller_t*))destroy;
-
- this->manager = (manager_t*)context;
+ private_gateway_controller_t *this;
+
+ INIT(this,
+ .public = {
+ .controller = {
+ .get_name = _get_name,
+ .handle = _handle,
+ .destroy = _destroy,
+ },
+ },
+ .manager = (manager_t*)context,
+ );
return &this->public.controller;
}
diff --git a/src/manager/controller/ikesa_controller.c b/src/manager/controller/ikesa_controller.c
index afa4a67f8..716d51a7a 100644
--- a/src/manager/controller/ikesa_controller.c
+++ b/src/manager/controller/ikesa_controller.c
@@ -173,19 +173,15 @@ static void list(private_ikesa_controller_t *this, request_t *r)
}
}
-/**
- * Implementation of controller_t.get_name
- */
-static char* get_name(private_ikesa_controller_t *this)
+METHOD(controller_t, get_name, char*,
+ private_ikesa_controller_t *this)
{
return "ikesa";
}
-/**
- * Implementation of controller_t.handle
- */
-static void handle(private_ikesa_controller_t *this,
- request_t *request, char *action)
+METHOD(controller_t, handle, void,
+ private_ikesa_controller_t *this, request_t *request, char *action,
+ char *p2, char *p3, char *p4, char *p5)
{
if (!this->manager->logged_in(this->manager))
{
@@ -205,10 +201,8 @@ static void handle(private_ikesa_controller_t *this,
return request->redirect(request, "ikesa/list");
}
-/**
- * Implementation of controller_t.destroy
- */
-static void destroy(private_ikesa_controller_t *this)
+METHOD(controller_t, destroy, void,
+ private_ikesa_controller_t *this)
{
free(this);
}
@@ -218,13 +212,18 @@ static void destroy(private_ikesa_controller_t *this)
*/
controller_t *ikesa_controller_create(context_t *context, void *param)
{
- private_ikesa_controller_t *this = malloc_thing(private_ikesa_controller_t);
-
- this->public.controller.get_name = (char*(*)(controller_t*))get_name;
- this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle;
- this->public.controller.destroy = (void(*)(controller_t*))destroy;
-
- this->manager = (manager_t*)context;
+ private_ikesa_controller_t *this;
+
+ INIT(this,
+ .public = {
+ .controller = {
+ .get_name = _get_name,
+ .handle = _handle,
+ .destroy = _destroy,
+ },
+ },
+ .manager = (manager_t*)context,
+ );
return &this->public.controller;
}
diff --git a/src/manager/gateway.c b/src/manager/gateway.c
index fd462afa7..8a8fbe895 100644
--- a/src/manager/gateway.c
+++ b/src/manager/gateway.c
@@ -98,10 +98,8 @@ static bool connect_(private_gateway_t *this)
return TRUE;
}
-/**
- * Implementation of gateway_t.request.
- */
-static char* request(private_gateway_t *this, char *xml, ...)
+METHOD(gateway_t, request, char*,
+ private_gateway_t *this, char *xml, ...)
{
if (this->fd < 0)
{
@@ -145,10 +143,8 @@ static char* request(private_gateway_t *this, char *xml, ...)
}
}
-/**
- * Implementation of gateway_t.query_ikesalist.
- */
-static enumerator_t* query_ikesalist(private_gateway_t *this)
+METHOD(gateway_t, query_ikesalist, enumerator_t*,
+ private_gateway_t *this)
{
char *str, *name, *value;
xml_t *xml;
@@ -202,11 +198,8 @@ static enumerator_t* query_ikesalist(private_gateway_t *this)
return NULL;
}
-
-/**
- * Implementation of gateway_t.query_configlist.
- */
-static enumerator_t* query_configlist(private_gateway_t *this)
+METHOD(gateway_t, query_configlist, enumerator_t*,
+ private_gateway_t *this)
{
char *str, *name, *value;
xml_t *xml;
@@ -302,10 +295,8 @@ static enumerator_t* read_result(private_gateway_t *this, char *res)
return NULL;
}
-/**
- * Implementation of gateway_t.initiate.
- */
-static enumerator_t* initiate(private_gateway_t *this, bool ike, char *name)
+METHOD(gateway_t, initiate, enumerator_t*,
+ private_gateway_t *this, bool ike, char *name)
{
char *str, *kind;
@@ -325,10 +316,8 @@ static enumerator_t* initiate(private_gateway_t *this, bool ike, char *name)
return read_result(this, str);
}
-/**
- * Implementation of gateway_t.terminate.
- */
-static enumerator_t* terminate(private_gateway_t *this, bool ike, u_int32_t id)
+METHOD(gateway_t, terminate, enumerator_t*,
+ private_gateway_t *this, bool ike, u_int32_t id)
{
char *str, *kind;
@@ -348,10 +337,8 @@ static enumerator_t* terminate(private_gateway_t *this, bool ike, u_int32_t id)
return read_result(this, str);
}
-/**
- * Implementation of gateway_t.destroy
- */
-static void destroy(private_gateway_t *this)
+METHOD(gateway_t, destroy, void,
+ private_gateway_t *this)
{
if (this->fd >= 0)
{
@@ -367,19 +354,21 @@ static void destroy(private_gateway_t *this)
*/
static private_gateway_t *gateway_create(char *name)
{
- private_gateway_t *this = malloc_thing(private_gateway_t);
-
- this->public.request = (char*(*)(gateway_t*, char *xml))request;
- this->public.query_ikesalist = (enumerator_t*(*)(gateway_t*))query_ikesalist;
- this->public.query_configlist = (enumerator_t*(*)(gateway_t*))query_configlist;
- this->public.initiate = (enumerator_t*(*)(gateway_t*, bool ike, char *name))initiate;
- this->public.terminate = (enumerator_t*(*)(gateway_t*, bool ike, u_int32_t id))terminate;
- this->public.destroy = (void(*)(gateway_t*))destroy;
-
- this->name = strdup(name);
- this->host = NULL;
- this->fd = -1;
- this->xmlid = 1;
+ private_gateway_t *this;
+
+ INIT(this,
+ .public = {
+ .request = _request,
+ .query_ikesalist = _query_ikesalist,
+ .query_configlist = _query_configlist,
+ .initiate = _initiate,
+ .terminate = _terminate,
+ .destroy = _destroy,
+ },
+ .name = strdup(name),
+ .fd = -1,
+ .xmlid = 1,
+ );
return this;
}
diff --git a/src/manager/gateway.h b/src/manager/gateway.h
index 54aade7b1..db44a2ffa 100644
--- a/src/manager/gateway.h
+++ b/src/manager/gateway.h
@@ -35,9 +35,10 @@ struct gateway_t {
* Send an XML request to the gateway.
*
* @param xml xml request string
+ * @param ... printf style argument list for xml request string
* @return allocated xml response string
*/
- char* (*request)(gateway_t *this, char *xml);
+ char* (*request)(gateway_t *this, char *xml, ...);
/**
* Query the list of IKE_SAs and all its children.
diff --git a/src/manager/manager.c b/src/manager/manager.c
index fb89c6b72..b6f3951c4 100644
--- a/src/manager/manager.c
+++ b/src/manager/manager.c
@@ -47,18 +47,14 @@ struct private_manager_t {
gateway_t *gateway;
};
-/**
- * Implementation of manager_t.create_gateway_enumerator.
- */
-static enumerator_t* create_gateway_enumerator(private_manager_t *this)
+METHOD(manager_t, create_gateway_enumerator, enumerator_t*,
+ private_manager_t *this)
{
return this->store->create_gateway_enumerator(this->store, this->user);
}
-/**
- * Implementation of manager_t.select_gateway.
- */
-static gateway_t* select_gateway(private_manager_t *this, int select_id)
+METHOD(manager_t, select_gateway, gateway_t*,
+ private_manager_t *this, int select_id)
{
if (select_id != 0)
{
@@ -95,18 +91,14 @@ static gateway_t* select_gateway(private_manager_t *this, int select_id)
return this->gateway;
}
-/**
- * Implementation of manager_t.logged_in.
- */
-static bool logged_in(private_manager_t *this)
+METHOD(manager_t, logged_in, bool,
+ private_manager_t *this)
{
return this->user != 0;
}
-/**
- * Implementation of manager_t.login.
- */
-static bool login(private_manager_t *this, char *username, char *password)
+METHOD(manager_t, login, bool,
+ private_manager_t *this, char *username, char *password)
{
if (!this->user)
{
@@ -115,10 +107,8 @@ static bool login(private_manager_t *this, char *username, char *password)
return this->user != 0;
}
-/**
- * Implementation of manager_t.logout.
- */
-static void logout(private_manager_t *this)
+METHOD(manager_t, logout, void,
+ private_manager_t *this)
{
if (this->gateway)
{
@@ -128,10 +118,8 @@ static void logout(private_manager_t *this)
this->user = 0;
}
-/**
- * Implementation of manager_t.destroy
- */
-static void destroy(private_manager_t *this)
+METHOD(context_t, destroy, void,
+ private_manager_t *this)
{
if (this->gateway) this->gateway->destroy(this->gateway);
free(this);
@@ -142,18 +130,21 @@ static void destroy(private_manager_t *this)
*/
manager_t *manager_create(storage_t *storage)
{
- private_manager_t *this = malloc_thing(private_manager_t);
-
- this->public.login = (bool(*)(manager_t*, char *username, char *password))login;
- this->public.logged_in = (bool(*)(manager_t*))logged_in;
- this->public.logout = (void(*)(manager_t*))logout;
- this->public.create_gateway_enumerator = (enumerator_t*(*)(manager_t*))create_gateway_enumerator;
- this->public.select_gateway = (gateway_t*(*)(manager_t*, int id))select_gateway;
- this->public.context.destroy = (void(*)(context_t*))destroy;
-
- this->user = 0;
- this->store = storage;
- this->gateway = NULL;
+ private_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .login = _login,
+ .logged_in = _logged_in,
+ .logout = _logout,
+ .create_gateway_enumerator = _create_gateway_enumerator,
+ .select_gateway = _select_gateway,
+ .context = {
+ .destroy = _destroy,
+ },
+ },
+ .store = storage,
+ );
return &this->public;
}
diff --git a/src/manager/manager.h b/src/manager/manager.h
index 231b0f5f3..f7620833a 100644
--- a/src/manager/manager.h
+++ b/src/manager/manager.h
@@ -31,8 +31,6 @@
#include <context.h>
-#include <utils/iterator.h>
-
typedef struct manager_t manager_t;
/**
@@ -46,7 +44,7 @@ struct manager_t {
context_t context;
/**
- * Create an iterator over all configured gateways.
+ * Create an enumerator over all configured gateways.
*
* enumerate() arguments: int id, char *name, int port, char *address
* If port is 0, address is a Unix socket address.
diff --git a/src/manager/storage.c b/src/manager/storage.c
index f7635ea71..5461a4288 100644
--- a/src/manager/storage.c
+++ b/src/manager/storage.c
@@ -37,10 +37,8 @@ struct private_storage_t {
database_t *db;
};
-/**
- * Implementation of storage_t.login.
- */
-static int login(private_storage_t *this, char *username, char *password)
+METHOD(storage_t, login, int,
+ private_storage_t *this, char *username, char *password)
{
hasher_t *hasher;
chunk_t hash, data, hex_str;
@@ -77,10 +75,8 @@ static int login(private_storage_t *this, char *username, char *password)
return uid;
}
-/**
- * Implementation of storage_t.create_gateway_enumerator.
- */
-static enumerator_t* create_gateway_enumerator(private_storage_t *this, int user)
+METHOD(storage_t, create_gateway_enumerator, enumerator_t*,
+ private_storage_t *this, int user)
{
enumerator_t *enumerator;
@@ -96,10 +92,8 @@ static enumerator_t* create_gateway_enumerator(private_storage_t *this, int user
return enumerator;
}
-/**
- * Implementation of storage_t.destroy
- */
-static void destroy(private_storage_t *this)
+METHOD(storage_t, destroy, void,
+ private_storage_t *this)
{
this->db->destroy(this->db);
free(this);
@@ -110,13 +104,16 @@ static void destroy(private_storage_t *this)
*/
storage_t *storage_create(char *uri)
{
- private_storage_t *this = malloc_thing(private_storage_t);
-
- this->public.login = (int(*)(storage_t*, char *username, char *password))login;
- this->public.create_gateway_enumerator = (enumerator_t*(*)(storage_t*,int))create_gateway_enumerator;
- this->public.destroy = (void(*)(storage_t*))destroy;
-
- this->db = lib->db->create(lib->db, uri);
+ private_storage_t *this;
+
+ INIT(this,
+ .public = {
+ .login = _login,
+ .create_gateway_enumerator = _create_gateway_enumerator,
+ .destroy = _destroy,
+ },
+ .db = lib->db->create(lib->db, uri),
+ );
if (this->db == NULL)
{
free(this);
diff --git a/src/manager/storage.h b/src/manager/storage.h
index d8e8b7479..69459e5aa 100644
--- a/src/manager/storage.h
+++ b/src/manager/storage.h
@@ -41,7 +41,7 @@ struct storage_t {
int (*login)(storage_t *this, char *username, char *password);
/**
- * Create an iterator over the gateways.
+ * Create an enumerator over the gateways.
*
* enumerate() arguments: int id, char *name, int port, char *address
* If port is 0, address is a Unix socket address.
diff --git a/src/manager/templates/static/jquery.js b/src/manager/templates/static/jquery.js
index 0728760b5..7cb68d02f 100644
--- a/src/manager/templates/static/jquery.js
+++ b/src/manager/templates/static/jquery.js
@@ -2110,7 +2110,7 @@ var jsc = (new Date).getTime();
jQuery.extend({
get: function( url, data, callback, type ) {
- // shift arguments if data argument was ommited
+ // shift arguments if data argument was omitted
if ( jQuery.isFunction( data ) ) {
callback = data;
data = null;
diff --git a/src/manager/xml.c b/src/manager/xml.c
index a9ef60c24..bf5bbbf05 100644
--- a/src/manager/xml.c
+++ b/src/manager/xml.c
@@ -66,11 +66,8 @@ typedef struct {
xmlNode *node;
} child_enum_t;
-/**
- * Implementation of xml_t.children().enumerate().
- */
-static bool child_enumerate(child_enum_t *e, private_xml_t **child,
- char **name, char **value)
+METHOD(enumerator_t, child_enumerate, bool,
+ child_enum_t *e, private_xml_t **child, char **name, char **value)
{
while (e->node && e->node->type != XML_ELEMENT_NODE)
{
@@ -100,18 +97,14 @@ static bool child_enumerate(child_enum_t *e, private_xml_t **child,
return FALSE;
}
-/**
- * Implementation of xml_t.get_attribute.
- */
-static char* get_attribute(private_xml_t *this, char *name)
+METHOD(xml_t, get_attribute, char*,
+ private_xml_t *this, char *name)
{
return NULL;
}
-/**
- * destroy enumerator, and complete tree if this was the last enumerator
- */
-static void child_destroy(child_enum_t *this)
+METHOD(enumerator_t, child_destroy, void,
+ child_enum_t *this)
{
if (--this->child.root->enums == 0)
{
@@ -121,20 +114,25 @@ static void child_destroy(child_enum_t *this)
free(this);
}
-/**
- * Implementation of xml_t.children.
- */
-static enumerator_t* children(private_xml_t *this)
+METHOD(xml_t, children, enumerator_t*,
+ private_xml_t *this)
{
- child_enum_t *ce = malloc_thing(child_enum_t);
- ce->e.enumerate = (void*)child_enumerate;
- ce->e.destroy = (void*)child_destroy;
- ce->node = this->node;
- ce->child.public.children = (void*)children;
- ce->child.public.get_attribute = (void*)get_attribute;
- ce->child.node = NULL;
- ce->child.doc = this->doc;
- ce->child.root = this->root;
+ child_enum_t *ce;
+ INIT(ce,
+ .e = {
+ .enumerate = (void*)_child_enumerate,
+ .destroy = _child_destroy,
+ },
+ .child = {
+ .public = {
+ .get_attribute = _get_attribute,
+ .children = _children,
+ },
+ .doc = this->doc,
+ .root = this->root,
+ },
+ .node = this->node,
+ );
this->root->enums++;
return &ce->e;
}
@@ -144,20 +142,24 @@ static enumerator_t* children(private_xml_t *this)
*/
xml_t *xml_create(char *xml)
{
- private_xml_t *this = malloc_thing(private_xml_t);
+ private_xml_t *this;
- this->public.get_attribute = (char*(*)(xml_t*,char*))get_attribute;
- this->public.children = (enumerator_t*(*)(xml_t*))children;
+ INIT(this,
+ .public = {
+ .get_attribute = _get_attribute,
+ .children = _children,
+ },
+ .doc = xmlReadMemory(xml, strlen(xml), NULL, NULL, 0),
+ );
- this->doc = xmlReadMemory(xml, strlen(xml), NULL, NULL, 0);
- if (this->doc == NULL)
+ if (!this->doc)
{
free(this);
return NULL;
}
+
this->node = xmlDocGetRootElement(this->doc);
this->root = this;
- this->enums = 0;
return &this->public;
}
diff --git a/src/medsrv/Makefile.am b/src/medsrv/Makefile.am
index 171b086cf..43da9c4e5 100644
--- a/src/medsrv/Makefile.am
+++ b/src/medsrv/Makefile.am
@@ -7,7 +7,7 @@ main.c filter/auth_filter.c filter/auth_filter.h \
controller/user_controller.c controller/user_controller.h \
controller/peer_controller.c controller/peer_controller.h
-medsrv_fcgi_LDADD = $(top_srcdir)/src/libstrongswan/libstrongswan.la $(top_builddir)/src/libfast/libfast.la
+medsrv_fcgi_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la $(top_builddir)/src/libfast/libfast.la
main.o : $(top_builddir)/config.status
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libfast
diff --git a/src/medsrv/Makefile.in b/src/medsrv/Makefile.in
index 99a8cc135..95f02c580 100644
--- a/src/medsrv/Makefile.in
+++ b/src/medsrv/Makefile.in
@@ -64,7 +64,7 @@ am_medsrv_fcgi_OBJECTS = user.$(OBJEXT) main.$(OBJEXT) \
peer_controller.$(OBJEXT)
medsrv_fcgi_OBJECTS = $(am_medsrv_fcgi_OBJECTS)
medsrv_fcgi_DEPENDENCIES = \
- $(top_srcdir)/src/libstrongswan/libstrongswan.la \
+ $(top_builddir)/src/libstrongswan/libstrongswan.la \
$(top_builddir)/src/libfast/libfast.la
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -198,6 +198,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -206,6 +209,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -222,11 +226,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -270,6 +276,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -286,7 +293,7 @@ main.c filter/auth_filter.c filter/auth_filter.h \
controller/user_controller.c controller/user_controller.h \
controller/peer_controller.c controller/peer_controller.h
-medsrv_fcgi_LDADD = $(top_srcdir)/src/libstrongswan/libstrongswan.la $(top_builddir)/src/libfast/libfast.la
+medsrv_fcgi_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la $(top_builddir)/src/libfast/libfast.la
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libfast
AM_CFLAGS = -rdynamic \
-DIPSECDIR=\"${ipsecdir}\" \
diff --git a/src/medsrv/controller/peer_controller.c b/src/medsrv/controller/peer_controller.c
index 5948fcfb7..edcf653b2 100755
--- a/src/medsrv/controller/peer_controller.c
+++ b/src/medsrv/controller/peer_controller.c
@@ -312,19 +312,15 @@ static void delete(private_peer_controller_t *this, request_t *request, int id)
DB_INT, id, DB_UINT, this->user->get_user(this->user));
}
-/**
- * Implementation of controller_t.get_name
- */
-static char* get_name(private_peer_controller_t *this)
+METHOD(controller_t, get_name, char*,
+ private_peer_controller_t *this)
{
return "peer";
}
-/**
- * Implementation of controller_t.handle
- */
-static void handle(private_peer_controller_t *this, request_t *request,
- char *action, char *idstr)
+METHOD(controller_t, handle, void,
+ private_peer_controller_t *this, request_t *request, char *action,
+ char *idstr, char *p3, char *p4, char *p5)
{
if (action)
{
@@ -354,10 +350,8 @@ static void handle(private_peer_controller_t *this, request_t *request,
request->redirect(request, "peer/list");
}
-/**
- * Implementation of controller_t.destroy
- */
-static void destroy(private_peer_controller_t *this)
+METHOD(controller_t, destroy, void,
+ private_peer_controller_t *this)
{
free(this);
}
@@ -367,14 +361,19 @@ static void destroy(private_peer_controller_t *this)
*/
controller_t *peer_controller_create(user_t *user, database_t *db)
{
- private_peer_controller_t *this= malloc_thing(private_peer_controller_t);
-
- this->public.controller.get_name = (char*(*)(controller_t*))get_name;
- this->public.controller.handle = (void(*)(controller_t*, request_t*, char*, char*, char*, char*, char*))handle;
- this->public.controller.destroy = (void(*)(controller_t*))destroy;
-
- this->user = user;
- this->db = db;
+ private_peer_controller_t *this;
+
+ INIT(this,
+ .public = {
+ .controller = {
+ .get_name = _get_name,
+ .handle = _handle,
+ .destroy = _destroy,
+ },
+ },
+ .user = user,
+ .db = db,
+ );
return &this->public.controller;
}
diff --git a/src/medsrv/controller/user_controller.c b/src/medsrv/controller/user_controller.c
index 0f25799d8..12bd938fe 100755
--- a/src/medsrv/controller/user_controller.c
+++ b/src/medsrv/controller/user_controller.c
@@ -44,7 +44,7 @@ struct private_user_controller_t {
user_t *user;
/**
- * minimum required password lenght
+ * minimum required password length
*/
u_int password_length;
};
@@ -293,18 +293,15 @@ static void edit(private_user_controller_t *this, request_t *request)
request->render(request, "templates/user/edit.cs");
}
-/**
- * Implementation of controller_t.get_name
- */
-static char* get_name(private_user_controller_t *this)
+METHOD(controller_t, get_name, char*,
+ private_user_controller_t *this)
{
return "user";
}
-/**
- * Implementation of controller_t.handle
- */
-static void handle(private_user_controller_t *this, request_t *request, char *action)
+METHOD(controller_t, handle, void,
+ private_user_controller_t *this, request_t *request, char *action,
+ char *p2, char *p3, char *p4, char *p5)
{
if (action)
{
@@ -332,10 +329,8 @@ static void handle(private_user_controller_t *this, request_t *request, char *ac
request->redirect(request, "user/login");
}
-/**
- * Implementation of controller_t.destroy
- */
-static void destroy(private_user_controller_t *this)
+METHOD(controller_t, destroy, void,
+ private_user_controller_t *this)
{
free(this);
}
@@ -345,16 +340,21 @@ static void destroy(private_user_controller_t *this)
*/
controller_t *user_controller_create(user_t *user, database_t *db)
{
- private_user_controller_t *this= malloc_thing(private_user_controller_t);
-
- this->public.controller.get_name = (char*(*)(controller_t*))get_name;
- this->public.controller.handle = (void(*)(controller_t*, request_t*, char*, char*, char*, char*, char*))handle;
- this->public.controller.destroy = (void(*)(controller_t*))destroy;
-
- this->user = user;
- this->db = db;
- this->password_length = lib->settings->get_int(lib->settings,
- "medsrv.password_length", 6);
+ private_user_controller_t *this;
+
+ INIT(this,
+ .public = {
+ .controller = {
+ .get_name = _get_name,
+ .handle = _handle,
+ .destroy = _destroy,
+ },
+ },
+ .user = user,
+ .db = db,
+ .password_length = lib->settings->get_int(lib->settings,
+ "medsrv.password_length", 6),
+ );
return &this->public.controller;
}
diff --git a/src/medsrv/filter/auth_filter.c b/src/medsrv/filter/auth_filter.c
index 9ed356042..d21abdc46 100755
--- a/src/medsrv/filter/auth_filter.c
+++ b/src/medsrv/filter/auth_filter.c
@@ -1,50 +1,48 @@
/*
- * Copyright (C) 2008 Martin Willi
- * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
- * 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 "auth_filter.h"
-
-#include <debug.h>
-
-typedef struct private_auth_filter_t private_auth_filter_t;
-
-/**
- * private data of auth_filter
- */
-struct private_auth_filter_t {
- /**
- * public functions
- */
- auth_filter_t public;
-
- /**
- * user session
- */
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
+ * 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 "auth_filter.h"
+
+#include <debug.h>
+
+typedef struct private_auth_filter_t private_auth_filter_t;
+
+/**
+ * private data of auth_filter
+ */
+struct private_auth_filter_t {
+ /**
+ * public functions
+ */
+ auth_filter_t public;
+
+ /**
+ * user session
+ */
user_t *user;
/**
* database connection
*/
- database_t *db;
+ database_t *db;
};
-
-/**
- * Implementation of filter_t.run
- */
-static bool run(private_auth_filter_t *this, request_t *request,
- char *controller, char *action)
+
+METHOD(filter_t, run, bool,
+ private_auth_filter_t *this, request_t *request, char *controller,
+ char *action, char *p2, char *p3, char *p4, char *p5)
{
if (this->user->get_user(this->user))
{
@@ -67,32 +65,35 @@ static bool run(private_auth_filter_t *this, request_t *request,
(streq(action, "add") || streq(action, "login") || streq(action, "help")))
{ /* add/login allowed */
return TRUE;
- }
- request->redirect(request, "user/login");
- return FALSE;
-}
-
-/**
- * Implementation of filter_t.destroy
- */
-static void destroy(private_auth_filter_t *this)
-{
- free(this);
-}
-
-/*
- * see header file
- */
-filter_t *auth_filter_create(user_t *user, database_t *db)
-{
- private_auth_filter_t *this= malloc_thing(private_auth_filter_t);
-
- this->public.filter.destroy = (void(*)(filter_t*))destroy;
- this->public.filter.run = (bool(*)(filter_t*, request_t*,char*,char*,char*,char*,char*,char*))run;
-
- this->user = user;
- this->db = db;
-
- return &this->public.filter;
-}
+ }
+ request->redirect(request, "user/login");
+ return FALSE;
+}
+
+METHOD(filter_t, destroy, void,
+ private_auth_filter_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+filter_t *auth_filter_create(user_t *user, database_t *db)
+{
+ private_auth_filter_t *this;
+
+ INIT(this,
+ .public = {
+ .filter = {
+ .destroy = _destroy,
+ .run = _run,
+ },
+ },
+ .user = user,
+ .db = db,
+ );
+
+ return &this->public.filter;
+}
diff --git a/src/medsrv/filter/auth_filter.h b/src/medsrv/filter/auth_filter.h
index f1fc565eb..c46de40a5 100755
--- a/src/medsrv/filter/auth_filter.h
+++ b/src/medsrv/filter/auth_filter.h
@@ -1,48 +1,48 @@
/*
- * Copyright (C) 2008 Martin Willi
- * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
- * 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 auth_filter_server auth_filter
- * @{ @ingroup filter_server
- */
-
-#ifndef AUTH_FILTER_H_
-#define AUTH_FILTER_H_
-
-#include <library.h>
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
+ * 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 auth_filter_server auth_filter
+ * @{ @ingroup filter_server
+ */
+
+#ifndef AUTH_FILTER_H_
+#define AUTH_FILTER_H_
+
+#include <library.h>
#include <filter.h>
-#include "user.h"
-
-typedef struct auth_filter_t auth_filter_t;
-
-/**
- * Authentication/Authorization filter.
- */
-struct auth_filter_t {
-
- /**
- * Implements filter_t interface.
- */
- filter_t filter;
-};
-
-/**
- * Create a auth_filter instance.
- */
-filter_t *auth_filter_create(user_t *user, database_t *db);
-
-#endif /* AUTH_FILTER_H_ @}*/
+#include "user.h"
+
+typedef struct auth_filter_t auth_filter_t;
+
+/**
+ * Authentication/Authorization filter.
+ */
+struct auth_filter_t {
+
+ /**
+ * Implements filter_t interface.
+ */
+ filter_t filter;
+};
+
+/**
+ * Create a auth_filter instance.
+ */
+filter_t *auth_filter_create(user_t *user, database_t *db);
+
+#endif /* AUTH_FILTER_H_ @}*/
diff --git a/src/medsrv/user.c b/src/medsrv/user.c
index d204dd057..b4859080b 100644
--- a/src/medsrv/user.c
+++ b/src/medsrv/user.c
@@ -33,26 +33,20 @@ struct private_user_t {
u_int user;
};
-/**
- * Implementation of user_t.set_user
- */
-static void set_user(private_user_t *this, u_int id)
+METHOD(user_t, set_user, void,
+ private_user_t *this, u_int id)
{
this->user = id;
}
-/**
- * Implementation of user_t.get_user
- */
-static u_int get_user(private_user_t *this)
+METHOD(user_t, get_user, u_int,
+ private_user_t *this)
{
return this->user;
}
-/**
- * Implementation of context_t.destroy
- */
-static void destroy(private_user_t *this)
+METHOD(context_t, destroy, void,
+ private_user_t *this)
{
free(this);
}
@@ -62,13 +56,17 @@ static void destroy(private_user_t *this)
*/
user_t *user_create(void *param)
{
- private_user_t *this= malloc_thing(private_user_t);
-
- this->public.set_user = (void(*)(user_t*,u_int id))set_user;
- this->public.get_user = (u_int(*)(user_t*))get_user;
- this->public.context.destroy = (void(*)(context_t*))destroy;
+ private_user_t *this;
- this->user = 0;
+ INIT(this,
+ .public = {
+ .set_user = _set_user,
+ .get_user = _get_user,
+ .context = {
+ .destroy = _destroy,
+ },
+ },
+ );
return &this->public;
}
diff --git a/src/openac/Makefile.in b/src/openac/Makefile.in
index 54544b665..95043350d 100644
--- a/src/openac/Makefile.in
+++ b/src/openac/Makefile.in
@@ -192,6 +192,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -200,6 +203,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -216,11 +220,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +270,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/pki/Makefile.in b/src/pki/Makefile.in
index b29174680..f9c417658 100644
--- a/src/pki/Makefile.in
+++ b/src/pki/Makefile.in
@@ -169,6 +169,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -177,6 +180,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -193,11 +197,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -241,6 +247,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/pki/command.c b/src/pki/command.c
index 0142b4ab7..07ba5bb1d 100644
--- a/src/pki/command.c
+++ b/src/pki/command.c
@@ -176,6 +176,13 @@ int command_usage(char *error)
fprintf(out, "Error: %s\n", error);
}
fprintf(out, "strongSwan %s PKI tool\n", VERSION);
+
+ if (active == help_idx)
+ {
+ fprintf(out, "loaded plugins: %s\n",
+ lib->plugins->loaded_plugins(lib->plugins));
+ }
+
fprintf(out, "usage:\n");
if (active == help_idx)
{
diff --git a/src/pki/commands/issue.c b/src/pki/commands/issue.c
index 6a5686d92..20163edf2 100644
--- a/src/pki/commands/issue.c
+++ b/src/pki/commands/issue.c
@@ -67,11 +67,11 @@ static int issue()
char *error = NULL, *keyid = NULL;
identification_t *id = NULL;
linked_list_t *san, *cdps, *ocsp, *permitted, *excluded, *policies, *mappings;
- int lifetime = 1095;
int pathlen = X509_NO_CONSTRAINT, inhibit_any = X509_NO_CONSTRAINT;
int inhibit_mapping = X509_NO_CONSTRAINT, require_explicit = X509_NO_CONSTRAINT;
chunk_t serial = chunk_empty;
chunk_t encoding = chunk_empty;
+ time_t lifetime = 1095;
time_t not_before, not_after;
x509_flag_t flags = 0;
x509_t *x509;
diff --git a/src/pki/commands/print.c b/src/pki/commands/print.c
index ee6f30c98..a7f02bfac 100644
--- a/src/pki/commands/print.c
+++ b/src/pki/commands/print.c
@@ -79,7 +79,7 @@ static void print_x509(x509_t *x509)
x509_cert_policy_t *policy;
x509_policy_mapping_t *mapping;
- chunk = x509->get_serial(x509);
+ chunk = chunk_skip_zero(x509->get_serial(x509));
printf("serial: %#B\n", &chunk);
first = TRUE;
@@ -329,10 +329,12 @@ static void print_crl(crl_t *crl)
struct tm tm;
x509_cdp_t *cdp;
- chunk = crl->get_serial(crl);
+ chunk = chunk_skip_zero(crl->get_serial(crl));
printf("serial: %#B\n", &chunk);
+
if (crl->is_delta_crl(crl, &chunk))
{
+ chunk = chunk_skip_zero(chunk);
printf("delta CRL: for serial %#B\n", &chunk);
}
chunk = crl->get_authKeyIdentifier(crl);
@@ -371,6 +373,7 @@ static void print_crl(crl_t *crl)
enumerator = crl->create_enumerator(crl);
while (enumerator->enumerate(enumerator, &chunk, &ts, &reason))
{
+ chunk = chunk_skip_zero(chunk);
localtime_r(&ts, &tm);
strftime(buf, sizeof(buf), "%F %T", &tm);
printf(" %#B %N %s\n", &chunk, crl_reason_names, reason, buf);
diff --git a/src/pki/commands/self.c b/src/pki/commands/self.c
index c7788ff62..c4508a671 100644
--- a/src/pki/commands/self.c
+++ b/src/pki/commands/self.c
@@ -55,11 +55,11 @@ static int self()
char *file = NULL, *dn = NULL, *hex = NULL, *error = NULL, *keyid = NULL;
identification_t *id = NULL;
linked_list_t *san, *ocsp, *permitted, *excluded, *policies, *mappings;
- int lifetime = 1095;
int pathlen = X509_NO_CONSTRAINT, inhibit_any = X509_NO_CONSTRAINT;
int inhibit_mapping = X509_NO_CONSTRAINT, require_explicit = X509_NO_CONSTRAINT;
chunk_t serial = chunk_empty;
chunk_t encoding = chunk_empty;
+ time_t lifetime = 1095;
time_t not_before, not_after;
x509_flag_t flags = 0;
x509_cert_policy_t *policy = NULL;
diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c
index 9a21bd99c..153734f53 100644
--- a/src/pki/commands/signcrl.c
+++ b/src/pki/commands/signcrl.c
@@ -120,21 +120,20 @@ static int sign_crl()
hash_algorithm_t digest = HASH_SHA1;
char *arg, *cacert = NULL, *cakey = NULL, *lastupdate = NULL, *error = NULL;
char *basecrl = NULL;
- char serial[512], crl_serial[8], *keyid = NULL;
+ char serial[512], *keyid = NULL;
int serial_len = 0;
crl_reason_t reason = CRL_REASON_UNSPECIFIED;
time_t thisUpdate, nextUpdate, date = time(NULL);
- int lifetime = 15;
+ time_t lifetime = 15;
linked_list_t *list, *cdps;
enumerator_t *enumerator, *lastenum = NULL;
x509_cdp_t *cdp;
- chunk_t encoding = chunk_empty, baseCrlNumber = chunk_empty;
+ chunk_t crl_serial = chunk_empty, baseCrlNumber = chunk_empty;
+ chunk_t encoding = chunk_empty;
list = linked_list_create();
cdps = linked_list_create();
- memset(crl_serial, 0, sizeof(crl_serial));
-
while (TRUE)
{
switch (command_getopt(&arg))
@@ -334,9 +333,8 @@ static int sign_crl()
error = "loading base CRL failed";
goto error;
}
- memcpy(crl_serial, lastcrl->get_serial(lastcrl).ptr,
- min(lastcrl->get_serial(lastcrl).len, sizeof(crl_serial)));
baseCrlNumber = chunk_clone(lastcrl->get_serial(lastcrl));
+ crl_serial = baseCrlNumber;
DESTROY_IF((certificate_t*)lastcrl);
lastcrl = NULL;
}
@@ -350,22 +348,31 @@ static int sign_crl()
error = "loading lastUpdate CRL failed";
goto error;
}
- memcpy(crl_serial, lastcrl->get_serial(lastcrl).ptr,
- min(lastcrl->get_serial(lastcrl).len, sizeof(crl_serial)));
+ crl_serial = lastcrl->get_serial(lastcrl);
lastenum = lastcrl->create_enumerator(lastcrl);
}
else
{
+ crl_serial = chunk_from_chars(0x00);
lastenum = enumerator_create_empty();
}
- chunk_increment(chunk_create(crl_serial, sizeof(crl_serial)));
+ /* remove superfluous leading zeros */
+ while (crl_serial.len > 1 && crl_serial.ptr[0] == 0x00 &&
+ (crl_serial.ptr[1] & 0x80) == 0x00)
+ {
+ crl_serial = chunk_skip_zero(crl_serial);
+ }
+ crl_serial = chunk_clone(crl_serial);
+
+ /* increment the serial number by one */
+ chunk_increment(crl_serial);
enumerator = enumerator_create_filter(list->create_enumerator(list),
(void*)filter, NULL, NULL);
crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
BUILD_SIGNING_KEY, private, BUILD_SIGNING_CERT, ca,
- BUILD_SERIAL, chunk_create(crl_serial, sizeof(crl_serial)),
+ BUILD_SERIAL, crl_serial,
BUILD_NOT_BEFORE_TIME, thisUpdate, BUILD_NOT_AFTER_TIME, nextUpdate,
BUILD_REVOKED_ENUMERATOR, enumerator,
BUILD_REVOKED_ENUMERATOR, lastenum, BUILD_DIGEST_ALG, digest,
@@ -374,6 +381,7 @@ static int sign_crl()
enumerator->destroy(enumerator);
lastenum->destroy(lastenum);
DESTROY_IF((certificate_t*)lastcrl);
+ free(crl_serial.ptr);
if (!crl)
{
diff --git a/src/pluto/Android.mk b/src/pluto/Android.mk
new file mode 100644
index 000000000..618f79c42
--- /dev/null
+++ b/src/pluto/Android.mk
@@ -0,0 +1,80 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# copy-n-paste from Makefile.am
+LOCAL_SRC_FILES := \
+ac.c ac.h \
+alg_info.c alg_info.h \
+ca.c ca.h \
+certs.c certs.h \
+connections.c connections.h \
+constants.c constants.h \
+cookie.c cookie.h \
+crl.c crl.h \
+crypto.c crypto.h \
+db_ops.c db_ops.h \
+defs.c defs.h \
+demux.c demux.h \
+event_queue.c event_queue.h \
+fetch.c fetch.h \
+foodgroups.c foodgroups.h \
+ike_alg.c ike_alg.h \
+ipsec_doi.c ipsec_doi.h \
+kameipsec.h \
+kernel.c kernel.h \
+kernel_alg.c kernel_alg.h \
+kernel_pfkey.c kernel_pfkey.h \
+keys.c keys.h \
+lex.c lex.h \
+log.c log.h \
+myid.c myid.h \
+modecfg.c modecfg.h \
+nat_traversal.c nat_traversal.h \
+ocsp.c ocsp.h \
+packet.c packet.h \
+pkcs7.c pkcs7.h \
+plugin_list.c plugin_list.h \
+pluto.c pluto.h \
+plutomain.c \
+rcv_whack.c rcv_whack.h \
+server.c server.h \
+smartcard.c smartcard.h \
+spdb.c spdb.h \
+state.c state.h \
+timer.c timer.h \
+vendor.c vendor.h \
+virtual.c virtual.h \
+whack_attribute.c whack_attribute.h \
+xauth/xauth_manager.c xauth/xauth_manager.h \
+xauth/xauth_provider.h xauth/xauth_verifier.h \
+x509.c x509.h \
+builder.c builder.h \
+rsaref/pkcs11t.h rsaref/pkcs11.h rsaref/unix.h rsaref/pkcs11f.h
+
+LOCAL_SRC_FILES += $(call add_plugin, xauth)
+
+# build pluto ------------------------------------------------------------------
+
+LOCAL_C_INCLUDES += \
+ $(libvstr_PATH) \
+ $(strongswan_PATH)/src/libhydra \
+ $(strongswan_PATH)/src/libstrongswan \
+ $(strongswan_PATH)/src/libfreeswan \
+ $(strongswan_PATH)/src/whack
+
+LOCAL_CFLAGS := $(strongswan_CFLAGS) \
+ -DPLUTO -DVENDORID -DXAUTH_VID -DCISCO_QUIRKS \
+ -DTHREADS -DKERNEL26_HAS_KAME_DUPLICATES \
+ -DPLUGINS='"$(strongswan_PLUTO_PLUGINS)"'
+
+LOCAL_MODULE := pluto
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_SHARED_LIBRARIES += libstrongswan libhydra libfreeswan libcutils
+
+include $(BUILD_EXECUTABLE)
diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am
index 934b11a46..3fd0e039c 100644
--- a/src/pluto/Makefile.am
+++ b/src/pluto/Makefile.am
@@ -2,7 +2,11 @@
# painless way. Only the most important options are included,
# further work may be necessary here...
-ipsec_PROGRAMS = pluto _pluto_adns
+ipsec_PROGRAMS = pluto
+
+if USE_ADNS
+ipsec_PROGRAMS += _pluto_adns
+endif
pluto_SOURCES = \
ac.c ac.h \
@@ -17,7 +21,6 @@ crypto.c crypto.h \
db_ops.c db_ops.h \
defs.c defs.h \
demux.c demux.h \
-dnskey.c dnskey.h \
event_queue.c event_queue.h \
fetch.c fetch.h \
foodgroups.c foodgroups.h \
@@ -36,6 +39,7 @@ nat_traversal.c nat_traversal.h \
ocsp.c ocsp.h \
packet.c packet.h \
pkcs7.c pkcs7.h \
+plugin_list.c plugin_list.h \
pluto.c pluto.h \
plutomain.c \
rcv_whack.c rcv_whack.h \
@@ -53,7 +57,13 @@ x509.c x509.h \
builder.c builder.h \
rsaref/pkcs11t.h rsaref/pkcs11.h rsaref/unix.h rsaref/pkcs11f.h
-_pluto_adns_SOURCES = adns.c adns.h
+if USE_ADNS
+pluto_SOURCES += \
+dnskey.c dnskey.h
+
+_pluto_adns_SOURCES = \
+adns.c adns.h
+endif
plutomain.o : $(top_builddir)/config.status
@@ -75,7 +85,7 @@ AM_CFLAGS = -rdynamic \
-DSHARED_SECRETS_FILE=\"${sysconfdir}/ipsec.secrets\" \
-DPLUGINS=\""${pluto_plugins}\"" \
-DPKCS11_DEFAULT_LIB=\"${default_pkcs11}\" \
--DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES \
+-DKERNEL26_HAS_KAME_DUPLICATES \
-DPLUTO -DDEBUG
pluto_LDADD = \
@@ -84,12 +94,16 @@ $(LIBFREESWANDIR)/libfreeswan.a \
$(LIBHYDRADIR)/libhydra.la \
-lresolv $(PTHREADLIB) $(DLLIB)
+if USE_ADNS
_pluto_adns_LDADD = \
$(LIBFREESWANDIR)/libfreeswan.a \
-lresolv $(DLLIB)
+endif
dist_man_MANS = pluto.8
+EXTRA_DIST = Android.mk
+
# compile options
#################
@@ -126,6 +140,10 @@ if USE_THREADS
AM_CFLAGS += -DTHREADS
endif
+if USE_ADNS
+ AM_CFLAGS += -DADNS
+endif
+
# build optional plugins
########################
diff --git a/src/pluto/Makefile.in b/src/pluto/Makefile.in
index 92e66db17..b055ba289 100644
--- a/src/pluto/Makefile.in
+++ b/src/pluto/Makefile.in
@@ -38,28 +38,33 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-ipsec_PROGRAMS = pluto$(EXEEXT) _pluto_adns$(EXEEXT)
+ipsec_PROGRAMS = pluto$(EXEEXT) $(am__EXEEXT_1)
+@USE_ADNS_TRUE@am__append_1 = _pluto_adns
+@USE_ADNS_TRUE@am__append_2 = \
+@USE_ADNS_TRUE@dnskey.c dnskey.h
+
# compile options
#################
# This compile option activates the sending of a strongSwan VID
-@USE_VENDORID_TRUE@am__append_1 = -DVENDORID
+@USE_VENDORID_TRUE@am__append_3 = -DVENDORID
# This compile option activates the sending of the XAUTH VID
-@USE_XAUTH_VID_TRUE@am__append_2 = -DXAUTH_VID
+@USE_XAUTH_VID_TRUE@am__append_4 = -DXAUTH_VID
# This compile option activates the support of the Cisco VPN client
-@USE_CISCO_QUIRKS_TRUE@am__append_3 = -DCISCO_QUIRKS
+@USE_CISCO_QUIRKS_TRUE@am__append_5 = -DCISCO_QUIRKS
# This compile option activates NAT traversal with IPSec transport mode
-@USE_NAT_TRANSPORT_TRUE@am__append_4 = -DI_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
+@USE_NAT_TRANSPORT_TRUE@am__append_6 = -DI_KNOW_TRANSPORT_MODE_HAS_SECURITY_CONCERN_BUT_I_WANT_IT
# This compile option activates smartcard support
-@USE_SMARTCARD_TRUE@am__append_5 = -DSMARTCARD
-@USE_LIBCAP_TRUE@am__append_6 = -lcap
-@USE_THREADS_TRUE@am__append_7 = -DTHREADS
-@USE_XAUTH_TRUE@am__append_8 = plugins/xauth
+@USE_SMARTCARD_TRUE@am__append_7 = -DSMARTCARD
+@USE_LIBCAP_TRUE@am__append_8 = -lcap
+@USE_THREADS_TRUE@am__append_9 = -DTHREADS
+@USE_ADNS_TRUE@am__append_10 = -DADNS
+@USE_XAUTH_TRUE@am__append_11 = plugins/xauth
subdir = src/pluto
DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
@@ -78,28 +83,50 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
+@USE_ADNS_TRUE@am__EXEEXT_1 = _pluto_adns$(EXEEXT)
am__installdirs = "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"
PROGRAMS = $(ipsec_PROGRAMS)
-am__pluto_adns_OBJECTS = adns.$(OBJEXT)
+am___pluto_adns_SOURCES_DIST = adns.c adns.h
+@USE_ADNS_TRUE@am__pluto_adns_OBJECTS = adns.$(OBJEXT)
_pluto_adns_OBJECTS = $(am__pluto_adns_OBJECTS)
am__DEPENDENCIES_1 =
-_pluto_adns_DEPENDENCIES = $(LIBFREESWANDIR)/libfreeswan.a \
- $(am__DEPENDENCIES_1)
+@USE_ADNS_TRUE@_pluto_adns_DEPENDENCIES = \
+@USE_ADNS_TRUE@ $(LIBFREESWANDIR)/libfreeswan.a \
+@USE_ADNS_TRUE@ $(am__DEPENDENCIES_1)
+am__pluto_SOURCES_DIST = ac.c ac.h alg_info.c alg_info.h ca.c ca.h \
+ certs.c certs.h connections.c connections.h constants.c \
+ constants.h cookie.c cookie.h crl.c crl.h crypto.c crypto.h \
+ db_ops.c db_ops.h defs.c defs.h demux.c demux.h event_queue.c \
+ event_queue.h fetch.c fetch.h foodgroups.c foodgroups.h \
+ ike_alg.c ike_alg.h ipsec_doi.c ipsec_doi.h kameipsec.h \
+ kernel.c kernel.h kernel_alg.c kernel_alg.h kernel_pfkey.c \
+ kernel_pfkey.h keys.c keys.h lex.c lex.h log.c log.h myid.c \
+ myid.h modecfg.c modecfg.h nat_traversal.c nat_traversal.h \
+ ocsp.c ocsp.h packet.c packet.h pkcs7.c pkcs7.h plugin_list.c \
+ plugin_list.h pluto.c pluto.h plutomain.c rcv_whack.c \
+ rcv_whack.h server.c server.h smartcard.c smartcard.h spdb.c \
+ spdb.h state.c state.h timer.c timer.h vendor.c vendor.h \
+ virtual.c virtual.h whack_attribute.c whack_attribute.h \
+ xauth/xauth_manager.c xauth/xauth_manager.h \
+ xauth/xauth_provider.h xauth/xauth_verifier.h x509.c x509.h \
+ builder.c builder.h rsaref/pkcs11t.h rsaref/pkcs11.h \
+ rsaref/unix.h rsaref/pkcs11f.h dnskey.c dnskey.h
+@USE_ADNS_TRUE@am__objects_1 = dnskey.$(OBJEXT)
am_pluto_OBJECTS = ac.$(OBJEXT) alg_info.$(OBJEXT) ca.$(OBJEXT) \
certs.$(OBJEXT) connections.$(OBJEXT) constants.$(OBJEXT) \
cookie.$(OBJEXT) crl.$(OBJEXT) crypto.$(OBJEXT) \
db_ops.$(OBJEXT) defs.$(OBJEXT) demux.$(OBJEXT) \
- dnskey.$(OBJEXT) event_queue.$(OBJEXT) fetch.$(OBJEXT) \
- foodgroups.$(OBJEXT) ike_alg.$(OBJEXT) ipsec_doi.$(OBJEXT) \
- kernel.$(OBJEXT) kernel_alg.$(OBJEXT) kernel_pfkey.$(OBJEXT) \
- keys.$(OBJEXT) lex.$(OBJEXT) log.$(OBJEXT) myid.$(OBJEXT) \
- modecfg.$(OBJEXT) nat_traversal.$(OBJEXT) ocsp.$(OBJEXT) \
- packet.$(OBJEXT) pkcs7.$(OBJEXT) pluto.$(OBJEXT) \
+ event_queue.$(OBJEXT) fetch.$(OBJEXT) foodgroups.$(OBJEXT) \
+ ike_alg.$(OBJEXT) ipsec_doi.$(OBJEXT) kernel.$(OBJEXT) \
+ kernel_alg.$(OBJEXT) kernel_pfkey.$(OBJEXT) keys.$(OBJEXT) \
+ lex.$(OBJEXT) log.$(OBJEXT) myid.$(OBJEXT) modecfg.$(OBJEXT) \
+ nat_traversal.$(OBJEXT) ocsp.$(OBJEXT) packet.$(OBJEXT) \
+ pkcs7.$(OBJEXT) plugin_list.$(OBJEXT) pluto.$(OBJEXT) \
plutomain.$(OBJEXT) rcv_whack.$(OBJEXT) server.$(OBJEXT) \
smartcard.$(OBJEXT) spdb.$(OBJEXT) state.$(OBJEXT) \
timer.$(OBJEXT) vendor.$(OBJEXT) virtual.$(OBJEXT) \
whack_attribute.$(OBJEXT) xauth_manager.$(OBJEXT) \
- x509.$(OBJEXT) builder.$(OBJEXT)
+ x509.$(OBJEXT) builder.$(OBJEXT) $(am__objects_1)
pluto_OBJECTS = $(am_pluto_OBJECTS)
pluto_DEPENDENCIES = $(LIBSTRONGSWANDIR)/libstrongswan.la \
$(LIBFREESWANDIR)/libfreeswan.a $(LIBHYDRADIR)/libhydra.la \
@@ -119,7 +146,8 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(_pluto_adns_SOURCES) $(pluto_SOURCES)
-DIST_SOURCES = $(_pluto_adns_SOURCES) $(pluto_SOURCES)
+DIST_SOURCES = $(am___pluto_adns_SOURCES_DIST) \
+ $(am__pluto_SOURCES_DIST)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
@@ -276,6 +304,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -284,6 +315,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -300,11 +332,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -348,6 +382,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -358,56 +393,27 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-pluto_SOURCES = \
-ac.c ac.h \
-alg_info.c alg_info.h \
-ca.c ca.h \
-certs.c certs.h \
-connections.c connections.h \
-constants.c constants.h \
-cookie.c cookie.h \
-crl.c crl.h \
-crypto.c crypto.h \
-db_ops.c db_ops.h \
-defs.c defs.h \
-demux.c demux.h \
-dnskey.c dnskey.h \
-event_queue.c event_queue.h \
-fetch.c fetch.h \
-foodgroups.c foodgroups.h \
-ike_alg.c ike_alg.h \
-ipsec_doi.c ipsec_doi.h \
-kameipsec.h \
-kernel.c kernel.h \
-kernel_alg.c kernel_alg.h \
-kernel_pfkey.c kernel_pfkey.h \
-keys.c keys.h \
-lex.c lex.h \
-log.c log.h \
-myid.c myid.h \
-modecfg.c modecfg.h \
-nat_traversal.c nat_traversal.h \
-ocsp.c ocsp.h \
-packet.c packet.h \
-pkcs7.c pkcs7.h \
-pluto.c pluto.h \
-plutomain.c \
-rcv_whack.c rcv_whack.h \
-server.c server.h \
-smartcard.c smartcard.h \
-spdb.c spdb.h \
-state.c state.h \
-timer.c timer.h \
-vendor.c vendor.h \
-virtual.c virtual.h \
-whack_attribute.c whack_attribute.h \
-xauth/xauth_manager.c xauth/xauth_manager.h \
-xauth/xauth_provider.h xauth/xauth_verifier.h \
-x509.c x509.h \
-builder.c builder.h \
-rsaref/pkcs11t.h rsaref/pkcs11.h rsaref/unix.h rsaref/pkcs11f.h
-
-_pluto_adns_SOURCES = adns.c adns.h
+pluto_SOURCES = ac.c ac.h alg_info.c alg_info.h ca.c ca.h certs.c \
+ certs.h connections.c connections.h constants.c constants.h \
+ cookie.c cookie.h crl.c crl.h crypto.c crypto.h db_ops.c \
+ db_ops.h defs.c defs.h demux.c demux.h event_queue.c \
+ event_queue.h fetch.c fetch.h foodgroups.c foodgroups.h \
+ ike_alg.c ike_alg.h ipsec_doi.c ipsec_doi.h kameipsec.h \
+ kernel.c kernel.h kernel_alg.c kernel_alg.h kernel_pfkey.c \
+ kernel_pfkey.h keys.c keys.h lex.c lex.h log.c log.h myid.c \
+ myid.h modecfg.c modecfg.h nat_traversal.c nat_traversal.h \
+ ocsp.c ocsp.h packet.c packet.h pkcs7.c pkcs7.h plugin_list.c \
+ plugin_list.h pluto.c pluto.h plutomain.c rcv_whack.c \
+ rcv_whack.h server.c server.h smartcard.c smartcard.h spdb.c \
+ spdb.h state.c state.h timer.c timer.h vendor.c vendor.h \
+ virtual.c virtual.h whack_attribute.c whack_attribute.h \
+ xauth/xauth_manager.c xauth/xauth_manager.h \
+ xauth/xauth_provider.h xauth/xauth_verifier.h x509.c x509.h \
+ builder.c builder.h rsaref/pkcs11t.h rsaref/pkcs11.h \
+ rsaref/unix.h rsaref/pkcs11f.h $(am__append_2)
+@USE_ADNS_TRUE@_pluto_adns_SOURCES = \
+@USE_ADNS_TRUE@adns.c adns.h
+
LIBSTRONGSWANDIR = $(top_builddir)/src/libstrongswan
LIBFREESWANDIR = $(top_builddir)/src/libfreeswan
LIBHYDRADIR = $(top_builddir)/src/libhydra
@@ -422,22 +428,23 @@ AM_CFLAGS = -rdynamic -DIPSEC_DIR=\"${ipsecdir}\" \
-DIPSEC_CONFDIR=\"${sysconfdir}\" -DIPSEC_PIDDIR=\"${piddir}\" \
-DSHARED_SECRETS_FILE=\"${sysconfdir}/ipsec.secrets\" \
-DPLUGINS=\""${pluto_plugins}\"" \
- -DPKCS11_DEFAULT_LIB=\"${default_pkcs11}\" -DKERNEL26_SUPPORT \
- -DKERNEL26_HAS_KAME_DUPLICATES -DPLUTO -DDEBUG $(am__append_1) \
- $(am__append_2) $(am__append_3) $(am__append_4) \
- $(am__append_5) $(am__append_7)
+ -DPKCS11_DEFAULT_LIB=\"${default_pkcs11}\" \
+ -DKERNEL26_HAS_KAME_DUPLICATES -DPLUTO -DDEBUG $(am__append_3) \
+ $(am__append_4) $(am__append_5) $(am__append_6) \
+ $(am__append_7) $(am__append_9) $(am__append_10)
pluto_LDADD = $(LIBSTRONGSWANDIR)/libstrongswan.la \
$(LIBFREESWANDIR)/libfreeswan.a $(LIBHYDRADIR)/libhydra.la \
- -lresolv $(PTHREADLIB) $(DLLIB) $(am__append_6)
-_pluto_adns_LDADD = \
-$(LIBFREESWANDIR)/libfreeswan.a \
--lresolv $(DLLIB)
+ -lresolv $(PTHREADLIB) $(DLLIB) $(am__append_8)
+@USE_ADNS_TRUE@_pluto_adns_LDADD = \
+@USE_ADNS_TRUE@$(LIBFREESWANDIR)/libfreeswan.a \
+@USE_ADNS_TRUE@-lresolv $(DLLIB)
dist_man_MANS = pluto.8
+EXTRA_DIST = Android.mk
# build optional plugins
########################
-SUBDIRS = . $(am__append_8)
+SUBDIRS = . $(am__append_11)
all: all-recursive
.SUFFIXES:
@@ -560,6 +567,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ocsp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/packet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs7.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_list.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pluto.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plutomain.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rcv_whack.Po@am__quote@
diff --git a/src/pluto/ac.c b/src/pluto/ac.c
index 3339d91fb..cd8007aea 100644
--- a/src/pluto/ac.c
+++ b/src/pluto/ac.c
@@ -261,7 +261,7 @@ void ac_list_certs(bool utc)
whack_log(RC_COMMENT, " hissuer: \"%Y\"", holderIssuer);
}
- holderSerial = ac->get_holderSerial(ac);
+ holderSerial = chunk_skip_zero(ac->get_holderSerial(ac));
if (holderSerial.ptr)
{
whack_log(RC_COMMENT, " hserial: %#B", &holderSerial);
@@ -277,7 +277,7 @@ void ac_list_certs(bool utc)
issuer = cert->get_issuer(cert);
whack_log(RC_COMMENT, " issuer: \"%Y\"", issuer);
- serial = ac->get_serial(ac);
+ serial = chunk_skip_zero(ac->get_serial(ac));
whack_log(RC_COMMENT, " serial: %#B", &serial);
cert->get_validity(cert, &now, &notBefore, &notAfter);
diff --git a/src/pluto/adns.c b/src/pluto/adns.c
index 5d6979447..76b459216 100644
--- a/src/pluto/adns.c
+++ b/src/pluto/adns.c
@@ -12,8 +12,6 @@
* for more details.
*/
-#ifndef USE_LWRES /* whole file! */
-
/* This program executes as multiple processes. The Master process
* receives queries (struct adns_query messages) from Pluto and distributes
* them amongst Worker processes. These Worker processes are created
@@ -610,5 +608,3 @@ main(int argc UNUSED, char **argv)
return master();
}
-
-#endif /* !USE_LWRES */
diff --git a/src/pluto/adns.h b/src/pluto/adns.h
index f564be232..dfbcbaf16 100644
--- a/src/pluto/adns.h
+++ b/src/pluto/adns.h
@@ -12,7 +12,13 @@
* for more details.
*/
-#ifndef USE_LWRES /* whole file! */
+#ifndef ADNS
+
+/* dummy struct to make compilers happy */
+struct adns_query {
+};
+
+#else /* rest of file */
/* The interface in RHL6.x and BIND distribution 8.2.2 are different,
* so we build some of our own :-(
@@ -69,5 +75,4 @@ enum helper_exit_status {
HES_BAD_LEN, /* implausible .len field */
HES_BAD_MAGIC, /* .magic field wrong */
};
-
-#endif /* !USE_LWRES */
+#endif /* ADNS */
diff --git a/src/pluto/builder.c b/src/pluto/builder.c
index d7ec3feb9..a6e05a330 100644
--- a/src/pluto/builder.c
+++ b/src/pluto/builder.c
@@ -71,17 +71,17 @@ static cert_t *builder_load_cert(certificate_type_t type, va_list args)
if (pgp)
{
cert->cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_GPG,
- BUILD_BLOB_PGP, blob,
- BUILD_END);
+ CRED_CERTIFICATE, CERT_GPG,
+ BUILD_BLOB_PGP, blob,
+ BUILD_END);
}
else
{
cert->cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, blob,
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER, blob,
BUILD_X509_FLAG, flags,
- BUILD_END);
+ BUILD_END);
}
if (cert->cert)
{
@@ -121,9 +121,9 @@ static x509crl_t *builder_load_crl(certificate_type_t type, va_list args)
crl->next = NULL;
crl->distributionPoints = linked_list_create();
crl->crl = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509_CRL,
- BUILD_BLOB_ASN1_DER, blob,
- BUILD_END);
+ CRED_CERTIFICATE, CERT_X509_CRL,
+ BUILD_BLOB_ASN1_DER, blob,
+ BUILD_END);
if (crl->crl)
{
return crl;
diff --git a/src/pluto/ca.c b/src/pluto/ca.c
index add85def8..827b98121 100644
--- a/src/pluto/ca.c
+++ b/src/pluto/ca.c
@@ -87,7 +87,7 @@ bool trusted_ca(identification_t *a, identification_t *b, int *pathlen)
break;
}
certificate = cacert->cert;
-
+
/* is the certificate self-signed? */
{
x509_t *x509 = (x509_t*)certificate;
@@ -219,7 +219,8 @@ cert_t* get_authcert(identification_t *subject, chunk_t keyid,
}
/* compare the subjectDistinguishedNames */
- if (!certificate->has_subject(certificate, subject))
+ if (!(subject && certificate->has_subject(certificate, subject)) &&
+ (subject || !keyid.ptr))
{
continue;
}
@@ -248,7 +249,7 @@ cert_t* add_authcert(cert_t *cert, x509_flag_t auth_flags)
lock_authcert_list("add_authcert");
- old_cert = get_authcert(certificate->get_subject(certificate),
+ old_cert = get_authcert(certificate->get_subject(certificate),
x509->get_subjectKeyIdentifier(x509),
auth_flags);
if (old_cert)
diff --git a/src/pluto/connections.c b/src/pluto/connections.c
index 2194362d2..27cec40fc 100644
--- a/src/pluto/connections.c
+++ b/src/pluto/connections.c
@@ -425,8 +425,9 @@ void delete_connection(connection_t *c, bool relations)
c->requested_ca->destroy_offset(c->requested_ca,
offsetof(identification_t, destroy));
}
+#ifdef ADNS
gw_delref(&c->gw_info);
-
+#endif
lock_certs_and_keys("delete_connection");
cert_release(c->spd.this.cert);
scx_release(c->spd.this.sc);
@@ -1477,6 +1478,8 @@ connection_t *rw_instantiate(connection_t *c, const ip_address *him,
return d;
}
+#ifdef ADNS
+
connection_t *oppo_instantiate(connection_t *c, const ip_address *him,
identification_t *his_id, struct gw_info *gw,
const ip_address *our_client USED_BY_DEBUG,
@@ -1544,6 +1547,8 @@ connection_t *oppo_instantiate(connection_t *c, const ip_address *him,
return d;
}
+#endif /* ADNS */
+
/* priority formatting */
void fmt_policy_prio(policy_prio_t pp, char buf[POLICY_PRIO_BUF])
{
@@ -1767,6 +1772,8 @@ connection_t *find_connection_for_clients(struct spd_route **srp,
return best;
}
+#ifdef ADNS
+
/* Find and instantiate a connection for an outgoing Opportunistic connection.
* We've already discovered its gateway.
* We look for a the connection such that:
@@ -1869,6 +1876,8 @@ connection_t *build_outgoing_opportunistic_connection(struct gw_info *gw,
}
}
+#endif /* ADNS */
+
bool orient(connection_t *c)
{
struct spd_route *sr;
@@ -2179,6 +2188,8 @@ void initiate_opportunistic(const ip_address *our_client,
initiate_opportunistic_body(&b, NULL, NULL);
}
+#ifdef ADNS
+
static void continue_oppo(struct adns_continuation *acr, err_t ugh)
{
struct find_oppo_continuation *cr = (void *)acr; /* inherit, damn you! */
@@ -2242,6 +2253,8 @@ static void continue_oppo(struct adns_continuation *acr, err_t ugh)
close_any(whackfd);
}
+#endif /* ADNS */
+
#ifdef USE_KEYRR
static err_t check_key_recs(enum myid_state try_state, const connection_t *c,
struct adns_continuation *ac)
@@ -2298,6 +2311,8 @@ static err_t check_key_recs(enum myid_state try_state, const connection_t *c,
}
#endif /* USE_KEYRR */
+#ifdef ADNS
+
static err_t check_txt_recs(enum myid_state try_state, const connection_t *c,
struct adns_continuation *ac)
{
@@ -2355,6 +2370,8 @@ static err_t check_txt_recs(enum myid_state try_state, const connection_t *c,
return ugh;
}
+#endif /* ADNS */
+
/* note: gateways_from_dns must be NULL iff this is the first call */
static void initiate_opportunistic_body(struct find_oppo_bundle *b,
@@ -2431,6 +2448,7 @@ static void initiate_opportunistic_body(struct find_oppo_bundle *b,
ipsecdoi_initiate(b->whackfd, c, c->policy, 1, SOS_NOBODY);
b->whackfd = NULL_FD; /* protect from close */
}
+#ifdef ADNS
else
{
/* We are handling an opportunistic situation.
@@ -2996,6 +3014,7 @@ static void initiate_opportunistic_body(struct find_oppo_bundle *b,
cannot_oppo(c, b, ugh);
}
}
+#endif /* ADNS */
close_any(b->whackfd);
}
diff --git a/src/pluto/constants.c b/src/pluto/constants.c
index ec7bfaf78..73ec0bc54 100644
--- a/src/pluto/constants.c
+++ b/src/pluto/constants.c
@@ -1105,6 +1105,8 @@ bool subnetisnone(const ip_subnet *sn)
return isanyaddr(&base) && subnetishost(sn);
}
+#ifdef ADNS
+
/* BIND enumerated types */
#include <arpa/nameser.h>
@@ -1169,6 +1171,8 @@ static const char *const rr_class_name[] = {
enum_names rr_class_names = { C_IN, C_IN, rr_class_name, NULL };
+#endif /* ADNS */
+
/*
* NAT-Traversal defines for nat_traveral type from nat_traversal.h
*
diff --git a/src/pluto/constants.h b/src/pluto/constants.h
index 075579d6d..c931f1782 100644
--- a/src/pluto/constants.h
+++ b/src/pluto/constants.h
@@ -658,7 +658,7 @@ extern const char *prettypolicy(lset_t policy);
#define POLICY_COMPRESS LELEM(4) /* must be third */
#define POLICY_TUNNEL LELEM(5)
#define POLICY_PFS LELEM(6)
-#define POLICY_DISABLEARRIVALCHECK LELEM(7) /* supress tunnel egress address checking */
+#define POLICY_DISABLEARRIVALCHECK LELEM(7) /* suppress tunnel egress address checking */
#define POLICY_IPSEC_SHIFT 2 /* log2(POLICY_ENCRYPT) */
#define POLICY_IPSEC_MASK LRANGES(POLICY_ENCRYPT, POLICY_DISABLEARRIVALCHECK)
diff --git a/src/pluto/crl.c b/src/pluto/crl.c
index 38db0f2fd..c49b09e19 100644
--- a/src/pluto/crl.c
+++ b/src/pluto/crl.c
@@ -507,7 +507,7 @@ void list_crls(bool utc, bool strict)
whack_log(RC_COMMENT, " ");
whack_log(RC_COMMENT, " issuer: \"%Y\"",
cert_crl->get_issuer(cert_crl));
- serial = crl->get_serial(crl);
+ serial = chunk_skip_zero(crl->get_serial(crl));
if (serial.ptr)
{
whack_log(RC_COMMENT, " serial: %#B", &serial);
diff --git a/src/pluto/crypto.c b/src/pluto/crypto.c
index f01966c72..a4f678222 100644
--- a/src/pluto/crypto.c
+++ b/src/pluto/crypto.c
@@ -30,7 +30,7 @@ static struct encrypt_desc encrypt_desc_3des =
algo_id: OAKLEY_3DES_CBC,
plugin_name: NULL,
algo_next: NULL,
-
+
enc_blocksize: DES_BLOCK_SIZE,
keydeflen: DES_BLOCK_SIZE * 3 * BITS_PER_BYTE,
keyminlen: DES_BLOCK_SIZE * 3 * BITS_PER_BYTE,
diff --git a/src/pluto/defs.c b/src/pluto/defs.c
index f83318e12..7f3a819de 100644
--- a/src/pluto/defs.c
+++ b/src/pluto/defs.c
@@ -16,6 +16,7 @@
#include <string.h>
#include <stdio.h>
#include <dirent.h>
+#include <inttypes.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -91,8 +92,7 @@ mv_chunk(u_char **pos, chunk_t content)
const char*
check_expiry(time_t expiration_date, int warning_interval, bool strict)
{
- time_t now;
- int time_left;
+ time_t now, time_left;
if (expiration_date == UNDEFINED_TIME)
return "ok (expires never)";
@@ -125,8 +125,8 @@ check_expiry(time_t expiration_date, int warning_interval, bool strict)
time_left /= 60;
unit = "minute";
}
- snprintf(buf, 35, "warning (expires in %d %s%s)", time_left,
- unit, (time_left == 1)?"":"s");
+ snprintf(buf, 35, "warning (expires in %" PRIu64 " %s%s)",
+ (u_int64_t)time_left, unit, (time_left == 1) ? "" : "s");
return buf;
}
}
diff --git a/src/pluto/demux.c b/src/pluto/demux.c
index 294601295..612e0813c 100644
--- a/src/pluto/demux.c
+++ b/src/pluto/demux.c
@@ -544,7 +544,7 @@ init_demux(void)
* - ip(7) describes IP_RECVERR
* - recvmsg(2) describes MSG_ERRQUEUE
* - readv(2) describes iovec
- * - cmsg(3) describes how to process auxilliary messages
+ * - cmsg(3) describes how to process auxiliary messages
*
* ??? we should link this message with one we've sent
* so that the diagnostic can refer to that negotiation.
@@ -1580,7 +1580,7 @@ process_packet(struct msg_digest **mdp)
/*
* okay, now we have to figure out if we are receiving a bogus
- * new message in an oustanding XAUTH server conversation
+ * new message in an outstanding XAUTH server conversation
* (i.e. a reply to our challenge)
* (this occurs with some broken other implementations).
*
diff --git a/src/pluto/dnskey.c b/src/pluto/dnskey.c
index 4f8e4ebf4..91b1b6ac1 100644
--- a/src/pluto/dnskey.c
+++ b/src/pluto/dnskey.c
@@ -60,13 +60,8 @@ void
init_adns(void)
{
const char *adns_path = pluto_adns_option;
-#ifndef USE_LWRES
static const char adns_name[] = "_pluto_adns";
const char *helper_bin_dir = getenv("IPSEC_LIBDIR");
-#else /* USE_LWRES */
- static const char adns_name[] = "lwdnsq";
- const char *helper_bin_dir = getenv("IPSEC_EXECDIR");
-#endif /* USE_LWRES */
char adns_path_space[4096]; /* plenty long? */
int qfds[2];
int afds[2];
@@ -460,85 +455,6 @@ rr_typename(int type)
}
-#ifdef USE_LWRES
-
-# ifdef USE_KEYRR
-static err_t
-process_lwdnsq_key(u_char *str
-, enum dns_auth_level dns_auth_level
-, struct adns_continuation *const cr)
-{
- /* fields of KEY record. See RFC 2535 3.1 KEY RDATA format. */
- unsigned long flags /* 16 bits */
- , protocol /* 8 bits */
- , algorithm; /* 8 bits */
-
- char *rest = str
- , *p
- , *endofnumber;
-
- /* flags */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq KEY: missing flags";
-
- flags = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq KEY: malformed flags";
-
- /* protocol */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq KEY: missing protocol";
-
- protocol = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq KEY: malformed protocol";
-
- /* algorithm */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq KEY: missing algorithm";
-
- algorithm = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq KEY: malformed algorithm";
-
- /* is this key interesting? */
- if (protocol == 4 /* IPSEC (RFC 2535 3.1.3) */
- && algorithm == 1 /* RSA/MD5 (RFC 2535 3.2) */
- && (flags & 0x8000ul) == 0 /* use for authentication (3.1.2) */
- && (flags & 0x2CF0ul) == 0) /* must be zero */
- {
- /* Decode base 64 encoding of key.
- * Similar code is in process_txt_rr_body.
- */
- u_char kb[RSA_MAX_ENCODING_BYTES]; /* plenty of space for binary form of public key */
- chunk_t kbc;
- err_t ugh = ttodatav(rest, 0, 64, kb, sizeof(kb), &kbc.len
- , diag_space, sizeof(diag_space), TTODATAV_IGNORESPACE);
-
- if (ugh != NULL)
- return builddiag("malformed key data: %s", ugh);
-
- if (kbc.len > sizeof(kb))
- return builddiag("key data larger than %lu bytes"
- , (unsigned long) sizeof(kb));
-
- kbc.ptr = kb;
- TRY(add_public_key(&cr->id, dns_auth_level, PUBKEY_ALG_RSA, &kbc
- , &cr->keys_from_dns));
-
- /* keep a reference to last one */
- unreference_key(&cr->last_info);
- cr->last_info = reference_key(cr->keys_from_dns->key);
- }
- return NULL;
-}
-# endif /* USE_KEYRR */
-
-#else /* ! USE_LWRES */
-
/* structure of Query Reply (RFC 1035 4.1.1):
*
* +---------------------+
@@ -1218,9 +1134,6 @@ process_dns_answer(struct adns_continuation *const cr
, qr_header.ancount, cr);
}
-#endif /* ! USE_LWRES */
-
-
/****************************************************************/
static err_t build_dns_name(u_char name_buf[NS_MAXDNAME + 2],
@@ -1427,7 +1340,7 @@ err_t start_adns_query(identification_t *id, /* domain to query */
cr->sgw_specified = (sgw_id != NULL);
cr->sgw_id = cr->sgw_specified ?
sgw_id->clone(sgw_id) :
- identification_create_from_string("%any");
+ identification_create_from_string("%any");
cr->gateways_from_dns = NULL;
#ifdef USE_KEYRR
cr->keys_from_dns = NULL;
@@ -1515,21 +1428,6 @@ send_unsent_ADNS_queries(void)
break; /* done! */
}
-#ifdef USE_LWRES
- next_query->used = FALSE;
- {
- /* NOTE STATIC: */
- static unsigned char qbuf[LWDNSQ_CMDBUF_LEN + 1]; /* room for NUL */
-
- snprintf(qbuf, sizeof(qbuf), "%s %lu %s\n"
- , rr_typename(next_query->type)
- , next_query->qtid
- , next_query->query.name_buf);
- DBG(DBG_DNS, DBG_log("lwdnsq query: %.*s", (int)(strlen(qbuf) - 1), qbuf));
- buf_cur = qbuf;
- buf_end = qbuf + strlen(qbuf);
- }
-#else /* !USE_LWRES */
next_query->query.debugging = next_query->debugging;
next_query->query.serial = next_query->qtid;
next_query->query.len = sizeof(next_query->query);
@@ -1537,210 +1435,13 @@ send_unsent_ADNS_queries(void)
next_query->query.type = next_query->type;
buf_cur = (const void *)&next_query->query;
buf_end = buf_cur + sizeof(next_query->query);
-#endif /* !USE_LWRES */
+
next_query = next_query->next;
adns_in_flight++;
}
}
}
-#ifdef USE_LWRES
-/* Process a line of lwdnsq answer.
- * Returns with error message iff lwdnsq result is malformed.
- * Most errors will be in DNS data and will be handled by cr->cont_fn.
- */
-static err_t process_lwdnsq_answer(char *ts)
-{
- err_t ugh = NULL;
- char *rest;
- char *p;
- char *endofnumber;
- struct adns_continuation *cr = NULL;
- unsigned long qtid;
- time_t anstime; /* time of answer */
- char *atype; /* type of answer */
- long ttl; /* ttl of answer; int, but long for conversion */
- bool AuthenticatedData = FALSE;
- static char scratch_null_str[] = ""; /* cannot be const, but isn't written */
-
- /* query transaction id */
- rest = ts;
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq: answer missing query transaction ID";
-
- qtid = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq: malformed query transaction ID";
-
- cr = continuation_for_qtid(qtid);
- if (qtid != 0 && cr == NULL)
- return "lwdnsq: unrecognized qtid"; /* can't happen! */
-
- /* time */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq: missing time";
-
- anstime = strtoul(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq: malformed time";
-
- /* TTL */
- p = strsep(&rest, " \t");
- if (p == NULL)
- return "lwdnsq: missing TTL";
-
- ttl = strtol(p, &endofnumber, 10);
- if (*endofnumber != '\0')
- return "lwdnsq: malformed TTL";
-
- /* type */
- atype = strsep(&rest, " \t");
- if (atype == NULL)
- return "lwdnsq: missing type";
-
- /* if rest is NULL, make it "", otherwise eat whitespace after type */
- rest = rest == NULL? scratch_null_str : rest + strspn(rest, " \t");
-
- if (strncasecmp(atype, "AD-", 3) == 0)
- {
- AuthenticatedData = TRUE;
- atype += 3;
- }
-
- /* deal with each type */
-
- if (cr == NULL)
- {
- /* we don't actually know which this applies to */
- return builddiag("lwdnsq: 0 qtid invalid with %s", atype);
- }
- else if (strcaseeq(atype, "START"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "DONE"))
- {
- if (!cr->used)
- {
- /* "no results returned by lwdnsq" should not happen */
- cr->cont_fn(cr
- , cr->gateways_from_dns == NULL
-#ifdef USE_KEYRR
- && cr->keys_from_dns == NULL
-#endif /* USE_KEYRR */
- ? "no results returned by lwdnsq" : NULL);
- cr->used = TRUE;
- }
- reset_globals();
- release_adns_continuation(cr);
- adns_in_flight--;
- }
- else if (strcaseeq(atype, "RETRY"))
- {
- if (!cr->used)
- {
- cr->cont_fn(cr, rest);
- cr->used = TRUE;
- }
- }
- else if (strcaseeq(atype, "FATAL"))
- {
- if (!cr->used)
- {
- cr->cont_fn(cr, rest);
- cr->used = TRUE;
- }
- }
- else if (strcaseeq(atype, "DNSSEC"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "NAME"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "TXT"))
- {
- char *end = rest + strlen(rest);
- err_t txt_ugh;
-
- if (*rest == '"' && end[-1] == '"')
- {
- /* strip those pesky quotes */
- rest++;
- *--end = '\0';
- }
-
- txt_ugh = process_txt_rr_body(rest
- , TRUE
- , AuthenticatedData? DAL_SIGNED : DAL_NOTSEC
- , cr);
-
- if (txt_ugh != NULL)
- {
- DBG(DBG_DNS,
- DBG_log("error processing TXT resource record (%s) while processing: %s"
- , txt_ugh, rest));
- cr->cont_fn(cr, txt_ugh);
- cr->used = TRUE;
- }
- }
- else if (strcaseeq(atype, "SIG"))
- {
- /* record the SIG records for posterity */
- if (cr->last_info != NULL)
- {
- free(cr->last_info->dns_sig);
- cr->last_info->dns_sig = clone_str(rest);
- }
- }
- else if (strcaseeq(atype, "A"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "AAAA"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "CNAME"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "CNAMEFROM"))
- {
- /* ignore */
- }
- else if (strcaseeq(atype, "PTR"))
- {
- /* ignore */
- }
-#ifdef USE_KEYRR
- else if (strcaseeq(atype, "KEY"))
- {
- err_t key_ugh = process_lwdnsq_key(rest
- , AuthenticatedData? DAL_SIGNED : DAL_NOTSEC
- , cr);
-
- if (key_ugh != NULL)
- {
- DBG(DBG_DNS,
- DBG_log("error processing KEY resource record (%s) while processing: %s"
- , key_ugh, rest));
- cr->cont_fn(cr, key_ugh);
- cr->used = TRUE;
- }
- }
-#endif /* USE_KEYRR */
- else
- {
- ugh = "lwdnsq: unrecognized type";
- }
- return ugh;
-}
-#endif /* USE_LWRES */
-
static void recover_adns_die(void)
{
struct adns_continuation *cr = NULL;
@@ -1779,12 +1480,7 @@ void handle_adns_answer(void)
{
/* These are retained across calls to handle_adns_answer. */
static size_t buflen = 0; /* bytes in answer buffer */
-#ifndef USE_LWRES
static struct adns_answer buf;
-#else /* USE_LWRES */
- static char buf[LWDNSQ_RESULT_LEN_MAX];
- static char buf_copy[LWDNSQ_RESULT_LEN_MAX];
-#endif /* USE_LWRES */
ssize_t n;
@@ -1826,7 +1522,6 @@ void handle_adns_answer(void)
}
buflen += n;
-#ifndef USE_LWRES
while (buflen >= offsetof(struct adns_answer, ans) && buflen >= buf.len)
{
/* we've got a tasty answer -- process it */
@@ -1892,36 +1587,4 @@ void handle_adns_answer(void)
buflen -= buf.len;
memmove((unsigned char *)&buf, (unsigned char *)&buf + buf.len, buflen);
}
-#else /* USE_LWRES */
- for (;;)
- {
- err_t ugh;
- char *nlp = memchr(buf, '\n', buflen);
-
- if (nlp == NULL)
- break;
-
- /* we've got a line */
- *nlp++ = '\0';
-
- DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL | DBG_DNS
- , DBG_log("lwdns: %s", buf));
-
- /* process lwdnsq_answer may modify buf, so make a copy. */
- buf_copy[0]='\0';
- strncat(buf_copy, buf, sizeof(buf_copy));
-
- ugh = process_lwdnsq_answer(buf_copy);
- if (ugh != NULL)
- plog("failure processing lwdnsq output: %s; record: %s"
- , ugh, buf);
-
- passert(GLOBALS_ARE_RESET());
- reset_globals();
-
- /* shift out answer that we've consumed */
- buflen -= nlp - buf;
- memmove(buf, nlp, buflen);
- }
-#endif /* USE_LWRES */
}
diff --git a/src/pluto/dnskey.h b/src/pluto/dnskey.h
index d26a0e64f..39a406cbd 100644
--- a/src/pluto/dnskey.h
+++ b/src/pluto/dnskey.h
@@ -47,14 +47,7 @@ struct adns_continuation {
#endif
struct adns_continuation *previous, *next;
struct pubkey *last_info; /* the last structure we accumulated */
-#ifdef USE_LWRES
- bool used; /* have we called the cont_fn yet? */
- struct {
- u_char name_buf[NS_MAXDNAME + 2];
- } query;
-#else /* ! USE_LWRES */
struct adns_query query;
-#endif /* ! USE_LWRES */
};
extern err_t start_adns_query(identification_t *id /* domain to query */
diff --git a/src/pluto/event_queue.c b/src/pluto/event_queue.c
index 55d064f26..602a013ee 100644
--- a/src/pluto/event_queue.c
+++ b/src/pluto/event_queue.c
@@ -147,13 +147,13 @@ METHOD(event_queue_t, destroy, void,
free(this);
}
-bool set_nonblock(int socket)
+static bool set_nonblock(int socket)
{
int flags = fcntl(socket, F_GETFL);
return flags != -1 && fcntl(socket, F_SETFL, flags | O_NONBLOCK) != -1;
}
-bool set_cloexec(int socket)
+static bool set_cloexec(int socket)
{
int flags = fcntl(socket, F_GETFD);
return flags != -1 && fcntl(socket, F_SETFD, flags | FD_CLOEXEC) != -1;
diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c
index c8a347b45..3e7adcc40 100644
--- a/src/pluto/ipsec_doi.c
+++ b/src/pluto/ipsec_doi.c
@@ -3862,10 +3862,11 @@ main_id_and_auth(struct msg_digest *md
if (r == STF_SUSPEND)
{
+ err_t ugh = NULL;
+#ifdef ADNS
/* initiate/resume asynchronous DNS lookup for key */
struct key_continuation *nkc = malloc_thing(struct key_continuation);
enum key_oppo_step step_done = kc == NULL? kos_null : kc->step;
- err_t ugh = NULL;
/* Record that state is used by a suspended md */
passert(st->st_suspended_md == NULL);
@@ -3896,7 +3897,9 @@ main_id_and_auth(struct msg_digest *md
default:
bad_case(step_done);
}
-
+#else /* ADNS */
+ ugh = "adns not supported";
+#endif /* ADNS */
if (ugh != NULL)
{
report_key_dns_failure(peer, ugh);
@@ -4444,6 +4447,8 @@ stf_status quick_inI1_outR1(struct msg_digest *md)
return quick_inI1_outR1_tail(&b, NULL);
}
+#ifdef ADNS
+
static void
report_verify_failure(struct verify_oppo_bundle *b, err_t ugh)
{
@@ -4808,6 +4813,8 @@ static enum verify_oppo_step quick_inI1_outR1_process_answer(
return next_step;
}
+#endif /* ADNS */
+
static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b,
struct adns_continuation *ac)
{
@@ -4871,6 +4878,7 @@ static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b,
*/
if (p->policy & POLICY_OPPO)
{
+#ifdef ADNS
/* Opportunistic case: delegation must be verified.
* Here be dragons.
*/
@@ -4925,6 +4933,11 @@ static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b,
*/
p = oppo_instantiate(p, &c->spd.that.host_addr, c->spd.that.id
, NULL, &our_client, &his_client);
+#else /* ADNS */
+ plog("opportunistic connections not supported because"
+ " adns is not available");
+ return STF_INTERNAL_ERROR;
+#endif /* ADNS */
}
else
{
diff --git a/src/pluto/kernel.c b/src/pluto/kernel.c
index 8bed1fcfc..e4729ef08 100644
--- a/src/pluto/kernel.c
+++ b/src/pluto/kernel.c
@@ -23,10 +23,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
-#include <wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/queue.h>
+#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/socket.h>
@@ -780,8 +780,9 @@ static bool raw_eroute(const ip_address *this_host,
host_t *host_src, *host_dst;
policy_type_t type = POLICY_IPSEC;
policy_dir_t dir = POLICY_OUT;
+ policy_priority_t priority = POLICY_PRIORITY_DEFAULT;
char text_said[SATOT_BUF];
- bool ok = TRUE, routed = FALSE,
+ bool ok = TRUE,
deleting = (op & ERO_MASK) == ERO_DELETE,
replacing = op & (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT);
@@ -819,7 +820,7 @@ static bool raw_eroute(const ip_address *this_host,
{
return TRUE;
}
- routed = TRUE;
+ priority = POLICY_PRIORITY_ROUTED;
break;
}
}
@@ -837,14 +838,14 @@ static bool raw_eroute(const ip_address *this_host,
if (deleting || replacing)
{
hydra->kernel_interface->del_policy(hydra->kernel_interface,
- ts_src, ts_dst, dir, mark, routed);
+ ts_src, ts_dst, dir, sa->reqid, mark, priority);
}
if (!deleting)
{
ok = hydra->kernel_interface->add_policy(hydra->kernel_interface,
host_src, host_dst, ts_src, ts_dst, dir, type, sa,
- mark, routed) == SUCCESS;
+ mark, priority) == SUCCESS;
}
if (dir == POLICY_IN)
@@ -853,7 +854,7 @@ static bool raw_eroute(const ip_address *this_host,
if (deleting || replacing)
{
hydra->kernel_interface->del_policy(hydra->kernel_interface,
- ts_src, ts_dst, dir, mark, routed);
+ ts_src, ts_dst, dir, sa->reqid, mark, priority);
}
if (!deleting && ok &&
@@ -861,7 +862,7 @@ static bool raw_eroute(const ip_address *this_host,
{
ok = hydra->kernel_interface->add_policy(hydra->kernel_interface,
host_src, host_dst, ts_src, ts_dst, dir, type, sa,
- mark, routed) == SUCCESS;
+ mark, priority) == SUCCESS;
}
}
diff --git a/src/pluto/kernel_alg.c b/src/pluto/kernel_alg.c
index eab2a8f06..b4b18fd80 100644
--- a/src/pluto/kernel_alg.c
+++ b/src/pluto/kernel_alg.c
@@ -205,7 +205,7 @@ bool kernel_alg_esp_ok_final(u_int ealg, u_int key_len, u_int aalg,
/*
* key_len passed comes from esp_attrs read from peer
- * For many older algoritms (eg 3DES) this key_len is fixed
+ * For many older algorithms (eg 3DES) this key_len is fixed
* and get passed as 0.
* ... then get default key_len
*/
diff --git a/src/pluto/keys.c b/src/pluto/keys.c
index 4b0e08791..c5adbfd11 100644
--- a/src/pluto/keys.c
+++ b/src/pluto/keys.c
@@ -27,10 +27,12 @@
#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
#include <sys/queue.h>
+#ifdef HAVE_GLOB_H
#include <glob.h>
#ifndef GLOB_ABORTED
# define GLOB_ABORTED GLOB_ABEND /* fix for old versions */
#endif
+#endif
#include <freeswan.h>
@@ -833,14 +835,7 @@ static void process_secret(secret_t *s, int whackfd)
err_t ugh = NULL;
s->kind = SECRET_PSK; /* default */
- if (*tok == '"' || *tok == '\'')
- {
- log_psk("PSK", s);
-
- /* old PSK format: just a string */
- ugh = process_psk_secret(&s->u.preshared_secret);
- }
- else if (tokeqword("psk"))
+ if (tokeqword("psk"))
{
log_psk("PSK", s);
@@ -987,13 +982,7 @@ static void process_secret_records(int whackfd)
for (;;)
{
- if (tok[0] == '"' || tok[0] == '\'')
- {
- /* found key part */
- process_secret(s, whackfd);
- break;
- }
- else if (tokeq(":"))
+ if (tokeq(":"))
{
/* found key part */
shift(); /* discard explicit separator */
@@ -1033,7 +1022,6 @@ static void process_secrets_file(const char *file_pat, int whackfd)
{
struct file_lex_position pos;
char **fnp;
- glob_t globbuf;
pos.depth = flp == NULL? 0 : flp->depth + 1;
@@ -1043,8 +1031,10 @@ static void process_secrets_file(const char *file_pat, int whackfd)
return;
}
+#ifdef HAVE_GLOB_H
/* do globbing */
{
+ glob_t globbuf;
int r = glob(file_pat, GLOB_ERR, globugh, &globbuf);
if (r != 0)
@@ -1066,21 +1056,31 @@ static void process_secrets_file(const char *file_pat, int whackfd)
globfree(&globbuf);
return;
}
- }
- /* for each file... */
- for (fnp = globbuf.gl_pathv; *fnp != NULL; fnp++)
- {
- if (lexopen(&pos, *fnp, FALSE))
+ /* for each file... */
+ for (fnp = globbuf.gl_pathv; *fnp != NULL; fnp++)
{
- plog("loading secrets from \"%s\"", *fnp);
- (void) flushline("file starts with indentation (continuation notation)");
- process_secret_records(whackfd);
- lexclose();
+ if (lexopen(&pos, *fnp, FALSE))
+ {
+ plog("loading secrets from \"%s\"", *fnp);
+ flushline("file starts with indentation (continuation notation)");
+ process_secret_records(whackfd);
+ lexclose();
+ }
}
- }
- globfree(&globbuf);
+ globfree(&globbuf);
+ }
+#else /* HAVE_GLOB_H */
+ /* if glob(3) is not available, try to load pattern directly */
+ if (lexopen(&pos, file_pat, FALSE))
+ {
+ plog("loading secrets from \"%s\"", file_pat);
+ flushline("file starts with indentation (continuation notation)");
+ process_secret_records(whackfd);
+ lexclose();
+ }
+#endif /* HAVE_GLOB_H */
}
void free_preshared_secrets(void)
@@ -1435,6 +1435,7 @@ void remove_x509_public_key(const cert_t *cert)
void list_public_keys(bool utc)
{
pubkey_list_t *p = pubkeys;
+ chunk_t serial;
if (p != NULL)
{
@@ -1465,7 +1466,8 @@ void list_public_keys(bool utc)
}
if (key->serial.len)
{
- whack_log(RC_COMMENT," serial: %#B", &key->serial);
+ serial = chunk_skip_zero(key->serial);
+ whack_log(RC_COMMENT," serial: %#B", &serial);
}
p = p->next;
}
diff --git a/src/pluto/lex.h b/src/pluto/lex.h
index f16769144..aa0be7829 100644
--- a/src/pluto/lex.h
+++ b/src/pluto/lex.h
@@ -22,7 +22,7 @@ struct file_lex_position
int lino; /* line number in file */
char buffer[MAX_TOK_LEN + 1]; /* note: one extra char for our use (jamming '"') */
char *cur; /* cursor */
- char under; /* except in shift(): character orignally at *cur */
+ char under; /* except in shift(): character originally at *cur */
struct file_lex_position *previous;
};
diff --git a/src/pluto/log.c b/src/pluto/log.c
index c5f1776ec..f6fa226d5 100644
--- a/src/pluto/log.c
+++ b/src/pluto/log.c
@@ -28,6 +28,10 @@
#include <sys/stat.h>
#include <sys/types.h>
+#ifdef ANDROID
+#include <android/log.h>
+#endif
+
#include <freeswan.h>
#include <library.h>
#include <debug.h>
@@ -124,7 +128,11 @@ static void pluto_dbg(debug_t group, level_t level, char *fmt, ...)
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
}
- if (log_to_syslog)
+ if (log_to_syslog
+#ifdef ANDROID
+ || TRUE
+#endif
+ )
{
/* write in memory buffer first */
vsnprintf(buffer, sizeof(buffer), fmt, args);
@@ -138,6 +146,11 @@ static void pluto_dbg(debug_t group, level_t level, char *fmt, ...)
*(next++) = '\0';
}
syslog(priority, "%s%s\n", (level > 1)? "| ":"", current);
+#ifdef ANDROID
+ __android_log_print(level > 1 ? ANDROID_LOG_DEBUG
+ : ANDROID_LOG_INFO, "pluto",
+ "%s%s\n", level > 1 ? "| " : "", current);
+#endif
current = next;
}
}
@@ -497,6 +510,9 @@ plog(const char *message, ...)
syslog(LOG_WARNING, "%s", m);
if (log_to_perpeer)
peerlog("", m);
+#ifdef ANDROID
+ __android_log_print(ANDROID_LOG_WARN, "pluto", "%s\n", m);
+#endif
whack_log(RC_LOG, "~%s", m);
}
@@ -517,6 +533,9 @@ loglog(int mess_no, const char *message, ...)
syslog(LOG_WARNING, "%s", m);
if (log_to_perpeer)
peerlog("", m);
+#ifdef ANDROID
+ __android_log_print(ANDROID_LOG_WARN, "pluto", "%s\n", m);
+#endif
whack_log(mess_no, "~%s", m);
}
@@ -536,9 +555,11 @@ log_errno_routine(int e, const char *message, ...)
if (log_to_syslog)
syslog(LOG_ERR, "ERROR: %s. Errno %d: %s", m, e, strerror(e));
if (log_to_perpeer)
- {
peerlog(strerror(e), m);
- }
+#ifdef ANDROID
+ __android_log_print(ANDROID_LOG_ERROR, "pluto", "ERROR: %s. Errno %d: %s\n",
+ m, e, strerror(e));
+#endif
whack_log(RC_LOG_SERIOUS
, "~ERROR: %s. Errno %d: %s", m, e, strerror(e));
@@ -560,6 +581,9 @@ exit_log(const char *message, ...)
syslog(LOG_ERR, "FATAL ERROR: %s", m);
if (log_to_perpeer)
peerlog("FATAL ERROR: ", m);
+#ifdef ANDROID
+ __android_log_print(ANDROID_LOG_ERROR, "pluto", "FATAL ERROR: %s\n", m);
+#endif
whack_log(RC_LOG_SERIOUS, "~FATAL ERROR: %s", m);
@@ -582,6 +606,10 @@ exit_log_errno_routine(int e, const char *message, ...)
syslog(LOG_ERR, "FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
if (log_to_perpeer)
peerlog(strerror(e), m);
+#ifdef ANDROID
+ __android_log_print(ANDROID_LOG_ERROR, "pluto", "FATAL ERROR: %s. "
+ "Errno %d: %s\n", m, e, strerror(e));
+#endif
whack_log(RC_LOG_SERIOUS
, "~FATAL ERROR: %s. Errno %d: %s", m, e, strerror(e));
@@ -631,6 +659,9 @@ whack_log(int mess_no, const char *message, ...)
syslog(LOG_WARNING, "%s", m + prelen);
if (log_to_perpeer)
peerlog("", m);
+#ifdef ANDROID
+ __android_log_print(ANDROID_LOG_WARN, "pluto", "%s\n", m + prelen);
+#endif
}
#endif
@@ -763,6 +794,9 @@ DBG_log(const char *message, ...)
syslog(LOG_DEBUG, "| %s", m);
if (log_to_perpeer)
peerlog("| ", m);
+#ifdef ANDROID
+ __android_log_print(ANDROID_LOG_DEBUG, "pluto", "| %s\n", m);
+#endif
}
/* dump raw bytes in hex to stderr (for lack of any better destination) */
@@ -834,19 +868,8 @@ DBG_dump(const char *label, const void *p, size_t len)
static void show_loaded_plugins()
{
- char buf[BUF_LEN];
- plugin_t *plugin;
- int len = 0;
- enumerator_t *enumerator;
-
- buf[0] = '\0';
- enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
- while (len < BUF_LEN && enumerator->enumerate(enumerator, &plugin))
- {
- len += snprintf(&buf[len], BUF_LEN-len, "%s ", plugin->get_name(plugin));
- }
- enumerator->destroy(enumerator);
- whack_log(RC_COMMENT, "loaded plugins: %s", buf);
+ whack_log(RC_COMMENT, "loaded plugins: %s",
+ lib->plugins->loaded_plugins(lib->plugins));
}
void show_status(bool all, const char *name)
diff --git a/src/pluto/myid.c b/src/pluto/myid.c
index ad4eefd15..c90d14ef8 100644
--- a/src/pluto/myid.c
+++ b/src/pluto/myid.c
@@ -72,7 +72,7 @@ void set_myid(enum myid_state s, char *idstr)
if (idstr)
{
myids[s]->destroy(myids[s]);
- myids[s] = identification_create_from_string(idstr);
+ myids[s] = identification_create_from_string(idstr);
if (s == MYID_SPECIFIED)
{
myid_state = MYID_SPECIFIED;
diff --git a/src/pluto/nat_traversal.c b/src/pluto/nat_traversal.c
index 5e9353b72..28be76825 100644
--- a/src/pluto/nat_traversal.c
+++ b/src/pluto/nat_traversal.c
@@ -232,7 +232,7 @@ void nat_traversal_natd_lookup(struct msg_digest *md)
if (i < 2)
{
loglog(RC_LOG_SERIOUS,
- "NAT-Traversal: Only %d NAT-D - Aborting NAT-Traversal negociation", i);
+ "NAT-Traversal: Only %d NAT-D - Aborting NAT-Traversal negotiation", i);
st->nat_traversal = 0;
return;
}
diff --git a/src/pluto/ocsp.c b/src/pluto/ocsp.c
index f5ee07398..c299e3d39 100644
--- a/src/pluto/ocsp.c
+++ b/src/pluto/ocsp.c
@@ -607,24 +607,24 @@ void list_ocsp_locations(ocsp_location_t *location, bool requests,
}
while (certinfo)
{
+ chunk_t serial = chunk_skip_zero(certinfo->serialNumber);
+
if (requests)
{
whack_log(RC_COMMENT, " serial: %#B, %d trials",
- &certinfo->serialNumber, certinfo->trials);
+ &serial, certinfo->trials);
}
else if (certinfo->once)
{
whack_log(RC_COMMENT, " serial: %#B, %s, once%s",
- &certinfo->serialNumber,
- cert_status_names[certinfo->status],
+ &serial, cert_status_names[certinfo->status],
(certinfo->nextUpdate < time(NULL))? " (expired)": "");
}
else
{
whack_log(RC_COMMENT, " serial: %#B, %s, until %T %s",
- &certinfo->serialNumber,
- cert_status_names[certinfo->status],
- &certinfo->nextUpdate, utc,
+ &serial, cert_status_names[certinfo->status],
+ &certinfo->nextUpdate, utc,
check_expiry(certinfo->nextUpdate, OCSP_WARNING_INTERVAL, strict));
}
certinfo = certinfo->next;
@@ -1144,9 +1144,9 @@ static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
*cert = cert_empty;
cert->cert = lib->creds->create(lib->creds,
- CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, object,
- BUILD_END);
+ CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER, object,
+ BUILD_END);
if (cert->cert == NULL)
{
DBG(DBG_CONTROL | DBG_PARSING,
diff --git a/src/pluto/plugin_list.c b/src/pluto/plugin_list.c
new file mode 100644
index 000000000..499218904
--- /dev/null
+++ b/src/pluto/plugin_list.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 Martin Willi, revosec AG
+ * Copyright (C) 2011 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 <whack.h>
+#include <log.h>
+
+#include <library.h>
+#include <utils/linked_list.h>
+
+/**
+ * List loaded plugin information
+ */
+void plugin_list(void)
+{
+ plugin_feature_t *features, *fp;
+ enumerator_t *enumerator;
+ linked_list_t *list;
+ plugin_t *plugin;
+ int count, i;
+ bool loaded;
+ char *str;
+
+ whack_log(RC_COMMENT, " ");
+ whack_log(RC_COMMENT, "List of loaded Plugins:");
+ whack_log(RC_COMMENT, " ");
+
+ enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
+ while (enumerator->enumerate(enumerator, &plugin, &list))
+ {
+ whack_log(RC_COMMENT, "%s:", plugin->get_name(plugin));
+ if (plugin->get_features)
+ {
+ count = plugin->get_features(plugin, &features);
+ for (i = 0; i < count; i++)
+ {
+ str = plugin_feature_get_string(&features[i]);
+ switch (features[i].kind)
+ {
+ case FEATURE_PROVIDE:
+ fp = &features[i];
+ loaded = list->find_first(list, NULL,
+ (void**)&fp) == SUCCESS;
+ whack_log(RC_COMMENT, " %s%s",
+ str, loaded ? "" : " (not loaded)");
+ break;
+ case FEATURE_DEPENDS:
+ whack_log(RC_COMMENT, " %s", str);
+ break;
+ case FEATURE_SDEPEND:
+ whack_log(RC_COMMENT, " %s(soft)", str);
+ break;
+ default:
+ break;
+ }
+ free(str);
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+}
diff --git a/src/pluto/plugin_list.h b/src/pluto/plugin_list.h
new file mode 100644
index 000000000..62e4a167d
--- /dev/null
+++ b/src/pluto/plugin_list.h
@@ -0,0 +1,21 @@
+/* Generates a list of all loaded plugins and their dependencies
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef _PLUGIN_LIST_H
+#define _PLUGIN_LIST_H
+
+extern void plugin_list(void);
+
+#endif /* _PLUGIN_LIST_H */
diff --git a/src/pluto/plugins/xauth/Makefile.in b/src/pluto/plugins/xauth/Makefile.in
index 3ae6ea12b..5a575548e 100644
--- a/src/pluto/plugins/xauth/Makefile.in
+++ b/src/pluto/plugins/xauth/Makefile.in
@@ -190,6 +190,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -198,6 +201,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -214,11 +218,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -262,6 +268,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/pluto/plugins/xauth/xauth_default_verifier.c b/src/pluto/plugins/xauth/xauth_default_verifier.c
index 776f77134..ca2e36aa0 100644
--- a/src/pluto/plugins/xauth/xauth_default_verifier.c
+++ b/src/pluto/plugins/xauth/xauth_default_verifier.c
@@ -43,6 +43,13 @@ METHOD(xauth_verifier_t, verify_secret, bool,
if (get_xauth_secret(user, server, &xauth_secret))
{
success = chunk_equals(secret, xauth_secret);
+
+ if (!success && secret.len && secret.ptr[secret.len - 1] == 0)
+ { /* fix for null-terminated passwords (e.g. from Android 4) */
+ secret.len--;
+ success = chunk_equals(secret, xauth_secret);
+ }
+
chunk_clear(&xauth_secret);
}
return success;
diff --git a/src/pluto/pluto.8 b/src/pluto/pluto.8
index 9ac537bd9..ed6f78050 100644
--- a/src/pluto/pluto.8
+++ b/src/pluto/pluto.8
@@ -1437,7 +1437,7 @@ Phase 1.
\fBPluto\fP responds to \fBSIGHUP\fP by issuing a suggestion that ``\fBwhack\fP
\-\-listen'' might have been intended.
.LP
-\fBPluto\fP exits when it recieves \fBSIGTERM\fP.
+\fBPluto\fP exits when it receives \fBSIGTERM\fP.
.SH EXIT STATUS
.LP
\fBpluto\fP normally forks a daemon process, so the exit status is
@@ -1558,7 +1558,7 @@ There is no good way for a connection to be automatically terminated.
This is a problem for Road Warrior and Opportunistic connections.
The \fB\-\-dontrekey\fP option does prevent the SAs from
being rekeyed on expiry.
-Additonally, if a Road Warrior connection has a client subnet with a fixed IP
+Additionally, if a Road Warrior connection has a client subnet with a fixed IP
address, a negotiation with that subnet will cause any other
connection instantiations with that same subnet to be unoriented
(deleted, in effect).
diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c
index 309bde649..dbc857ce2 100644
--- a/src/pluto/plutomain.c
+++ b/src/pluto/plutomain.c
@@ -22,6 +22,7 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/socket.h>
#include <sys/un.h>
#include <fcntl.h>
#include <getopt.h>
@@ -29,6 +30,7 @@
#include <arpa/nameser.h> /* missing from <resolv.h> on old systems */
#include <sys/queue.h>
#include <sys/prctl.h>
+#include <signal.h>
#include <pwd.h>
#include <grp.h>
@@ -79,11 +81,32 @@
#include "whack_attribute.h"
#include "pluto.h"
+#ifdef ANDROID
+#include <private/android_filesystem_config.h> /* for AID_VPN */
+#endif
+
/**
* Number of threads in the thread pool, if not specified in config.
*/
#define DEFAULT_THREADS 4
+/**
+ * PID file, in which pluto stores its process id
+ */
+static char pluto_lock[sizeof(ctl_addr.sun_path)] = DEFAULT_CTLBASE LOCK_SUFFIX;
+
+/**
+ * TRUE if the lock has been checked. This helps to avoid any unintended
+ * deletion of the lock or control socket.
+ */
+static bool pluto_lock_checked = FALSE;
+
+/**
+ * Global reference to PID file (required to truncate, if undeletable)
+ */
+static FILE *pidfile = NULL;
+
+
static void usage(const char *mess)
{
if (mess != NULL && *mess != '\0')
@@ -148,59 +171,66 @@ static void usage(const char *mess)
exit_pluto(mess == NULL? 0 : 1);
}
-
-/* lock file support
- * - provides convenient way for scripts to find Pluto's pid
- * - prevents multiple Plutos competing for the same port
- * - same basename as unix domain control socket
- * NOTE: will not take account of sharing LOCK_DIR with other systems.
- */
-
-static char pluto_lock[sizeof(ctl_addr.sun_path)] = DEFAULT_CTLBASE LOCK_SUFFIX;
-static bool pluto_lock_created = FALSE;
-
-/* create lockfile, or die in the attempt */
-static int create_lock(void)
+static bool check_lock()
{
- int fd = open(pluto_lock, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC
- , S_IRUSR | S_IRGRP | S_IROTH);
+ struct stat stb;
+ FILE *fpid;
- if (fd < 0)
+ if (stat(pluto_lock, &stb) == 0)
{
- if (errno == EEXIST)
- {
- fprintf(stderr, "pluto: lock file \"%s\" already exists\n"
- , pluto_lock);
- exit_pluto(10);
- }
- else
+ fpid = fopen(pluto_lock, "r");
+ if (fpid)
{
- fprintf(stderr
- , "pluto: unable to create lock file \"%s\" (%d %s)\n"
- , pluto_lock, errno, strerror(errno));
- exit_pluto(1);
+ char buf[64];
+ pid_t pid = 0;
+
+ memset(buf, 0, sizeof(buf));
+ if (fread(buf, 1, sizeof(buf), fpid))
+ {
+ buf[sizeof(buf) - 1] = '\0';
+ pid = atoi(buf);
+ }
+ fclose(fpid);
+ if (pid && kill(pid, 0) == 0)
+ { /* such a process is running */
+ return TRUE;
+ }
}
+ fprintf(stderr, "pluto: removing lock file \"%s\", process not "
+ "running\n", pluto_lock);
+ unlink(pluto_lock);
}
- pluto_lock_created = TRUE;
- return fd;
+ pluto_lock_checked = TRUE;
+ return FALSE;
}
-static bool fill_lock(int lockfd, pid_t pid)
+static void fill_lock(void)
{
- char buf[30]; /* holds "<pid>\n" */
- int len = snprintf(buf, sizeof(buf), "%u\n", (unsigned int) pid);
- bool ok = len > 0 && write(lockfd, buf, len) == len;
-
- close(lockfd);
- return ok;
+ pidfile = fopen(pluto_lock, "w");
+ if (pidfile)
+ {
+ fprintf(pidfile, "%u\n", (u_int)getpid());
+ fflush(pidfile);
+ }
+ /* keep pidfile open so we can truncate it, if we cannot delete it */
}
static void delete_lock(void)
{
- if (pluto_lock_created)
+ /* because unlinking the PID file may fail, we truncate it to ensure the
+ * daemon can be properly restarted. one probable cause for this is the
+ * combination of not running as root and the effective user lacking
+ * permissions on the parent dir(s) of the PID file */
+ if (pluto_lock_checked)
{
+ if (pidfile)
+ {
+ ignore_result(ftruncate(fileno(pidfile), 0));
+ fclose(pidfile);
+ }
+ unlink(pluto_lock);
+ /* delete this here to avoid that exit_pluto calls delete the socket */
delete_ctl_socket();
- unlink(pluto_lock); /* is noting failure useful? */
}
}
@@ -234,26 +264,6 @@ static const char *pkcs11_init_args = NULL;
/* options read by optionsfrom */
options_t *options;
-/**
- * Log loaded plugins
- */
-static void print_plugins()
-{
- char buf[BUF_LEN];
- plugin_t *plugin;
- int len = 0;
- enumerator_t *enumerator;
-
- buf[0] = '\0';
- enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
- while (len < BUF_LEN && enumerator->enumerate(enumerator, &plugin))
- {
- len += snprintf(&buf[len], BUF_LEN-len, "%s ", plugin->get_name(plugin));
- }
- enumerator->destroy(enumerator);
- DBG1(DBG_DMN, "loaded plugins: %s", buf);
-}
-
int main(int argc, char **argv)
{
bool fork_desired = TRUE;
@@ -263,9 +273,14 @@ int main(int argc, char **argv)
unsigned int keep_alive = 0;
bool force_keepalive = FALSE;
char *virtual_private = NULL;
- int lockfd;
#ifdef CAPABILITIES
- int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
+ int keep[] = {
+ CAP_NET_ADMIN,
+ CAP_NET_BIND_SERVICE,
+#ifdef ANDROID
+ CAP_NET_RAW,
+#endif
+ };
#endif /* CAPABILITIES */
/* initialize library and optionsfrom */
@@ -313,11 +328,7 @@ int main(int argc, char **argv)
{ "perpeerlogbase", required_argument, NULL, 'P' },
{ "perpeerlog", no_argument, NULL, 'l' },
{ "policygroupsdir", required_argument, NULL, 'f' },
-#ifdef USE_LWRES
- { "lwdnsq", required_argument, NULL, 'a' },
-#else /* !USE_LWRES */
{ "adns", required_argument, NULL, 'a' },
-#endif /* !USE_LWRES */
{ "pkcs11module", required_argument, NULL, 'm' },
{ "pkcs11keepstate", no_argument, NULL, 'k' },
{ "pkcs11initargs", required_argument, NULL, 'z' },
@@ -471,11 +482,11 @@ int main(int argc, char **argv)
case 'f': /* --policygroupsdir <policygroups-dir> */
policygroups_dir = optarg;
continue;
-
+#ifdef ADNS
case 'a': /* --adns <pathname> */
pluto_adns_option = optarg;
continue;
-
+#endif
case 'm': /* --pkcs11module <pathname> */
pkcs11_module_path = optarg;
continue;
@@ -545,7 +556,12 @@ int main(int argc, char **argv)
if (optind != argc)
usage("unexpected argument");
reset_debugging();
- lockfd = create_lock();
+
+ if (check_lock())
+ {
+ fprintf(stderr, "pluto: lock file \"%s\" already exists\n", pluto_lock);
+ exit_pluto(10);
+ }
/* select between logging methods */
@@ -598,11 +614,13 @@ int main(int argc, char **argv)
if (pid != 0)
{
- /* parent: die, after filling PID into lock file.
+ /* parent: die
* must not use exit_pluto: lock would be removed!
*/
- exit(fill_lock(lockfd, pid)? 0 : 1);
+ exit(0);
}
+ /* child: fill PID into lock file */
+ fill_lock();
}
if (setsid() < 0)
@@ -617,7 +635,7 @@ int main(int argc, char **argv)
else
{
/* no daemon fork: we have to fill in lock file */
- (void) fill_lock(lockfd, getpid());
+ fill_lock();
fprintf(stdout, "Pluto initialized\n");
fflush(stdout);
}
@@ -637,6 +655,9 @@ int main(int argc, char **argv)
close(fd);
}
+ /* for uncritical pseudo random numbers */
+ srand(time(NULL) + getpid());
+
init_constants();
init_log("pluto");
@@ -660,7 +681,8 @@ int main(int argc, char **argv)
{
exit(SS_RC_INITIALIZATION_FAILED);
}
- print_plugins();
+ DBG1(DBG_DMN, "loaded plugins: %s",
+ lib->plugins->loaded_plugins(lib->plugins));
init_builder();
if (!init_secret() || !init_crypto())
@@ -674,22 +696,24 @@ int main(int argc, char **argv)
init_states();
init_demux();
init_kernel();
+#ifdef ADNS
init_adns();
+#endif
init_myid();
fetch_initialize();
ac_initialize();
whack_attribute_initialize();
/* drop unneeded capabilities and change UID/GID */
- prctl(PR_SET_KEEPCAPS, 1);
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
#ifdef IPSEC_GROUP
{
struct group group, *grp;
- char buf[1024];
+ char buf[1024];
if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 ||
- grp == NULL || setgid(grp->gr_gid) != 0)
+ grp == NULL || setgid(grp->gr_gid) != 0)
{
plog("unable to change daemon group");
abort();
@@ -699,15 +723,22 @@ int main(int argc, char **argv)
#ifdef IPSEC_USER
{
struct passwd passwd, *pwp;
- char buf[1024];
+ char buf[1024];
if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 ||
- pwp == NULL || setuid(pwp->pw_uid) != 0)
+ pwp == NULL || setuid(pwp->pw_uid) != 0)
{
plog("unable to change daemon user");
abort();
}
- }
+ }
+#endif
+#ifdef ANDROID
+ if (setuid(AID_VPN) != 0)
+ {
+ plog("unable to change daemon user");
+ abort();
+ }
#endif
#ifdef CAPABILITIES_LIBCAP
@@ -793,7 +824,9 @@ void exit_pluto(int status)
free_ifaces();
ac_finalize(); /* free X.509 attribute certificates */
scx_finalize(); /* finalize and unload PKCS #11 module */
+#ifdef ADNS
stop_adns();
+#endif
free_md_pool();
free_crypto();
free_myid(); /* free myids */
@@ -803,6 +836,7 @@ void exit_pluto(int status)
delete_lock();
options->destroy(options);
pluto_deinit();
+ lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
lib->plugins->unload(lib->plugins);
libhydra_deinit();
library_deinit();
diff --git a/src/pluto/rcv_whack.c b/src/pluto/rcv_whack.c
index c140095f0..0a7b33ab5 100644
--- a/src/pluto/rcv_whack.c
+++ b/src/pluto/rcv_whack.c
@@ -57,6 +57,7 @@
#include "myid.h"
#include "kernel_alg.h"
#include "ike_alg.h"
+#include "plugin_list.h"
#include "whack_attribute.h"
/* helper variables and function to decode strings from whack message */
@@ -132,6 +133,8 @@ static void key_add_merge(struct key_add_common *oc, identification_t *keyid)
}
}
+#ifdef ADNS
+
static void key_add_continue(struct adns_continuation *ac, err_t ugh)
{
struct key_add_continuation *kc = (void *) ac;
@@ -159,6 +162,8 @@ static void key_add_continue(struct adns_continuation *ac, err_t ugh)
whack_log_fd = NULL_FD;
}
+#endif /* ADNS */
+
static void key_add_request(const whack_message_t *msg)
{
identification_t *key_id;
@@ -189,9 +194,11 @@ static void key_add_request(const whack_message_t *msg)
kc = malloc_thing(struct key_add_continuation);
kc->common = oc;
kc->lookingfor = kaa;
+ ugh = NULL;
switch (kaa)
{
+#ifdef ADNS
case ka_TXT:
ugh = start_adns_query(key_id
, key_id /* same */
@@ -199,6 +206,7 @@ static void key_add_request(const whack_message_t *msg)
, key_add_continue
, &kc->ac);
break;
+#endif /* ADNS */
#ifdef USE_KEYRR
case ka_KEY:
ugh = start_adns_query(key_id
@@ -282,7 +290,7 @@ void whack_handle(int whackctlfd)
{
if (msg.magic == WHACK_BASIC_MAGIC)
{
- /* Only shutdown command. Simpler inter-version compatability. */
+ /* Only shutdown command. Simpler inter-version compatibility. */
if (msg.whack_shutdown)
{
plog("shutting down");
@@ -437,7 +445,9 @@ void whack_handle(int whackctlfd)
plog("listening for IKE messages");
listening = TRUE;
daily_log_reset();
+#ifdef ADNS
reset_adns_restart_count();
+#endif
set_myFQDN();
find_ifaces();
load_preshared_secrets(NULL_FD);
@@ -548,6 +558,11 @@ void whack_handle(int whackctlfd)
kernel_alg_list();
}
+ if (msg.whack_list & LIST_PLUGINS)
+ {
+ plugin_list();
+ }
+
if (msg.whack_key)
{
/* add a public key */
diff --git a/src/pluto/server.c b/src/pluto/server.c
index 4d07843c1..167b1d4c7 100644
--- a/src/pluto/server.c
+++ b/src/pluto/server.c
@@ -222,10 +222,6 @@ use_interface(const char *rifn)
}
}
-#ifndef IPSECDEVPREFIX
-# define IPSECDEVPREFIX "ipsec"
-#endif
-
static struct raw_iface *
find_raw_ifaces4(void)
{
@@ -233,7 +229,7 @@ find_raw_ifaces4(void)
struct ifconf ifconf;
struct ifreq buf[300]; /* for list of interfaces -- arbitrary limit */
struct raw_iface *rifaces = NULL;
- int master_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); /* Get a UDP socket */
+ int master_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); /* Get a UDP socket */
/* get list of interfaces with assigned IPv4 addresses from system */
@@ -401,7 +397,6 @@ find_raw_ifaces6(void)
return rifaces;
}
-#if 1
static int
create_socket(struct raw_iface *ifp, const char *v_name, int port)
{
@@ -414,7 +409,6 @@ create_socket(struct raw_iface *ifp, const char *v_name, int port)
return -1;
}
-#if 1
/* Set socket Nonblocking */
if ((fcntl_flags=fcntl(fd, F_GETFL)) >= 0) {
if (!(fcntl_flags & O_NONBLOCK)) {
@@ -422,7 +416,6 @@ create_socket(struct raw_iface *ifp, const char *v_name, int port)
fcntl(fd, F_SETFL, fcntl_flags);
}
}
-#endif
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
{
@@ -467,7 +460,6 @@ create_socket(struct raw_iface *ifp, const char *v_name, int port)
}
#endif
-#if defined(linux) && defined(KERNEL26_SUPPORT)
{
struct sadb_x_policy policy;
int level, opt;
@@ -509,7 +501,6 @@ create_socket(struct raw_iface *ifp, const char *v_name, int port)
return -1;
}
}
-#endif
setportof(htons(port), &ifp->addr);
if (bind(fd, sockaddrof(&ifp->addr), sockaddrlenof(&ifp->addr)) < 0)
@@ -523,29 +514,21 @@ create_socket(struct raw_iface *ifp, const char *v_name, int port)
setportof(htons(pluto_port), &ifp->addr);
return fd;
}
-#endif
static void
process_raw_ifaces(struct raw_iface *rifaces)
{
struct raw_iface *ifp;
- /* Find all virtual/real interface pairs.
- * For each real interface...
+ /* For each real interface...
*/
for (ifp = rifaces; ifp != NULL; ifp = ifp->next)
{
- struct raw_iface *v = NULL; /* matching ipsecX interface */
+ struct raw_iface *v = NULL;
bool after = FALSE; /* has vfp passed ifp on the list? */
bool bad = FALSE;
struct raw_iface *vfp;
- /* ignore if virtual (ipsec*) interface */
- if (strneq(ifp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1))
- {
- continue;
- }
-
for (vfp = rifaces; vfp != NULL; vfp = vfp->next)
{
if (vfp == ifp)
@@ -554,74 +537,26 @@ process_raw_ifaces(struct raw_iface *rifaces)
}
else if (sameaddr(&ifp->addr, &vfp->addr))
{
- /* Different entries with matching IP addresses.
- * Many interesting cases.
+ /* ugh: a second interface with the same IP address
+ * "after" allows us to avoid double reporting.
*/
- if (strneq(vfp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1))
+ if (after)
{
- if (v != NULL && !streq(v->name, vfp->name))
- {
- loglog(RC_LOG_SERIOUS
- , "ipsec interfaces %s and %s share same address %s"
- , v->name, vfp->name, ip_str(&ifp->addr));
- bad = TRUE;
- }
- else
- {
- v = vfp; /* current winner */
- }
- }
- else
- {
- /* ugh: a second real interface with the same IP address
- * "after" allows us to avoid double reporting.
- */
-#if defined(linux) && defined(KERNEL26_SUPPORT)
- {
- if (after)
- {
- bad = TRUE;
- break;
- }
- continue;
- }
-#endif
- if (after)
- {
- loglog(RC_LOG_SERIOUS
- , "IP interfaces %s and %s share address %s!"
- , ifp->name, vfp->name, ip_str(&ifp->addr));
- }
bad = TRUE;
+ break;
}
+ continue;
}
}
if (bad)
continue;
-#if defined(linux) && defined(KERNEL26_SUPPORT)
- {
- v = ifp;
- goto add_entry;
- }
-#endif
-
- /* what if we didn't find a virtual interface? */
- if (v == NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("IP interface %s %s has no matching ipsec* interface -- ignored"
- , ifp->name, ip_str(&ifp->addr)));
- continue;
- }
+ v = ifp;
/* We've got all we need; see if this is a new thing:
* search old interfaces list.
*/
-#if defined(linux) && defined(KERNEL26_SUPPORT)
-add_entry:
-#endif
{
struct iface **p = &interfaces;
@@ -787,6 +722,7 @@ call_server(void)
act.sa_handler = &termhandler;
r = sigaction(SIGTERM, &act, NULL);
+ r = sigaction(SIGINT, &act, NULL);
passert(r == 0);
}
@@ -821,6 +757,7 @@ call_server(void)
FD_ZERO(&writefds);
FD_SET(ctl_fd, &readfds);
+#ifdef ADNS
/* the only write file-descriptor of interest */
if (adns_qfd != NULL_FD && unsent_ADNS_queries)
{
@@ -835,6 +772,7 @@ call_server(void)
maxfd = adns_afd;
FD_SET(adns_afd, &readfds);
}
+#endif /* ADNS */
events_fd = pluto->events->get_event_fd(pluto->events);
if (maxfd < events_fd)
@@ -902,6 +840,7 @@ call_server(void)
{
/* at least one file descriptor is ready */
+#ifdef ADNS
if (adns_qfd != NULL_FD && FD_ISSET(adns_qfd, &writefds))
{
passert(ndes > 0);
@@ -920,6 +859,7 @@ call_server(void)
passert(GLOBALS_ARE_RESET());
ndes--;
}
+#endif /* ADNS*/
if (FD_ISSET(events_fd, &readfds))
{
diff --git a/src/pluto/spdb.c b/src/pluto/spdb.c
index 48585432b..06fe7d7c8 100644
--- a/src/pluto/spdb.c
+++ b/src/pluto/spdb.c
@@ -1300,7 +1300,7 @@ notification_t parse_isakmp_sa_body(u_int32_t ipsecdoisit,
* proposal is emitted into it.
*
* If "selection" is true, the SA is supposed to represent the
- * single tranform that the peer has accepted.
+ * single transform that the peer has accepted.
* ??? We only check that it is acceptable, not that it is one that we offered!
*
* Only IPsec DOI is accepted (what is the ISAKMP DOI?).
diff --git a/src/pluto/spdb.h b/src/pluto/spdb.h
index 221cc00bb..8a0bffbbd 100644
--- a/src/pluto/spdb.h
+++ b/src/pluto/spdb.h
@@ -100,7 +100,7 @@ extern notification_t parse_ipsec_sa_body(
pb_stream *sa_pbs, /* body of input SA Payload */
const struct isakmp_sa *sa, /* header of input SA Payload */
pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
- bool selection, /* if this SA is a selection, only one tranform can appear */
+ bool selection, /* if this SA is a selection, only one transform can appear */
struct state *st); /* current state object */
extern void backup_pbs(pb_stream *pbs);
diff --git a/src/pluto/state.c b/src/pluto/state.c
index e4234bc87..f5185888e 100644
--- a/src/pluto/state.c
+++ b/src/pluto/state.c
@@ -216,7 +216,7 @@ struct state *state_with_serialno(so_serial_t sn)
}
/* Insert a state object in the hash table. The object is inserted
- * at the begining of list.
+ * at the beginning of list.
* Needs cookies, connection, and msgid.
*/
void insert_state(struct state *st)
diff --git a/src/pluto/timer.c b/src/pluto/timer.c
index c1ad55f5e..1d34d2c54 100644
--- a/src/pluto/timer.c
+++ b/src/pluto/timer.c
@@ -46,18 +46,7 @@
*/
time_t now(void)
{
- static time_t delta = 0
- , last_time = 0;
- time_t n = time(NULL);
-
- passert(n != (time_t)-1);
- if (last_time > n)
- {
- plog("time moved backwards %ld seconds", (long)(last_time - n));
- delta += last_time - n;
- }
- last_time = n;
- return n + delta;
+ return time_monotonic(NULL);
}
/* This file has the event handling routines. Events are
diff --git a/src/pluto/vendor.c b/src/pluto/vendor.c
index 99cfc5734..6cc599d8d 100644
--- a/src/pluto/vendor.c
+++ b/src/pluto/vendor.c
@@ -346,7 +346,7 @@ static void handle_known_vendorid (struct msg_digest *md, const char *vidstr,
case VID_STRONGSWAN:
vid_useful = TRUE;
break;
-
+
/* Remote side supports OpenPGP certificates */
case VID_OPENPGP:
md->openpgp = TRUE;
diff --git a/src/pluto/x509.c b/src/pluto/x509.c
index 7e2aca862..f017e5775 100644
--- a/src/pluto/x509.c
+++ b/src/pluto/x509.c
@@ -410,7 +410,7 @@ void list_x509cert_chain(const char *caption, cert_t* cert,
certificate->get_subject(certificate));
whack_log(RC_COMMENT, " issuer: \"%Y\"",
certificate->get_issuer(certificate));
- serial = x509->get_serial(x509);
+ serial = chunk_skip_zero(x509->get_serial(x509));
whack_log(RC_COMMENT, " serial: %#B", &serial);
/* list validity */
diff --git a/src/scepclient/Makefile.in b/src/scepclient/Makefile.in
index 9f8ac874e..576a8fb17 100644
--- a/src/scepclient/Makefile.in
+++ b/src/scepclient/Makefile.in
@@ -200,6 +200,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -208,6 +211,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -224,11 +228,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -272,6 +278,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
diff --git a/src/scepclient/scepclient.c b/src/scepclient/scepclient.c
index d9f6b0925..0b54eeee3 100644
--- a/src/scepclient/scepclient.c
+++ b/src/scepclient/scepclient.c
@@ -50,6 +50,7 @@
#include <credentials/certificates/certificate.h>
#include <credentials/certificates/x509.h>
#include <credentials/certificates/pkcs10.h>
+#include <plugins/plugin.h>
#include "../pluto/constants.h"
#include "../pluto/defs.h"
@@ -275,25 +276,6 @@ usage(const char *message)
}
/**
- * Log loaded plugins
- */
-static void print_plugins()
-{
- char buf[BUF_LEN];
- plugin_t *plugin;
- int len = 0;
- enumerator_t *enumerator;
-
- enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
- while (len < BUF_LEN && enumerator->enumerate(enumerator, &plugin))
- {
- len += snprintf(&buf[len], BUF_LEN-len, "%s ", plugin->get_name(plugin));
- }
- enumerator->destroy(enumerator);
- DBG1(DBG_LIB, " loaded plugins: %s", buf);
-}
-
-/**
* @brief main of scepclient
*
* @param argc number of arguments
@@ -333,7 +315,7 @@ int main(int argc, char **argv)
char *file_out_pkcs7 = DEFAULT_FILENAME_PKCS7;
char *file_out_cert_self = DEFAULT_FILENAME_CERT_SELF;
char *file_out_cert = DEFAULT_FILENAME_CERT;
- char *file_out_prefix_cacert = DEFAULT_FILENAME_PREFIX_CACERT;
+ char *file_out_ca_cert = DEFAULT_FILENAME_CACERT_ENC;
/* by default user certificate is requested */
bool request_ca_certificate = FALSE;
@@ -541,7 +523,7 @@ int main(int argc, char **argv)
{
request_ca_certificate = TRUE;
if (filename)
- file_out_prefix_cacert = filename;
+ file_out_ca_cert = filename;
}
else
{
@@ -703,10 +685,6 @@ int main(int argc, char **argv)
case 'x': /* --maxpolltime */
max_poll_time = atoi(optarg);
- if (max_poll_time < 0)
- {
- usage("invalid maxpolltime specified");
- }
continue;
case 'a': /*--algorithm */
@@ -762,7 +740,8 @@ int main(int argc, char **argv)
{
exit_scepclient("plugin loading failed");
}
- print_plugins();
+ DBG1(DBG_LIB, " loaded plugins: %s",
+ lib->plugins->loaded_plugins(lib->plugins));
if ((filetype_out == 0) && (!request_ca_certificate))
{
@@ -785,6 +764,24 @@ int main(int argc, char **argv)
usage("cannot generate --out of given --in!");
}
+ /* get CA cert */
+ if (request_ca_certificate)
+ {
+ char *path = concatenate_paths(CA_CERT_PATH, file_out_ca_cert);
+
+ if (!scep_http_request(scep_url, chunk_empty, SCEP_GET_CA_CERT,
+ http_get_request, &scep_response))
+ {
+ exit_scepclient("did not receive a valid scep response");
+ }
+
+ if (!chunk_write(scep_response, path, "ca cert", 0022, force))
+ {
+ exit_scepclient("could not write ca cert file '%s'", path);
+ }
+ exit_scepclient(NULL); /* no further output required */
+ }
+
/*
* input of PKCS#1 file
*/
diff --git a/src/starter/Android.mk b/src/starter/Android.mk
new file mode 100644
index 000000000..a82fe9385
--- /dev/null
+++ b/src/starter/Android.mk
@@ -0,0 +1,47 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# copy-n-paste from Makefile.am (update for LEX/YACC)
+LOCAL_SRC_FILES := \
+parser.c lexer.c ipsec-parser.h netkey.c args.h netkey.h \
+starterwhack.c starterwhack.h starterstroke.c invokepluto.c confread.c \
+starterstroke.h interfaces.c invokepluto.h confread.h interfaces.h args.c \
+keywords.c files.h keywords.h cmp.c starter.c cmp.h exec.c invokecharon.c \
+exec.h invokecharon.h loglite.c klips.c klips.h
+
+# build starter ----------------------------------------------------------------
+
+LOCAL_C_INCLUDES += \
+ $(libvstr_PATH) \
+ $(strongswan_PATH)/src/libhydra \
+ $(strongswan_PATH)/src/libfreeswan \
+ $(strongswan_PATH)/src/libstrongswan \
+ $(strongswan_PATH)/src/libfreeswan \
+ $(strongswan_PATH)/src/pluto \
+ $(strongswan_PATH)/src/whack \
+ $(strongswan_PATH)/src/stroke
+
+LOCAL_CFLAGS := $(strongswan_CFLAGS) -DSTART_CHARON \
+ -DPLUGINS='"$(strongswan_STARTER_PLUGINS)"'
+
+ifneq ($(strongswan_BUILD_PLUTO),)
+LOCAL_CFLAGS += -DSTART_PLUTO
+endif
+
+LOCAL_MODULE := starter
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_REQUIRED_MODULES := stroke
+ifneq ($(strongswan_BUILD_PLUTO),)
+LOCAL_REQUIRED_MODULES += whack
+endif
+
+LOCAL_SHARED_LIBRARIES += libstrongswan libhydra libfreeswan
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/src/starter/Makefile.am b/src/starter/Makefile.am
index f05aeca22..94ddf5aba 100644
--- a/src/starter/Makefile.am
+++ b/src/starter/Makefile.am
@@ -1,9 +1,10 @@
ipsec_PROGRAMS = starter
-starter_SOURCES = y.tab.c netkey.c y.tab.h parser.h args.h netkey.h \
+starter_SOURCES = \
+parser.y lexer.l ipsec-parser.h netkey.c args.h netkey.h \
starterwhack.c starterwhack.h starterstroke.c invokepluto.c confread.c \
starterstroke.h interfaces.c invokepluto.h confread.h interfaces.h args.c \
keywords.c files.h keywords.h cmp.c starter.c cmp.h exec.c invokecharon.c \
-exec.h invokecharon.h lex.yy.c loglite.c klips.c klips.h
+exec.h invokecharon.h loglite.c klips.c klips.h
INCLUDES = \
-I${linux_headers} \
@@ -21,11 +22,15 @@ AM_CFLAGS = \
-DIPSEC_EAPDIR=\"${eapdir}\" \
-DDEV_RANDOM=\"${random_device}\" \
-DDEV_URANDOM=\"${urandom_device}\" \
+-DPLUGINS=\""${starter_plugins}\"" \
-DDEBUG
-starter_LDADD = defs.o $(top_builddir)/src/libfreeswan/libfreeswan.a $(top_builddir)/src/libstrongswan/libstrongswan.la $(SOCKLIB)
-EXTRA_DIST = parser.l parser.y keywords.txt ipsec.conf
-MAINTAINERCLEANFILES = lex.yy.c y.tab.c y.tab.h keywords.c
+AM_YFLAGS = -v -d
+
+starter_LDADD = defs.o $(top_builddir)/src/libfreeswan/libfreeswan.a $(top_builddir)/src/libstrongswan/libstrongswan.la $(top_builddir)/src/libhydra/libhydra.la $(SOCKLIB)
+EXTRA_DIST = keywords.txt ipsec.conf Android.mk
+MAINTAINERCLEANFILES = keywords.c
+BUILT_SOURCES = parser.h
PLUTODIR=$(top_srcdir)/src/pluto
SCEPCLIENTDIR=$(top_srcdir)/src/scepclient
@@ -42,14 +47,9 @@ if USE_LOAD_WARNING
AM_CFLAGS += -DLOAD_WARNING
endif
-lex.yy.c: $(srcdir)/parser.l $(srcdir)/parser.y $(srcdir)/parser.h y.tab.h
- $(LEX) $(srcdir)/parser.l
-
-y.tab.c: $(srcdir)/parser.y $(srcdir)/parser.l $(srcdir)/parser.h
- $(YACC) -v -d $(srcdir)/parser.y
-
-y.tab.h: $(srcdir)/parser.y $(srcdir)/parser.l $(srcdir)/parser.h
- $(YACC) -v -d $(srcdir)/parser.y
+if USE_TOOLS
+ AM_CFLAGS += -DGENERATE_SELFCERT
+endif
keywords.c: $(srcdir)/keywords.txt $(srcdir)/keywords.h
$(GPERF) -m 10 -C -G -D -t < $(srcdir)/keywords.txt > $@
diff --git a/src/starter/Makefile.in b/src/starter/Makefile.in
index 72adbf7bc..f2c0cc38e 100644
--- a/src/starter/Makefile.in
+++ b/src/starter/Makefile.in
@@ -38,8 +38,10 @@ ipsec_PROGRAMS = starter$(EXEEXT)
@USE_PLUTO_TRUE@am__append_1 = -DSTART_PLUTO
@USE_CHARON_TRUE@am__append_2 = -DSTART_CHARON
@USE_LOAD_WARNING_TRUE@am__append_3 = -DLOAD_WARNING
+@USE_TOOLS_TRUE@am__append_4 = -DGENERATE_SELFCERT
subdir = src/starter
-DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ lexer.c parser.c parser.h
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/ltoptions.m4 \
@@ -57,18 +59,18 @@ CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__installdirs = "$(DESTDIR)$(ipsecdir)"
PROGRAMS = $(ipsec_PROGRAMS)
-am_starter_OBJECTS = y.tab.$(OBJEXT) netkey.$(OBJEXT) \
+am_starter_OBJECTS = parser.$(OBJEXT) lexer.$(OBJEXT) netkey.$(OBJEXT) \
starterwhack.$(OBJEXT) starterstroke.$(OBJEXT) \
invokepluto.$(OBJEXT) confread.$(OBJEXT) interfaces.$(OBJEXT) \
args.$(OBJEXT) keywords.$(OBJEXT) cmp.$(OBJEXT) \
starter.$(OBJEXT) exec.$(OBJEXT) invokecharon.$(OBJEXT) \
- lex.yy.$(OBJEXT) loglite.$(OBJEXT) klips.$(OBJEXT)
+ loglite.$(OBJEXT) klips.$(OBJEXT)
starter_OBJECTS = $(am_starter_OBJECTS)
am__DEPENDENCIES_1 =
starter_DEPENDENCIES = defs.o \
$(top_builddir)/src/libfreeswan/libfreeswan.a \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
- $(am__DEPENDENCIES_1)
+ $(top_builddir)/src/libhydra/libhydra.la $(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -82,6 +84,13 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
+LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
+LTLEXCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(LEX) $(LFLAGS) $(AM_LFLAGS)
+YLWRAP = $(top_srcdir)/ylwrap
+YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+LTYACCCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(YACC) $(YFLAGS) $(AM_YFLAGS)
SOURCES = $(starter_SOURCES)
DIST_SOURCES = $(starter_SOURCES)
ETAGS = etags
@@ -178,6 +187,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -186,6 +198,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -202,11 +215,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -250,6 +265,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -260,11 +276,12 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-starter_SOURCES = y.tab.c netkey.c y.tab.h parser.h args.h netkey.h \
+starter_SOURCES = \
+parser.y lexer.l ipsec-parser.h netkey.c args.h netkey.h \
starterwhack.c starterwhack.h starterstroke.c invokepluto.c confread.c \
starterstroke.h interfaces.c invokepluto.h confread.h interfaces.h args.c \
keywords.c files.h keywords.h cmp.c starter.c cmp.h exec.c invokecharon.c \
-exec.h invokecharon.h lex.yy.c loglite.c klips.c klips.h
+exec.h invokecharon.h loglite.c klips.c klips.h
INCLUDES = \
-I${linux_headers} \
@@ -278,17 +295,21 @@ INCLUDES = \
AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" \
-DIPSEC_CONFDIR=\"${sysconfdir}\" -DIPSEC_PIDDIR=\"${piddir}\" \
-DIPSEC_EAPDIR=\"${eapdir}\" -DDEV_RANDOM=\"${random_device}\" \
- -DDEV_URANDOM=\"${urandom_device}\" -DDEBUG $(am__append_1) \
- $(am__append_2) $(am__append_3)
-starter_LDADD = defs.o $(top_builddir)/src/libfreeswan/libfreeswan.a $(top_builddir)/src/libstrongswan/libstrongswan.la $(SOCKLIB)
-EXTRA_DIST = parser.l parser.y keywords.txt ipsec.conf
-MAINTAINERCLEANFILES = lex.yy.c y.tab.c y.tab.h keywords.c
+ -DDEV_URANDOM=\"${urandom_device}\" \
+ -DPLUGINS=\""${starter_plugins}\"" -DDEBUG $(am__append_1) \
+ $(am__append_2) $(am__append_3) $(am__append_4)
+AM_YFLAGS = -v -d
+starter_LDADD = defs.o $(top_builddir)/src/libfreeswan/libfreeswan.a $(top_builddir)/src/libstrongswan/libstrongswan.la $(top_builddir)/src/libhydra/libhydra.la $(SOCKLIB)
+EXTRA_DIST = keywords.txt ipsec.conf Android.mk
+MAINTAINERCLEANFILES = keywords.c
+BUILT_SOURCES = parser.h
PLUTODIR = $(top_srcdir)/src/pluto
SCEPCLIENTDIR = $(top_srcdir)/src/scepclient
-all: all-am
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
+.SUFFIXES: .c .l .lo .o .obj .y
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -362,6 +383,11 @@ clean-ipsecPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
+parser.h: parser.c
+ @if test ! -f $@; then \
+ rm -f parser.c; \
+ $(MAKE) $(AM_MAKEFLAGS) parser.c; \
+ else :; fi
starter$(EXEEXT): $(starter_OBJECTS) $(starter_DEPENDENCIES)
@rm -f starter$(EXEEXT)
$(LINK) $(starter_OBJECTS) $(starter_LDADD) $(LIBS)
@@ -381,13 +407,13 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/invokepluto.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keywords.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/klips.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lex.yy.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lexer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loglite.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netkey.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/starter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/starterstroke.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/starterwhack.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/y.tab.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -410,6 +436,12 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+.l.c:
+ $(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE)
+
+.y.c:
+ $(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE)
+
mostlyclean-libtool:
-rm -f *.lo
@@ -499,13 +531,15 @@ distdir: $(DISTFILES)
fi; \
done
check-am: all-am
-check: check-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(PROGRAMS)
installdirs:
for dir in "$(DESTDIR)$(ipsecdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
-install: install-am
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
@@ -530,6 +564,10 @@ distclean-generic:
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
+ -rm -f lexer.c
+ -rm -f parser.c
+ -rm -f parser.h
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
@@ -602,7 +640,7 @@ ps-am:
uninstall-am: uninstall-ipsecPROGRAMS
-.MAKE: install-am install-strip
+.MAKE: all check install install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-ipsecPROGRAMS clean-libtool ctags distclean \
@@ -619,15 +657,6 @@ uninstall-am: uninstall-ipsecPROGRAMS
tags uninstall uninstall-am uninstall-ipsecPROGRAMS
-lex.yy.c: $(srcdir)/parser.l $(srcdir)/parser.y $(srcdir)/parser.h y.tab.h
- $(LEX) $(srcdir)/parser.l
-
-y.tab.c: $(srcdir)/parser.y $(srcdir)/parser.l $(srcdir)/parser.h
- $(YACC) -v -d $(srcdir)/parser.y
-
-y.tab.h: $(srcdir)/parser.y $(srcdir)/parser.l $(srcdir)/parser.h
- $(YACC) -v -d $(srcdir)/parser.y
-
keywords.c: $(srcdir)/keywords.txt $(srcdir)/keywords.h
$(GPERF) -m 10 -C -G -D -t < $(srcdir)/keywords.txt > $@
diff --git a/src/starter/args.c b/src/starter/args.c
index 4d8003aab..65d0a753c 100644
--- a/src/starter/args.c
+++ b/src/starter/args.c
@@ -24,7 +24,6 @@
#include "../pluto/log.h"
#include "keywords.h"
-#include "parser.h"
#include "confread.h"
#include "args.h"
@@ -130,6 +129,7 @@ static const char *LST_plutodebug[] = {
"control",
"lifecycle",
"klips",
+ "kernel",
"dns",
"natt",
"oppo",
@@ -228,6 +228,7 @@ static const token_info_t token_info[] =
{ ARG_TIME, offsetof(starter_conn_t, dpd_delay), NULL },
{ ARG_TIME, offsetof(starter_conn_t, dpd_timeout), NULL },
{ ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action },
+ { ARG_ENUM, offsetof(starter_conn_t, close_action), LST_dpd_action },
{ ARG_TIME, offsetof(starter_conn_t, inactivity), NULL },
{ ARG_MISC, 0, NULL /* KW_MODECONFIG */ },
{ ARG_MISC, 0, NULL /* KW_XAUTH */ },
@@ -254,7 +255,7 @@ static const token_info_t token_info[] =
{ ARG_STR, offsetof(starter_ca_t, certuribase), NULL },
/* end keywords */
- { ARG_MISC, 0, NULL /* KW_HOST */ },
+ { ARG_STR, offsetof(starter_end_t, host), NULL },
{ ARG_UINT, offsetof(starter_end_t, ikeport), NULL },
{ ARG_MISC, 0, NULL /* KW_NEXTHOP */ },
{ ARG_STR, offsetof(starter_end_t, subnet), NULL },
diff --git a/src/starter/args.h b/src/starter/args.h
index b003784c8..f5c13e6ba 100644
--- a/src/starter/args.h
+++ b/src/starter/args.h
@@ -17,7 +17,7 @@
#define _ARGS_H_
#include "keywords.h"
-#include "parser.h"
+#include "ipsec-parser.h"
extern char **new_list(char *value);
extern bool assign_arg(kw_token_t token, kw_token_t first, kw_list_t *kw
diff --git a/src/starter/confread.c b/src/starter/confread.c
index 1e7daa6a9..627601e88 100644
--- a/src/starter/confread.c
+++ b/src/starter/confread.c
@@ -12,6 +12,9 @@
* for more details.
*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
@@ -26,9 +29,9 @@
#include "../pluto/log.h"
#include "keywords.h"
-#include "parser.h"
#include "confread.h"
#include "args.h"
+#include "files.h"
#include "interfaces.h"
/* strings containing a colon are interpreted as an IPv6 address */
@@ -39,6 +42,17 @@ static const char esp_defaults[] = "aes128-sha1,3des-sha1";
static const char firewall_defaults[] = "ipsec _updown iptables";
+static bool daemon_exists(char *daemon, char *path)
+{
+ struct stat st;
+ if (stat(path, &st) != 0)
+ {
+ plog("Disabling %sstart option, '%s' not found", daemon, path);
+ return FALSE;
+ }
+ return TRUE;
+}
+
static void default_values(starter_config_t *cfg)
{
if (cfg == NULL)
@@ -123,7 +137,7 @@ static void load_setup(starter_config_t *cfg, config_parsed_t *cfgp)
kw_token_t token = kw->entry->token;
- if (token < KW_SETUP_FIRST || token > KW_SETUP_LAST)
+ if ((int)token < KW_SETUP_FIRST || token > KW_SETUP_LAST)
{
plog("# unsupported keyword '%s' in config setup", kw->entry->name);
cfg->err++;
@@ -137,6 +151,21 @@ static void load_setup(starter_config_t *cfg, config_parsed_t *cfgp)
continue;
}
}
+
+ /* verify the executables are actually available (some distros split
+ * packages but enabled both) */
+#ifdef START_CHARON
+ cfg->setup.charonstart = cfg->setup.charonstart &&
+ daemon_exists("charon", CHARON_CMD);
+#else
+ cfg->setup.charonstart = FALSE;
+#endif
+#ifdef START_PLUTO
+ cfg->setup.plutostart = cfg->setup.plutostart &&
+ daemon_exists("pluto", PLUTO_CMD);
+#else
+ cfg->setup.plutostart = FALSE;
+#endif
}
static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
@@ -155,6 +184,70 @@ static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
/* post processing of some keywords that were assigned automatically */
switch (token)
{
+ case KW_HOST:
+ free(end->host);
+ end->host = NULL;
+ if (streq(value, "%defaultroute"))
+ {
+ if (cfg->defaultroute.defined)
+ {
+ end->addr = cfg->defaultroute.addr;
+ end->nexthop = cfg->defaultroute.nexthop;
+ }
+ else if (!cfg->defaultroute.supported)
+ {
+ plog("%%defaultroute not supported, fallback to %%any");
+ }
+ else
+ {
+ plog("# default route not known: %s=%s", name, value);
+ goto err;
+ }
+ }
+ else if (streq(value, "%any") || streq(value, "%any4"))
+ {
+ anyaddr(conn->addr_family, &end->addr);
+ }
+ else if (streq(value, "%any6"))
+ {
+ conn->addr_family = AF_INET6;
+ anyaddr(conn->addr_family, &end->addr);
+ }
+ else if (streq(value, "%group"))
+ {
+ ip_address any;
+
+ conn->policy |= POLICY_GROUP | POLICY_TUNNEL;
+ anyaddr(conn->addr_family, &end->addr);
+ anyaddr(conn->tunnel_addr_family, &any);
+ end->has_client = TRUE;
+ }
+ else
+ {
+ /* check for allow_any prefix */
+ if (value[0] == '%')
+ {
+ end->allow_any = TRUE;
+ value++;
+ }
+ conn->addr_family = ip_version(value);
+ ugh = ttoaddr(value, 0, conn->addr_family, &end->addr);
+ if (ugh != NULL)
+ {
+ plog("# bad addr: %s=%s [%s]", name, value, ugh);
+ if (streq(ugh, "does not look numeric and name lookup failed"))
+ {
+ end->dns_failed = TRUE;
+ anyaddr(conn->addr_family, &end->addr);
+ }
+ else
+ {
+ goto err;
+ }
+ }
+ end->host = clone_str(value);
+ }
+ break;
case KW_SUBNET:
if ((strlen(value) >= 6 && strncmp(value,"vhost:",6) == 0)
|| (strlen(value) >= 5 && strncmp(value,"vnet:",5) == 0))
@@ -264,67 +357,6 @@ static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
/* individual processing of keywords that were not assigned automatically */
switch (token)
{
- case KW_HOST:
- if (streq(value, "%defaultroute"))
- {
- if (cfg->defaultroute.defined)
- {
- end->addr = cfg->defaultroute.addr;
- end->nexthop = cfg->defaultroute.nexthop;
- }
- else if (!cfg->defaultroute.supported)
- {
- plog("%%defaultroute not supported, fallback to %%any");
- }
- else
- {
- plog("# default route not known: %s=%s", name, value);
- goto err;
- }
- }
- else if (streq(value, "%any") || streq(value, "%any4"))
- {
- anyaddr(conn->addr_family, &end->addr);
- }
- else if (streq(value, "%any6"))
- {
- conn->addr_family = AF_INET6;
- anyaddr(conn->addr_family, &end->addr);
- }
- else if (streq(value, "%group"))
- {
- ip_address any;
-
- conn->policy |= POLICY_GROUP | POLICY_TUNNEL;
- anyaddr(conn->addr_family, &end->addr);
- anyaddr(conn->tunnel_addr_family, &any);
- end->has_client = TRUE;
- }
- else
- {
- /* check for allow_any prefix */
- if (value[0] == '%')
- {
- end->allow_any = TRUE;
- value++;
- }
- conn->addr_family = ip_version(value);
- ugh = ttoaddr(value, 0, conn->addr_family, &end->addr);
- if (ugh != NULL)
- {
- plog("# bad addr: %s=%s [%s]", name, value, ugh);
- if (streq(ugh, "does not look numeric and name lookup failed"))
- {
- end->dns_failed = TRUE;
- anyaddr(conn->addr_family, &end->addr);
- }
- else
- {
- goto err;
- }
- }
- }
- break;
case KW_NEXTHOP:
if (streq(value, "%defaultroute"))
{
@@ -425,7 +457,7 @@ err:
* handles left|right=<FQDN> DNS resolution failure
*/
static void handle_dns_failure(const char *label, starter_end_t *end,
- starter_config_t *cfg)
+ starter_config_t *cfg, starter_conn_t *conn)
{
if (end->dns_failed)
{
@@ -434,7 +466,7 @@ static void handle_dns_failure(const char *label, starter_end_t *end,
plog("# fallback to %s=%%any due to '%%' prefix or %sallowany=yes",
label, label);
}
- else
+ else if (!end->host || conn->keyexchange == KEY_EXCHANGE_IKEV1)
{
/* declare an error */
cfg->err++;
@@ -609,7 +641,7 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg
case KW_AUTHBY:
conn->policy &= ~(POLICY_ID_AUTH_MASK | POLICY_ENCRYPT);
- if (!(streq(kw->value, "never") || streq(kw->value, "eap")))
+ if (!streq(kw->value, "never"))
{
char *value = kw->value;
char *second = strchr(kw->value, '|');
@@ -636,7 +668,7 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg
{
conn->policy |= POLICY_XAUTH_RSASIG | POLICY_ENCRYPT;
}
- else if (streq(value, "xauthpsk"))
+ else if (streq(value, "xauthpsk") || streq(value, "eap"))
{
conn->policy |= POLICY_XAUTH_PSK | POLICY_ENCRYPT;
}
@@ -762,8 +794,8 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg
}
}
- handle_dns_failure("left", &conn->left, cfg);
- handle_dns_failure("right", &conn->right, cfg);
+ handle_dns_failure("left", &conn->left, cfg, conn);
+ handle_dns_failure("right", &conn->right, cfg, conn);
handle_firewall("left", &conn->left, cfg);
handle_firewall("right", &conn->right, cfg);
}
diff --git a/src/starter/confread.h b/src/starter/confread.h
index 4f9c5f7d0..9cb919ce5 100644
--- a/src/starter/confread.h
+++ b/src/starter/confread.h
@@ -20,7 +20,7 @@
#include <freeswan.h>
#endif
-#include "parser.h"
+#include "ipsec-parser.h"
#include "interfaces.h"
typedef enum {
@@ -66,6 +66,7 @@ struct starter_end {
char *groups;
char *cert_policy;
char *iface;
+ char *host;
ip_address addr;
u_int ikeport;
ip_address nexthop;
@@ -143,6 +144,8 @@ struct starter_conn {
dpd_action_t dpd_action;
int dpd_count;
+ dpd_action_t close_action;
+
time_t inactivity;
bool me_mediation;
@@ -195,12 +198,12 @@ struct starter_config {
char *plutostderrlog;
bool uniqueids;
u_int overridemtu;
- u_int crlcheckinterval;
+ time_t crlcheckinterval;
bool cachecrls;
strict_t strictcrlpolicy;
bool nocrsend;
bool nat_traversal;
- u_int keep_alive;
+ time_t keep_alive;
u_int force_keepalive;
char *virtual_private;
char *pkcs11module;
diff --git a/src/starter/files.h b/src/starter/files.h
index ec41c9f2e..88857c0b2 100644
--- a/src/starter/files.h
+++ b/src/starter/files.h
@@ -33,7 +33,6 @@
#define CHARON_PID_FILE IPSEC_PIDDIR "/charon.pid"
#define DYNIP_DIR IPSEC_PIDDIR "/dynip"
-#define INFO_FILE IPSEC_PIDDIR "/ipsec.info"
#endif /* _STARTER_FILES_H_ */
diff --git a/src/starter/invokepluto.c b/src/starter/invokepluto.c
index f91f4b6c9..70c0692ea 100644
--- a/src/starter/invokepluto.c
+++ b/src/starter/invokepluto.c
@@ -173,6 +173,7 @@ starter_start_pluto (starter_config_t *cfg, bool no_fork, bool attach_gdb)
ADD_DEBUG("control")
ADD_DEBUG("lifecycle")
ADD_DEBUG("klips")
+ ADD_DEBUG("kernel")
ADD_DEBUG("dns")
ADD_DEBUG("natt")
ADD_DEBUG("oppo")
@@ -183,7 +184,7 @@ starter_start_pluto (starter_config_t *cfg, bool no_fork, bool attach_gdb)
static char buf1[15];
arg[argc++] = "--crlcheckinterval";
- snprintf(buf1, sizeof(buf1), "%u", cfg->setup.crlcheckinterval);
+ snprintf(buf1, sizeof(buf1), "%d", (int)cfg->setup.crlcheckinterval);
arg[argc++] = buf1;
}
if (cfg->setup.cachecrls)
@@ -211,7 +212,7 @@ starter_start_pluto (starter_config_t *cfg, bool no_fork, bool attach_gdb)
static char buf2[15];
arg[argc++] = "--keep_alive";
- snprintf(buf2, sizeof(buf2), "%u", cfg->setup.keep_alive);
+ snprintf(buf2, sizeof(buf2), "%d", (int)cfg->setup.keep_alive);
arg[argc++] = buf2;
}
if (cfg->setup.virtual_private)
diff --git a/src/starter/ipsec-parser.h b/src/starter/ipsec-parser.h
new file mode 100644
index 000000000..1c6cf20ef
--- /dev/null
+++ b/src/starter/ipsec-parser.h
@@ -0,0 +1,55 @@
+/* strongSwan config file parser
+ * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
+ *
+ * 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 _IPSEC_PARSER_H_
+#define _IPSEC_PARSER_H_
+
+#include "keywords.h"
+
+typedef struct kw_entry kw_entry_t;
+
+struct kw_entry {
+ char *name;
+ kw_token_t token;
+};
+
+typedef struct kw_list kw_list_t;
+
+struct kw_list {
+ kw_entry_t *entry;
+ char *value;
+ kw_list_t *next;
+};
+
+typedef struct section_list section_list_t;
+
+struct section_list {
+ char *name;
+ kw_list_t *kw;
+ section_list_t *next;
+};
+
+typedef struct config_parsed config_parsed_t;
+
+struct config_parsed {
+ kw_list_t *config_setup;
+ section_list_t *conn_first, *conn_last;
+ section_list_t *ca_first, *ca_last;
+};
+
+config_parsed_t *parser_load_conf (const char *file);
+void parser_free_conf (config_parsed_t *cfg);
+
+#endif /* _IPSEC_PARSER_H_ */
+
diff --git a/src/starter/keywords.c b/src/starter/keywords.c
index 340b7131d..edb55ae7f 100644
--- a/src/starter/keywords.c
+++ b/src/starter/keywords.c
@@ -54,12 +54,12 @@ struct kw_entry {
kw_token_t token;
};
-#define TOTAL_KEYWORDS 130
+#define TOTAL_KEYWORDS 131
#define MIN_WORD_LENGTH 3
#define MAX_WORD_LENGTH 17
-#define MIN_HASH_VALUE 18
-#define MAX_HASH_VALUE 249
-/* maximum key range = 232, duplicates = 0 */
+#define MIN_HASH_VALUE 9
+#define MAX_HASH_VALUE 246
+/* maximum key range = 238, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -75,32 +75,32 @@ hash (str, len)
{
static const unsigned char asso_values[] =
{
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 11,
- 125, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 20, 250, 18, 6, 55,
- 59, 3, 9, 3, 92, 3, 250, 147, 71, 12,
- 29, 83, 38, 4, 13, 3, 8, 80, 3, 250,
- 250, 12, 9, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
- 250, 250, 250, 250, 250, 250
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 12,
+ 126, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 51, 247, 11, 1, 92,
+ 43, 0, 6, 0, 110, 0, 247, 120, 56, 37,
+ 27, 72, 43, 1, 16, 0, 5, 75, 1, 247,
+ 247, 11, 5, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247, 247, 247, 247, 247,
+ 247, 247, 247, 247, 247, 247
};
register int hval = len;
@@ -126,162 +126,163 @@ static const struct kw_entry wordlist[] =
{"pfs", KW_PFS},
{"right", KW_RIGHT},
{"rightgroups", KW_RIGHTGROUPS},
- {"left", KW_LEFT},
{"lifetime", KW_KEYLIFE},
+ {"left", KW_LEFT},
{"rightsubnet", KW_RIGHTSUBNET},
{"rightikeport", KW_RIGHTIKEPORT},
{"rightsendcert", KW_RIGHTSENDCERT},
{"leftcert", KW_LEFTCERT},
+ {"keep_alive", KW_KEEP_ALIVE},
{"keyingtries", KW_KEYINGTRIES},
- {"keylife", KW_KEYLIFE},
{"leftsendcert", KW_LEFTSENDCERT},
+ {"keylife", KW_KEYLIFE},
{"lifebytes", KW_LIFEBYTES},
- {"keep_alive", KW_KEEP_ALIVE},
- {"leftgroups", KW_LEFTGROUPS},
+ {"lifepackets", KW_LIFEPACKETS},
{"leftrsasigkey", KW_LEFTRSASIGKEY},
{"leftcertpolicy", KW_LEFTCERTPOLICY},
- {"certuribase", KW_CERTURIBASE},
- {"lifepackets", KW_LIFEPACKETS},
- {"rightrsasigkey", KW_RIGHTRSASIGKEY},
- {"leftprotoport", KW_LEFTPROTOPORT},
- {"uniqueids", KW_UNIQUEIDS},
+ {"leftgroups", KW_LEFTGROUPS},
+ {"leftca", KW_LEFTCA},
{"rightallowany", KW_RIGHTALLOWANY},
+ {"uniqueids", KW_UNIQUEIDS},
+ {"leftprotoport", KW_LEFTPROTOPORT},
+ {"rightrsasigkey", KW_RIGHTRSASIGKEY},
{"virtual_private", KW_VIRTUAL_PRIVATE},
- {"leftca", KW_LEFTCA},
+ {"certuribase", KW_CERTURIBASE},
{"rightsubnetwithin", KW_RIGHTSUBNETWITHIN},
- {"strictcrlpolicy", KW_STRICTCRLPOLICY},
- {"type", KW_TYPE},
{"interfaces", KW_INTERFACES},
+ {"reqid", KW_REQID},
+ {"rightid", KW_RIGHTID},
+ {"strictcrlpolicy", KW_STRICTCRLPOLICY},
{"rightsourceip", KW_RIGHTSOURCEIP},
+ {"type", KW_TYPE},
+ {"inactivity", KW_INACTIVITY},
{"leftnexthop", KW_LEFTNEXTHOP},
- {"rightprotoport", KW_RIGHTPROTOPORT},
{"mark_in", KW_MARK_IN},
- {"reqid", KW_REQID},
- {"inactivity", KW_INACTIVITY},
+ {"rightprotoport", KW_RIGHTPROTOPORT},
{"margintime", KW_REKEYMARGIN},
{"marginbytes", KW_MARGINBYTES},
- {"rightid", KW_RIGHTID},
{"marginpackets", KW_MARGINPACKETS},
{"leftnatip", KW_LEFTNATIP},
- {"rightcert", KW_RIGHTCERT},
- {"ocspuri", KW_OCSPURI},
- {"esp", KW_ESP},
- {"rightnatip", KW_RIGHTNATIP},
- {"keyexchange", KW_KEYEXCHANGE},
- {"rightnexthop", KW_RIGHTNEXTHOP},
- {"rightca", KW_RIGHTCA},
- {"rightcertpolicy", KW_RIGHTCERTPOLICY},
- {"leftupdown", KW_LEFTUPDOWN},
- {"ocspuri1", KW_OCSPURI},
{"mediated_by", KW_MEDIATED_BY},
- {"me_peerid", KW_ME_PEERID},
- {"cacert", KW_CACERT},
- {"crluri", KW_CRLURI},
- {"eap", KW_EAP},
+ {"ldapbase", KW_LDAPBASE},
{"leftfirewall", KW_LEFTFIREWALL},
{"rightfirewall", KW_RIGHTFIREWALL},
- {"overridemtu", KW_OVERRIDEMTU},
+ {"crluri", KW_CRLURI},
{"mobike", KW_MOBIKE},
- {"packetdefault", KW_PACKETDEFAULT},
- {"crluri1", KW_CRLURI},
- {"ldapbase", KW_LDAPBASE},
- {"leftallowany", KW_LEFTALLOWANY},
+ {"rightnatip", KW_RIGHTNATIP},
+ {"rightnexthop", KW_RIGHTNEXTHOP},
{"mediation", KW_MEDIATION},
- {"compress", KW_COMPRESS},
- {"leftsubnet", KW_LEFTSUBNET},
+ {"leftallowany", KW_LEFTALLOWANY},
+ {"leftupdown", KW_LEFTUPDOWN},
+ {"overridemtu", KW_OVERRIDEMTU},
+ {"aaa_identity", KW_AAA_IDENTITY},
+ {"esp", KW_ESP},
+ {"crluri1", KW_CRLURI},
{"lefthostaccess", KW_LEFTHOSTACCESS},
+ {"leftsubnet", KW_LEFTSUBNET},
+ {"leftid", KW_LEFTID},
{"forceencaps", KW_FORCEENCAPS},
- {"dumpdir", KW_DUMPDIR},
- {"righthostaccess", KW_RIGHTHOSTACCESS},
- {"authby", KW_AUTHBY},
- {"aaa_identity", KW_AAA_IDENTITY},
- {"tfc", KW_TFC},
+ {"eap", KW_EAP},
{"nat_traversal", KW_NAT_TRAVERSAL},
- {"rightauth", KW_RIGHTAUTH},
- {"rightupdown", KW_RIGHTUPDOWN},
- {"dpdtimeout", KW_DPDTIMEOUT},
+ {"me_peerid", KW_ME_PEERID},
+ {"rightcert", KW_RIGHTCERT},
{"installpolicy", KW_INSTALLPOLICY},
+ {"authby", KW_AUTHBY},
+ {"klipsdebug", KW_KLIPSDEBUG},
+ {"rightca", KW_RIGHTCA},
{"mark_out", KW_MARK_OUT},
- {"fragicmp", KW_FRAGICMP},
- {"force_keepalive", KW_FORCE_KEEPALIVE},
- {"leftid", KW_LEFTID},
- {"leftsubnetwithin", KW_LEFTSUBNETWITHIN},
+ {"rightupdown", KW_RIGHTUPDOWN},
+ {"keyexchange", KW_KEYEXCHANGE},
+ {"ocspuri", KW_OCSPURI},
+ {"compress", KW_COMPRESS},
+ {"rightcertpolicy", KW_RIGHTCERTPOLICY},
+ {"cacert", KW_CACERT},
{"eap_identity", KW_EAP_IDENTITY},
- {"cachecrls", KW_CACHECRLS},
- {"pfsgroup", KW_PFSGROUP},
- {"rightid2", KW_RIGHTID2},
- {"dpdaction", KW_DPDACTION},
- {"xauth_identity", KW_XAUTH_IDENTITY},
- {"leftsourceip", KW_LEFTSOURCEIP},
- {"klipsdebug", KW_KLIPSDEBUG},
- {"leftcert2", KW_LEFTCERT2},
- {"charondebug", KW_CHARONDEBUG},
{"hidetos", KW_HIDETOS},
{"ike", KW_IKE},
- {"charonstart", KW_CHARONSTART},
- {"rightauth2", KW_RIGHTAUTH2},
+ {"leftsubnetwithin", KW_LEFTSUBNETWITHIN},
+ {"righthostaccess", KW_RIGHTHOSTACCESS},
+ {"packetdefault", KW_PACKETDEFAULT},
+ {"dpdaction", KW_DPDACTION},
+ {"ocspuri1", KW_OCSPURI},
+ {"pfsgroup", KW_PFSGROUP},
+ {"rightauth", KW_RIGHTAUTH},
{"also", KW_ALSO},
- {"leftca2", KW_LEFTCA2},
+ {"leftsourceip", KW_LEFTSOURCEIP},
+ {"rightid2", KW_RIGHTID2},
+ {"dumpdir", KW_DUMPDIR},
{"rekey", KW_REKEY},
- {"plutostderrlog", KW_PLUTOSTDERRLOG},
- {"plutostart", KW_PLUTOSTART},
{"ikelifetime", KW_IKELIFETIME},
- {"crlcheckinterval", KW_CRLCHECKINTERVAL},
- {"auto", KW_AUTO},
+ {"dpdtimeout", KW_DPDTIMEOUT},
{"ldaphost", KW_LDAPHOST},
{"rekeyfuzz", KW_REKEYFUZZ},
+ {"leftcert2", KW_LEFTCERT2},
{"leftikeport", KW_LEFTIKEPORT},
+ {"crlcheckinterval", KW_CRLCHECKINTERVAL},
+ {"plutostderrlog", KW_PLUTOSTDERRLOG},
+ {"plutostart", KW_PLUTOSTART},
+ {"rightauth2", KW_RIGHTAUTH2},
+ {"leftca2", KW_LEFTCA2},
{"mark", KW_MARK},
- {"auth", KW_AUTH},
- {"prepluto", KW_PREPLUTO},
+ {"force_keepalive", KW_FORCE_KEEPALIVE},
+ {"auto", KW_AUTO},
+ {"charondebug", KW_CHARONDEBUG},
{"dpddelay", KW_DPDDELAY},
+ {"xauth_identity", KW_XAUTH_IDENTITY},
+ {"charonstart", KW_CHARONSTART},
+ {"fragicmp", KW_FRAGICMP},
+ {"prepluto", KW_PREPLUTO},
+ {"closeaction", KW_CLOSEACTION},
+ {"leftid2", KW_LEFTID2},
+ {"plutodebug", KW_PLUTODEBUG},
+ {"tfc", KW_TFC},
+ {"auth", KW_AUTH},
+ {"rekeymargin", KW_REKEYMARGIN},
+ {"modeconfig", KW_MODECONFIG},
{"leftauth", KW_LEFTAUTH},
- {"rightca2", KW_RIGHTCA2},
{"xauth", KW_XAUTH},
- {"rightcert2", KW_RIGHTCERT2},
- {"rekeymargin", KW_REKEYMARGIN},
- {"leftid2", KW_LEFTID2},
- {"ocspuri2", KW_OCSPURI2},
- {"nocrsend", KW_NOCRSEND},
- {"reauth", KW_REAUTH},
+ {"cachecrls", KW_CACHECRLS},
{"crluri2", KW_CRLURI2},
- {"plutodebug", KW_PLUTODEBUG},
+ {"postpluto", KW_POSTPLUTO},
+ {"nocrsend", KW_NOCRSEND},
{"leftauth2", KW_LEFTAUTH2},
+ {"rightca2", KW_RIGHTCA2},
+ {"rightcert2", KW_RIGHTCERT2},
{"pkcs11module", KW_PKCS11MODULE},
+ {"reauth", KW_REAUTH},
{"pkcs11initargs", KW_PKCS11INITARGS},
{"pkcs11keepstate", KW_PKCS11KEEPSTATE},
- {"pkcs11proxy", KW_PKCS11PROXY},
- {"modeconfig", KW_MODECONFIG},
- {"postpluto", KW_POSTPLUTO}
+ {"ocspuri2", KW_OCSPURI2},
+ {"pkcs11proxy", KW_PKCS11PROXY}
};
static const short lookup[] =
{
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 0, 1,
- -1, -1, -1, 2, 3, -1, 4, -1, 5, 6,
- 7, 8, 9, -1, 10, 11, 12, 13, 14, -1,
- 15, 16, -1, 17, 18, 19, 20, 21, -1, 22,
- -1, -1, 23, -1, 24, 25, 26, 27, -1, 28,
- 29, -1, -1, -1, 30, -1, 31, -1, -1, -1,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, -1,
- -1, 41, 42, 43, 44, 45, 46, -1, 47, 48,
- 49, -1, -1, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, -1, -1, 60, 61, 62, 63, 64,
- 65, -1, 66, 67, -1, 68, 69, -1, 70, 71,
- -1, -1, 72, 73, -1, 74, 75, 76, 77, -1,
- 78, -1, 79, -1, 80, -1, 81, 82, -1, 83,
- 84, 85, 86, 87, 88, 89, 90, -1, -1, 91,
- -1, -1, -1, 92, -1, 93, 94, -1, 95, 96,
- -1, 97, 98, -1, -1, -1, -1, 99, -1, -1,
- -1, 100, 101, 102, 103, 104, 105, 106, 107, -1,
- -1, -1, 108, -1, 109, -1, -1, 110, 111, -1,
- -1, -1, 112, -1, 113, 114, 115, -1, -1, -1,
- -1, -1, 116, 117, 118, -1, -1, -1, 119, -1,
- -1, 120, -1, -1, -1, -1, -1, -1, -1, 121,
- -1, -1, -1, 122, -1, -1, 123, -1, 124, -1,
- 125, 126, -1, -1, -1, -1, 127, -1, 128, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 129
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 0,
+ 1, 2, -1, -1, 3, 4, 5, 6, 7, 8,
+ -1, 9, 10, 11, 12, -1, 13, -1, 14, -1,
+ 15, 16, 17, -1, 18, 19, 20, -1, -1, -1,
+ 21, 22, 23, 24, 25, -1, -1, -1, 26, 27,
+ 28, -1, 29, -1, -1, -1, 30, -1, 31, 32,
+ 33, 34, 35, -1, 36, 37, -1, 38, -1, 39,
+ 40, -1, -1, 41, 42, 43, -1, -1, 44, 45,
+ 46, -1, 47, -1, 48, 49, 50, 51, 52, 53,
+ -1, 54, 55, -1, -1, -1, 56, -1, 57, 58,
+ 59, 60, -1, 61, -1, -1, 62, 63, 64, 65,
+ 66, -1, 67, 68, 69, 70, -1, 71, 72, 73,
+ 74, -1, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, -1, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, 93, 94, -1, 95, 96, 97, 98, -1, -1,
+ 99, 100, -1, -1, 101, -1, 102, -1, -1, 103,
+ -1, 104, 105, -1, 106, -1, -1, -1, -1, -1,
+ 107, 108, -1, -1, -1, -1, -1, 109, -1, -1,
+ -1, -1, 110, -1, 111, -1, -1, -1, -1, -1,
+ -1, -1, -1, 112, 113, 114, -1, 115, -1, 116,
+ -1, 117, -1, -1, 118, 119, -1, -1, -1, 120,
+ -1, -1, -1, -1, -1, 121, 122, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 123, -1, 124, -1,
+ -1, -1, -1, -1, -1, -1, 125, 126, 127, 128,
+ -1, -1, 129, -1, -1, -1, 130
};
#ifdef __GNUC__
diff --git a/src/starter/keywords.h b/src/starter/keywords.h
index 9f46a8b4b..02be919ea 100644
--- a/src/starter/keywords.h
+++ b/src/starter/keywords.h
@@ -91,6 +91,7 @@ typedef enum {
KW_DPDDELAY,
KW_DPDTIMEOUT,
KW_DPDACTION,
+ KW_CLOSEACTION,
KW_INACTIVITY,
KW_MODECONFIG,
KW_XAUTH,
diff --git a/src/starter/keywords.txt b/src/starter/keywords.txt
index 2c0e5de3d..548fa2f70 100644
--- a/src/starter/keywords.txt
+++ b/src/starter/keywords.txt
@@ -82,6 +82,7 @@ pfsgroup, KW_PFSGROUP
dpddelay, KW_DPDDELAY
dpdtimeout, KW_DPDTIMEOUT
dpdaction, KW_DPDACTION
+closeaction, KW_CLOSEACTION
inactivity, KW_INACTIVITY
modeconfig, KW_MODECONFIG
xauth, KW_XAUTH
diff --git a/src/starter/lex.yy.c b/src/starter/lexer.c
index 13bf87f0b..f093354d5 100644
--- a/src/starter/lex.yy.c
+++ b/src/starter/lexer.c
@@ -1,5 +1,5 @@
-#line 3 "lex.yy.c"
+#line 3 "lexer.c"
#define YY_INT_ALIGNED short int
@@ -487,9 +487,9 @@ int yy_flex_debug = 0;
#define YY_MORE_ADJ 0
#define YY_RESTORE_YY_MORE_OFFSET
char *yytext;
-#line 1 "./parser.l"
+#line 1 "lexer.l"
#define YY_NO_INPUT 1
-#line 4 "./parser.l"
+#line 4 "lexer.l"
/* FreeS/WAN config file parser (parser.l)
* Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
*
@@ -506,9 +506,12 @@ char *yytext;
#include <string.h>
#include <stdlib.h>
+
+#ifdef HAVE_GLOB_H
#include <glob.h>
+#endif
-#include "y.tab.h"
+#include "parser.h"
#define MAX_INCLUDE_DEPTH 20
@@ -561,65 +564,86 @@ void _parser_y_fini (void)
yylex_destroy();
}
-int _parser_y_include (const char *filename)
+/**
+ * parse the file located at filename
+ */
+int include_file(char *filename)
{
- glob_t files;
- int i, ret;
+ unsigned int p = __parser_y_private.stack_ptr + 1;
+ FILE *f;
- ret = glob(filename, GLOB_ERR, NULL, &files);
- if (ret)
+ if (p >= MAX_INCLUDE_DEPTH)
{
- const char *err;
-
- switch (ret)
- {
- case GLOB_NOSPACE:
- err = "include files ran out of memory";
- break;
- case GLOB_ABORTED:
- err = "include files aborted due to read error";
- break;
- case GLOB_NOMATCH:
- err = "include files found no matches";
- break;
- default:
- err = "unknown include files error";
- }
- yyerror(err);
+ yyerror("max inclusion depth reached");
return 1;
}
- for (i = 0; i < files.gl_pathc; i++)
+ f = fopen(filename, "r");
+ if (!f)
+ {
+ yyerror("can't open include filename");
+ return 0; /* ignore this error */
+ }
+
+ __parser_y_private.stack_ptr++;
+ __parser_y_private.file[p] = f;
+ __parser_y_private.stack[p] = YY_CURRENT_BUFFER;
+ __parser_y_private.line[p] = 1;
+ __parser_y_private.filename[p] = strdup(filename);
+
+ yy_switch_to_buffer(yy_create_buffer(f,YY_BUF_SIZE));
+ return 0;
+}
+
+int _parser_y_include (const char *filename)
+{
+ int ret = 0;
+#ifdef HAVE_GLOB_H
{
- FILE *f;
- unsigned int p = __parser_y_private.stack_ptr + 1;
+ glob_t files;
+ int i;
- if (p >= MAX_INCLUDE_DEPTH)
+ ret = glob(filename, GLOB_ERR, NULL, &files);
+ if (ret)
{
- yyerror("max inclusion depth reached");
+ const char *err;
+
+ switch (ret)
+ {
+ case GLOB_NOSPACE:
+ err = "include files ran out of memory";
+ break;
+ case GLOB_ABORTED:
+ err = "include files aborted due to read error";
+ break;
+ case GLOB_NOMATCH:
+ err = "include files found no matches";
+ break;
+ default:
+ err = "unknown include files error";
+ }
+ globfree(&files);
+ yyerror(err);
return 1;
}
- f = fopen(files.gl_pathv[i], "r");
- if (!f)
+ for (i = 0; i < files.gl_pathc; i++)
{
- yyerror("can't open include filename");
- continue;
+ if ((ret = include_file(files.gl_pathv[i])))
+ {
+ break;
+ }
}
-
- __parser_y_private.stack_ptr++;
- __parser_y_private.file[p] = f;
- __parser_y_private.stack[p] = YY_CURRENT_BUFFER;
- __parser_y_private.line[p] = 1;
- __parser_y_private.filename[p] = strdup(files.gl_pathv[i]);
-
- yy_switch_to_buffer(yy_create_buffer(f,YY_BUF_SIZE));
+ globfree(&files);
}
- globfree(&files);
- return 0;
+#else /* HAVE_GLOB_H */
+ /* if glob(3) is not available, try to load pattern directly */
+ ret = include_file(filename);
+#endif /* HAVE_GLOB_H */
+ return ret;
}
-#line 623 "lex.yy.c"
+#line 647 "lexer.c"
#define INITIAL 0
@@ -807,10 +831,10 @@ YY_DECL
register char *yy_cp, *yy_bp;
register int yy_act;
-#line 135 "./parser.l"
+#line 159 "lexer.l"
-#line 814 "lex.yy.c"
+#line 838 "lexer.c"
if ( !(yy_init) )
{
@@ -895,7 +919,7 @@ do_action: /* This label is used only to access EOF actions. */
goto yy_find_action;
case YY_STATE_EOF(INITIAL):
-#line 137 "./parser.l"
+#line 161 "lexer.l"
{
if (__parser_y_private.filename[__parser_y_private.stack_ptr]) {
free(__parser_y_private.filename[__parser_y_private.stack_ptr]);
@@ -915,23 +939,23 @@ case YY_STATE_EOF(INITIAL):
YY_BREAK
case 1:
YY_RULE_SETUP
-#line 154 "./parser.l"
+#line 178 "lexer.l"
return FIRST_SPACES;
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 156 "./parser.l"
+#line 180 "lexer.l"
/* ignore spaces in line */ ;
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 158 "./parser.l"
+#line 182 "lexer.l"
return EQUAL;
YY_BREAK
case 4:
/* rule 4 can match eol */
YY_RULE_SETUP
-#line 160 "./parser.l"
+#line 184 "lexer.l"
{
__parser_y_private.line[__parser_y_private.stack_ptr]++;
return EOL;
@@ -939,37 +963,37 @@ YY_RULE_SETUP
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 165 "./parser.l"
+#line 189 "lexer.l"
return CONFIG;
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 166 "./parser.l"
+#line 190 "lexer.l"
return SETUP;
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 167 "./parser.l"
+#line 191 "lexer.l"
return CONN;
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 168 "./parser.l"
+#line 192 "lexer.l"
return CA;
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 169 "./parser.l"
+#line 193 "lexer.l"
return INCLUDE;
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 170 "./parser.l"
+#line 194 "lexer.l"
return FILE_VERSION;
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 172 "./parser.l"
+#line 196 "lexer.l"
{
yylval.s = strdup(yytext);
return STRING;
@@ -977,7 +1001,7 @@ YY_RULE_SETUP
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 177 "./parser.l"
+#line 201 "lexer.l"
{
yylval.s = strdup(yytext+1);
if (yylval.s) yylval.s[strlen(yylval.s)-1]='\0';
@@ -986,15 +1010,15 @@ YY_RULE_SETUP
YY_BREAK
case 13:
YY_RULE_SETUP
-#line 183 "./parser.l"
+#line 207 "lexer.l"
yyerror(yytext);
YY_BREAK
case 14:
YY_RULE_SETUP
-#line 185 "./parser.l"
+#line 209 "lexer.l"
ECHO;
YY_BREAK
-#line 998 "lex.yy.c"
+#line 1022 "lexer.c"
case YY_END_OF_BUFFER:
{
@@ -1956,7 +1980,7 @@ void yyfree (void * ptr )
#define YYTABLES_NAME "yytables"
-#line 185 "./parser.l"
+#line 209 "lexer.l"
diff --git a/src/starter/parser.l b/src/starter/lexer.l
index c45847c5c..734776a74 100644
--- a/src/starter/parser.l
+++ b/src/starter/lexer.l
@@ -17,9 +17,12 @@
#include <string.h>
#include <stdlib.h>
+
+#ifdef HAVE_GLOB_H
#include <glob.h>
+#endif
-#include "y.tab.h"
+#include "parser.h"
#define MAX_INCLUDE_DEPTH 20
@@ -72,62 +75,83 @@ void _parser_y_fini (void)
yylex_destroy();
}
-int _parser_y_include (const char *filename)
+/**
+ * parse the file located at filename
+ */
+int include_file(char *filename)
{
- glob_t files;
- int i, ret;
+ unsigned int p = __parser_y_private.stack_ptr + 1;
+ FILE *f;
- ret = glob(filename, GLOB_ERR, NULL, &files);
- if (ret)
+ if (p >= MAX_INCLUDE_DEPTH)
{
- const char *err;
-
- switch (ret)
- {
- case GLOB_NOSPACE:
- err = "include files ran out of memory";
- break;
- case GLOB_ABORTED:
- err = "include files aborted due to read error";
- break;
- case GLOB_NOMATCH:
- err = "include files found no matches";
- break;
- default:
- err = "unknown include files error";
- }
- yyerror(err);
+ yyerror("max inclusion depth reached");
return 1;
}
- for (i = 0; i < files.gl_pathc; i++)
+ f = fopen(filename, "r");
+ if (!f)
+ {
+ yyerror("can't open include filename");
+ return 0; /* ignore this error */
+ }
+
+ __parser_y_private.stack_ptr++;
+ __parser_y_private.file[p] = f;
+ __parser_y_private.stack[p] = YY_CURRENT_BUFFER;
+ __parser_y_private.line[p] = 1;
+ __parser_y_private.filename[p] = strdup(filename);
+
+ yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
+ return 0;
+}
+
+int _parser_y_include (const char *filename)
+{
+ int ret = 0;
+#ifdef HAVE_GLOB_H
{
- FILE *f;
- unsigned int p = __parser_y_private.stack_ptr + 1;
+ glob_t files;
+ int i;
- if (p >= MAX_INCLUDE_DEPTH)
+ ret = glob(filename, GLOB_ERR, NULL, &files);
+ if (ret)
{
- yyerror("max inclusion depth reached");
+ const char *err;
+
+ switch (ret)
+ {
+ case GLOB_NOSPACE:
+ err = "include files ran out of memory";
+ break;
+ case GLOB_ABORTED:
+ err = "include files aborted due to read error";
+ break;
+ case GLOB_NOMATCH:
+ err = "include files found no matches";
+ break;
+ default:
+ err = "unknown include files error";
+ }
+ globfree(&files);
+ yyerror(err);
return 1;
}
- f = fopen(files.gl_pathv[i], "r");
- if (!f)
+ for (i = 0; i < files.gl_pathc; i++)
{
- yyerror("can't open include filename");
- continue;
+ if ((ret = include_file(files.gl_pathv[i])))
+ {
+ break;
+ }
}
-
- __parser_y_private.stack_ptr++;
- __parser_y_private.file[p] = f;
- __parser_y_private.stack[p] = YY_CURRENT_BUFFER;
- __parser_y_private.line[p] = 1;
- __parser_y_private.filename[p] = strdup(files.gl_pathv[i]);
-
- yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
+ globfree(&files);
}
- globfree(&files);
- return 0;
+#else /* HAVE_GLOB_H */
+ /* if glob(3) is not available, try to load pattern directly */
+ ret = include_file(filename);
+#endif /* HAVE_GLOB_H */
+ return ret;
}
%}
diff --git a/src/starter/netkey.c b/src/starter/netkey.c
index e0449f0b2..6646195cb 100644
--- a/src/starter/netkey.c
+++ b/src/starter/netkey.c
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <freeswan.h>
+#include <hydra.h>
#include "../pluto/constants.h"
#include "../pluto/defs.h"
@@ -66,18 +67,6 @@ starter_netkey_init(void)
void
starter_netkey_cleanup(void)
{
- if (system("ip xfrm state > /dev/null 2>&1") == 0)
- {
- ignore_result(system("ip xfrm state flush"));
- ignore_result(system("ip xfrm policy flush"));
- }
- else if (system("type setkey > /dev/null 2>&1") == 0)
- {
- ignore_result(system("setkey -F"));
- ignore_result(system("setkey -FP"));
- }
- else
- {
- plog("WARNING: cannot flush IPsec state/policy database");
- }
+ hydra->kernel_interface->flush_sas(hydra->kernel_interface);
+ hydra->kernel_interface->flush_policies(hydra->kernel_interface);
}
diff --git a/src/starter/y.tab.c b/src/starter/parser.c
index 504b5589e..ef668027d 100644
--- a/src/starter/y.tab.c
+++ b/src/starter/parser.c
@@ -68,7 +68,7 @@
/* Copy the first part of user declarations. */
/* Line 189 of yacc.c */
-#line 1 "./parser.y"
+#line 1 "parser.y"
/* strongSwan config file parser (parser.y)
* Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
@@ -93,7 +93,7 @@
#include "../pluto/constants.h"
#include "../pluto/defs.h"
#include "../pluto/log.h"
-#include "parser.h"
+#include "ipsec-parser.h"
#define YYERROR_VERBOSE
#define ERRSTRING_LEN 256
@@ -123,7 +123,7 @@ extern kw_entry_t *in_word_set (char *str, unsigned int len);
/* Line 189 of yacc.c */
-#line 127 "y.tab.c"
+#line 127 "parser.c"
/* Enabling traces. */
#ifndef YYDEBUG
@@ -182,12 +182,12 @@ typedef union YYSTYPE
{
/* Line 214 of yacc.c */
-#line 54 "./parser.y"
+#line 54 "parser.y"
char *s;
/* Line 214 of yacc.c */
-#line 191 "y.tab.c"
+#line 191 "parser.c"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -199,7 +199,7 @@ typedef union YYSTYPE
/* Line 264 of yacc.c */
-#line 203 "y.tab.c"
+#line 203 "parser.c"
#ifdef short
# undef short
@@ -1402,7 +1402,7 @@ yyreduce:
case 4:
/* Line 1455 of yacc.c */
-#line 71 "./parser.y"
+#line 71 "parser.y"
{
free((yyvsp[(2) - (3)].s));
}
@@ -1411,7 +1411,7 @@ yyreduce:
case 5:
/* Line 1455 of yacc.c */
-#line 75 "./parser.y"
+#line 75 "parser.y"
{
_parser_kw = &(_parser_cfg->config_setup);
_parser_kw_last = NULL;
@@ -1421,7 +1421,7 @@ yyreduce:
case 7:
/* Line 1455 of yacc.c */
-#line 80 "./parser.y"
+#line 80 "parser.y"
{
section_list_t *section = malloc_thing(section_list_t);
@@ -1442,7 +1442,7 @@ yyreduce:
case 9:
/* Line 1455 of yacc.c */
-#line 96 "./parser.y"
+#line 96 "parser.y"
{
section_list_t *section = malloc_thing(section_list_t);
section->name = clone_str((yyvsp[(2) - (3)].s));
@@ -1462,7 +1462,7 @@ yyreduce:
case 11:
/* Line 1455 of yacc.c */
-#line 111 "./parser.y"
+#line 111 "parser.y"
{
extern void _parser_y_include (const char *f);
_parser_y_include((yyvsp[(2) - (2)].s));
@@ -1473,7 +1473,7 @@ yyreduce:
case 16:
/* Line 1455 of yacc.c */
-#line 126 "./parser.y"
+#line 126 "parser.y"
{
kw_list_t *new;
kw_entry_t *entry = in_word_set((yyvsp[(1) - (3)].s), strlen((yyvsp[(1) - (3)].s)));
@@ -1503,7 +1503,7 @@ yyreduce:
case 17:
/* Line 1455 of yacc.c */
-#line 151 "./parser.y"
+#line 151 "parser.y"
{
free((yyvsp[(1) - (2)].s));
}
@@ -1512,7 +1512,7 @@ yyreduce:
/* Line 1455 of yacc.c */
-#line 1516 "y.tab.c"
+#line 1516 "parser.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -1724,7 +1724,7 @@ yyreturn:
/* Line 1675 of yacc.c */
-#line 157 "./parser.y"
+#line 157 "parser.y"
void yyerror(const char *s)
diff --git a/src/starter/parser.h b/src/starter/parser.h
index 1c6cf20ef..f0e666bb5 100644
--- a/src/starter/parser.h
+++ b/src/starter/parser.h
@@ -1,55 +1,88 @@
-/* strongSwan config file parser
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- *
- * 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 _IPSEC_PARSER_H_
-#define _IPSEC_PARSER_H_
-
-#include "keywords.h"
-
-typedef struct kw_entry kw_entry_t;
-
-struct kw_entry {
- char *name;
- kw_token_t token;
-};
-
-typedef struct kw_list kw_list_t;
-
-struct kw_list {
- kw_entry_t *entry;
- char *value;
- kw_list_t *next;
-};
-
-typedef struct section_list section_list_t;
-
-struct section_list {
- char *name;
- kw_list_t *kw;
- section_list_t *next;
-};
-
-typedef struct config_parsed config_parsed_t;
-
-struct config_parsed {
- kw_list_t *config_setup;
- section_list_t *conn_first, *conn_last;
- section_list_t *ca_first, *ca_last;
-};
-
-config_parsed_t *parser_load_conf (const char *file);
-void parser_free_conf (config_parsed_t *cfg);
-
-#endif /* _IPSEC_PARSER_H_ */
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ 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 3 of the License, or
+ (at your option) any later version.
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ EQUAL = 258,
+ FIRST_SPACES = 259,
+ EOL = 260,
+ CONFIG = 261,
+ SETUP = 262,
+ CONN = 263,
+ CA = 264,
+ INCLUDE = 265,
+ FILE_VERSION = 266,
+ STRING = 267
+ };
+#endif
+/* Tokens. */
+#define EQUAL 258
+#define FIRST_SPACES 259
+#define EOL 260
+#define CONFIG 261
+#define SETUP 262
+#define CONN 263
+#define CA 264
+#define INCLUDE 265
+#define FILE_VERSION 266
+#define STRING 267
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 1676 of yacc.c */
+#line 54 "parser.y"
+ char *s;
+
+
+/* Line 1676 of yacc.c */
+#line 80 "parser.h"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+extern YYSTYPE yylval;
+
diff --git a/src/starter/parser.y b/src/starter/parser.y
index b0b1f6f21..dfaec9ee8 100644
--- a/src/starter/parser.y
+++ b/src/starter/parser.y
@@ -22,7 +22,7 @@
#include "../pluto/constants.h"
#include "../pluto/defs.h"
#include "../pluto/log.h"
-#include "parser.h"
+#include "ipsec-parser.h"
#define YYERROR_VERBOSE
#define ERRSTRING_LEN 256
diff --git a/src/starter/starter.c b/src/starter/starter.c
index fcef2f7ff..44e21431c 100644
--- a/src/starter/starter.c
+++ b/src/starter/starter.c
@@ -29,6 +29,7 @@
#include <freeswan.h>
#include <library.h>
+#include <hydra.h>
#include "../pluto/constants.h"
#include "../pluto/defs.h"
@@ -161,60 +162,92 @@ static void fsig(int signal)
}
}
+#ifdef GENERATE_SELFCERT
static void generate_selfcert()
{
struct stat stb;
- /* if ipsec.secrets file is missing then generate RSA default key pair */
- if (stat(SECRETS_FILE, &stb) != 0)
- {
- mode_t oldmask;
- FILE *f;
- uid_t uid = 0;
- gid_t gid = 0;
+ /* if ipsec.secrets file is missing then generate RSA default key pair */
+ if (stat(SECRETS_FILE, &stb) != 0)
+ {
+ mode_t oldmask;
+ FILE *f;
+ uid_t uid = 0;
+ gid_t gid = 0;
#ifdef IPSEC_GROUP
- {
- char buf[1024];
- struct group group, *grp;
+ {
+ char buf[1024];
+ struct group group, *grp;
- if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) == 0 && grp)
- {
- gid = grp->gr_gid;
- }
+ if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) == 0 && grp)
+ {
+ gid = grp->gr_gid;
}
+ }
#endif
#ifdef IPSEC_USER
- {
- char buf[1024];
- struct passwd passwd, *pwp;
+ {
+ char buf[1024];
+ struct passwd passwd, *pwp;
- if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) == 0 && pwp)
- {
- uid = pwp->pw_uid;
- }
+ if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) == 0 && pwp)
+ {
+ uid = pwp->pw_uid;
}
+ }
#endif
- setegid(gid);
- seteuid(uid);
- ignore_result(system("ipsec scepclient --out pkcs1 --out cert-self --quiet"));
- seteuid(0);
- setegid(0);
+ setegid(gid);
+ seteuid(uid);
+ ignore_result(system("ipsec scepclient --out pkcs1 --out cert-self --quiet"));
+ seteuid(0);
+ setegid(0);
+
+ /* ipsec.secrets is root readable only */
+ oldmask = umask(0066);
+
+ f = fopen(SECRETS_FILE, "w");
+ if (f)
+ {
+ fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n");
+ fprintf(f, "\n");
+ fprintf(f, ": RSA myKey.der\n");
+ fclose(f);
+ }
+ ignore_result(chown(SECRETS_FILE, uid, gid));
+ umask(oldmask);
+ }
+}
+#endif /* GENERATE_SELFCERT */
- /* ipsec.secrets is root readable only */
- oldmask = umask(0066);
+static bool check_pid(char *pid_file)
+{
+ struct stat stb;
+ FILE *pidfile;
- f = fopen(SECRETS_FILE, "w");
- if (f)
+ if (stat(pid_file, &stb) == 0)
+ {
+ pidfile = fopen(pid_file, "r");
+ if (pidfile)
+ {
+ char buf[64];
+ pid_t pid = 0;
+ memset(buf, 0, sizeof(buf));
+ if (fread(buf, 1, sizeof(buf), pidfile))
{
- fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n");
- fprintf(f, "\n");
- fprintf(f, ": RSA myKey.der\n");
- fclose(f);
+ buf[sizeof(buf) - 1] = '\0';
+ pid = atoi(buf);
+ }
+ fclose(pidfile);
+ if (pid && kill(pid, 0) == 0)
+ { /* such a process is running */
+ return TRUE;
}
- ignore_result(chown(SECRETS_FILE, uid, gid));
- umask(oldmask);
}
+ plog("removing pidfile '%s', process not running", pid_file);
+ unlink(pid_file);
+ }
+ return FALSE;
}
static void usage(char *name)
@@ -233,7 +266,6 @@ int main (int argc, char **argv)
struct stat stb;
- char *err = NULL;
int i;
int id = 1;
struct timeval tv;
@@ -250,6 +282,9 @@ int main (int argc, char **argv)
library_init(NULL);
atexit(library_deinit);
+ libhydra_init("starter");
+ atexit(libhydra_deinit);
+
/* parse command line */
for (i = 1; i < argc; i++)
{
@@ -323,17 +358,19 @@ int main (int argc, char **argv)
exit(LSB_RC_NOT_ALLOWED);
}
- if (stat(PLUTO_PID_FILE, &stb) == 0)
+ if (check_pid(PLUTO_PID_FILE))
{
- plog("pluto is already running (%s exists) -- skipping pluto start", PLUTO_PID_FILE);
+ plog("pluto is already running (%s exists) -- skipping pluto start",
+ PLUTO_PID_FILE);
}
else
{
_action_ |= FLAG_ACTION_START_PLUTO;
}
- if (stat(CHARON_PID_FILE, &stb) == 0)
+ if (check_pid(CHARON_PID_FILE))
{
- plog("charon is already running (%s exists) -- skipping charon start", CHARON_PID_FILE);
+ plog("charon is already running (%s exists) -- skipping charon start",
+ CHARON_PID_FILE);
}
else
{
@@ -375,14 +412,17 @@ int main (int argc, char **argv)
last_reload = time_monotonic(NULL);
- if (stat(STARTER_PID_FILE, &stb) == 0)
+ if (check_pid(STARTER_PID_FILE))
{
- plog("starter is already running (%s exists) -- no fork done", STARTER_PID_FILE);
+ plog("starter is already running (%s exists) -- no fork done",
+ STARTER_PID_FILE);
confread_free(cfg);
exit(LSB_RC_SUCCESS);
}
+#ifdef GENERATE_SELFCERT
generate_selfcert();
+#endif
/* fork if we're not debugging stuff */
if (!no_fork)
@@ -393,8 +433,11 @@ int main (int argc, char **argv)
{
case 0:
{
- int fnull = open("/dev/null", O_RDWR);
+ int fnull;
+ closefrom(3);
+
+ fnull = open("/dev/null", O_RDWR);
if (fnull >= 0)
{
dup2(fnull, STDIN_FILENO);
@@ -402,6 +445,7 @@ int main (int argc, char **argv)
dup2(fnull, STDERR_FILENO);
close(fnull);
}
+
setsid();
}
break;
@@ -425,6 +469,13 @@ int main (int argc, char **argv)
}
}
+ /* load plugins */
+ if (!lib->plugins->load(lib->plugins, NULL,
+ lib->settings->get_str(lib->settings, "starter.load", PLUGINS)))
+ {
+ exit(LSB_RC_FAILURE);
+ }
+
for (;;)
{
/*
@@ -443,8 +494,8 @@ int main (int argc, char **argv)
starter_netkey_cleanup();
confread_free(cfg);
unlink(STARTER_PID_FILE);
- unlink(INFO_FILE);
plog("ipsec starter stopped");
+ lib->plugins->unload(lib->plugins);
close_log();
exit(LSB_RC_SUCCESS);
}
@@ -495,7 +546,6 @@ int main (int argc, char **argv)
*/
if (_action_ & FLAG_ACTION_UPDATE)
{
- err = NULL;
DBG(DBG_CONTROL,
DBG_log("Reloading config...")
);
diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c
index 7272b2530..ae04c20dd 100644
--- a/src/starter/starterstroke.c
+++ b/src/starter/starterstroke.c
@@ -24,6 +24,8 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <credentials/auth_cfg.h>
+
#include <freeswan.h>
#include <constants.h>
@@ -39,15 +41,6 @@
#define IPV4_LEN 4
#define IPV6_LEN 16
-/**
- * Authentication methods, must be the same as in charons authenticator.h
- */
-enum auth_method_t {
- AUTH_PUBKEY = 1,
- AUTH_PSK = 2,
- AUTH_EAP = 3
-};
-
static char* push_string(stroke_msg_t *msg, char *string)
{
unsigned long string_start = msg->length;
@@ -169,6 +162,7 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
msg_end->auth2 = push_string(msg, conn_end->auth2);
msg_end->id = push_string(msg, conn_end->id);
msg_end->id2 = push_string(msg, conn_end->id2);
+ msg_end->rsakey = push_string(msg, conn_end->rsakey);
msg_end->cert = push_string(msg, conn_end->cert);
msg_end->cert2 = push_string(msg, conn_end->cert2);
msg_end->cert_policy = push_string(msg, conn_end->cert_policy);
@@ -176,8 +170,15 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
msg_end->ca2 = push_string(msg, conn_end->ca2);
msg_end->groups = push_string(msg, conn_end->groups);
msg_end->updown = push_string(msg, conn_end->updown);
- ip_address2string(&conn_end->addr, buffer, sizeof(buffer));
- msg_end->address = push_string(msg, buffer);
+ if (conn_end->host)
+ {
+ msg_end->address = push_string(msg, conn_end->host);
+ }
+ else
+ {
+ ip_address2string(&conn_end->addr, buffer, sizeof(buffer));
+ msg_end->address = push_string(msg, buffer);
+ }
msg_end->ikeport = conn_end->ikeport;
msg_end->subnets = push_string(msg, conn_end->subnet);
msg_end->sourceip = push_string(msg, conn_end->sourceip);
@@ -202,15 +203,19 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
/* PUBKEY is preferred to PSK and EAP */
if (conn->policy & POLICY_PUBKEY)
{
- msg.add_conn.auth_method = AUTH_PUBKEY;
+ msg.add_conn.auth_method = AUTH_CLASS_PUBKEY;
}
else if (conn->policy & POLICY_PSK)
{
- msg.add_conn.auth_method = AUTH_PSK;
+ msg.add_conn.auth_method = AUTH_CLASS_PSK;
+ }
+ else if (conn->policy & POLICY_XAUTH_PSK)
+ {
+ msg.add_conn.auth_method = AUTH_CLASS_EAP;
}
else
{
- msg.add_conn.auth_method = AUTH_EAP;
+ msg.add_conn.auth_method = AUTH_CLASS_ANY;
}
msg.add_conn.eap_type = conn->eap_type;
msg.add_conn.eap_vendor = conn->eap_vendor;
@@ -230,6 +235,14 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
msg.add_conn.mode = MODE_TRANSPORT;
msg.add_conn.proxy_mode = TRUE;
}
+ else if (conn->policy & POLICY_SHUNT_PASS)
+ {
+ msg.add_conn.mode = MODE_PASS;
+ }
+ else if (conn->policy & (POLICY_SHUNT_DROP | POLICY_SHUNT_REJECT))
+ {
+ msg.add_conn.mode = MODE_DROP;
+ }
else
{
msg.add_conn.mode = MODE_TRANSPORT;
@@ -258,6 +271,7 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
msg.add_conn.algorithms.esp = push_string(&msg, conn->esp);
msg.add_conn.dpd.delay = conn->dpd_delay;
msg.add_conn.dpd.action = conn->dpd_action;
+ msg.add_conn.close_action = conn->close_action;
msg.add_conn.inactivity = conn->inactivity;
msg.add_conn.ikeme.mediation = conn->me_mediation;
msg.add_conn.ikeme.mediated_by = push_string(&msg, conn->me_mediated_by);
diff --git a/src/starter/y.tab.h b/src/starter/y.tab.h
deleted file mode 100644
index caf6ea172..000000000
--- a/src/starter/y.tab.h
+++ /dev/null
@@ -1,88 +0,0 @@
-
-/* A Bison parser, made by GNU Bison 2.4.1. */
-
-/* Skeleton interface for Bison's Yacc-like parsers in C
-
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- Free Software Foundation, Inc.
-
- 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 3 of the License, or
- (at your option) any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-
-/* Tokens. */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
- /* Put the tokens into the symbol table, so that GDB and other debuggers
- know about them. */
- enum yytokentype {
- EQUAL = 258,
- FIRST_SPACES = 259,
- EOL = 260,
- CONFIG = 261,
- SETUP = 262,
- CONN = 263,
- CA = 264,
- INCLUDE = 265,
- FILE_VERSION = 266,
- STRING = 267
- };
-#endif
-/* Tokens. */
-#define EQUAL 258
-#define FIRST_SPACES 259
-#define EOL 260
-#define CONFIG 261
-#define SETUP 262
-#define CONN 263
-#define CA 264
-#define INCLUDE 265
-#define FILE_VERSION 266
-#define STRING 267
-
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-{
-
-/* Line 1676 of yacc.c */
-#line 54 "./parser.y"
- char *s;
-
-
-/* Line 1676 of yacc.c */
-#line 80 "y.tab.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-extern YYSTYPE yylval;
-
-
diff --git a/src/stroke/Android.mk b/src/stroke/Android.mk
new file mode 100644
index 000000000..69b3e54ca
--- /dev/null
+++ b/src/stroke/Android.mk
@@ -0,0 +1,27 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# copy-n-paste from Makefile.am
+LOCAL_SRC_FILES := \
+stroke.c stroke_msg.h stroke_keywords.c stroke_keywords.h
+
+# build stroke -----------------------------------------------------------------
+
+LOCAL_C_INCLUDES += \
+ $(libvstr_PATH) \
+ $(strongswan_PATH)/src/libstrongswan
+
+LOCAL_CFLAGS := $(strongswan_CFLAGS)
+
+LOCAL_MODULE := stroke
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_SHARED_LIBRARIES += libstrongswan
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/src/stroke/Makefile.am b/src/stroke/Makefile.am
index 363cde717..f93680b64 100644
--- a/src/stroke/Makefile.am
+++ b/src/stroke/Makefile.am
@@ -1,9 +1,11 @@
ipsec_PROGRAMS = stroke
-stroke_SOURCES = stroke.c stroke_msg.h stroke_keywords.c stroke_keywords.h
+stroke_SOURCES = \
+stroke.c stroke_msg.h stroke_keywords.c stroke_keywords.h
+
stroke_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la $(SOCKLIB)
INCLUDES = -I$(top_srcdir)/src/libstrongswan
-EXTRA_DIST = stroke_keywords.txt
+EXTRA_DIST = stroke_keywords.txt Android.mk
BUILT_SOURCES = stroke_keywords.c
MAINTAINERCLEANFILES = stroke_keywords.c
AM_CFLAGS = -DIPSEC_PIDDIR=\"${piddir}\"
diff --git a/src/stroke/Makefile.in b/src/stroke/Makefile.in
index 4e8318e0f..946bacc20 100644
--- a/src/stroke/Makefile.in
+++ b/src/stroke/Makefile.in
@@ -169,6 +169,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -177,6 +180,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -193,11 +197,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -241,6 +247,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -251,10 +258,12 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-stroke_SOURCES = stroke.c stroke_msg.h stroke_keywords.c stroke_keywords.h
+stroke_SOURCES = \
+stroke.c stroke_msg.h stroke_keywords.c stroke_keywords.h
+
stroke_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la $(SOCKLIB)
INCLUDES = -I$(top_srcdir)/src/libstrongswan
-EXTRA_DIST = stroke_keywords.txt
+EXTRA_DIST = stroke_keywords.txt Android.mk
BUILT_SOURCES = stroke_keywords.c
MAINTAINERCLEANFILES = stroke_keywords.c
AM_CFLAGS = -DIPSEC_PIDDIR=\"${piddir}\"
diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c
index 2c5a03d77..bb299567b 100644
--- a/src/stroke/stroke.c
+++ b/src/stroke/stroke.c
@@ -1,5 +1,5 @@
/* Stroke for charon is the counterpart to whack from pluto
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2012 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -19,7 +19,6 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
-#include <sys/fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
@@ -90,9 +89,11 @@ static int send_stroke_msg (stroke_msg_t *msg)
{
buffer[byte_count] = '\0';
- /* we prompt if we receive the "Passphrase:"/"PIN:" magic keyword */
+ /* we prompt if we receive a magic keyword */
if ((byte_count >= 12 &&
strcmp(buffer + byte_count - 12, "Passphrase:\n") == 0) ||
+ (byte_count >= 10 &&
+ strcmp(buffer + byte_count - 10, "Password:\n") == 0) ||
(byte_count >= 5 &&
strcmp(buffer + byte_count - 5, "PIN:\n") == 0))
{
@@ -102,7 +103,11 @@ static int send_stroke_msg (stroke_msg_t *msg)
{
*pass = ' ';
}
+#ifdef HAVE_GETPASS
pass = getpass(buffer);
+#else
+ pass = "";
+#endif
if (pass)
{
ignore_result(write(sock, pass, strlen(pass)));
@@ -231,7 +236,18 @@ static int show_status(stroke_keyword_t kw, char *connection)
{
stroke_msg_t msg;
- msg.type = (kw == STROKE_STATUS)? STR_STATUS:STR_STATUS_ALL;
+ switch (kw)
+ {
+ case STROKE_STATUSALL:
+ msg.type = STR_STATUS_ALL;
+ break;
+ case STROKE_STATUSALL_NOBLK:
+ msg.type = STR_STATUS_ALL_NOBLK;
+ break;
+ default:
+ msg.type = STR_STATUS;
+ break;
+ }
msg.length = offsetof(stroke_msg_t, buffer);
msg.status.name = push_string(&msg, connection);
return send_stroke_msg(&msg);
@@ -249,6 +265,7 @@ static int list_flags[] = {
LIST_CRLS,
LIST_OCSP,
LIST_ALGS,
+ LIST_PLUGINS,
LIST_ALL
};
@@ -326,6 +343,28 @@ static int leases(stroke_keyword_t kw, char *pool, char *address)
return send_stroke_msg(&msg);
}
+static int memusage()
+{
+ stroke_msg_t msg;
+
+ msg.type = STR_MEMUSAGE;
+ msg.length = offsetof(stroke_msg_t, buffer);
+ return send_stroke_msg(&msg);
+}
+
+static int user_credentials(char *name, char *user, char *pass)
+{
+ stroke_msg_t msg;
+
+ msg.type = STR_USER_CREDS;
+ msg.length = offsetof(stroke_msg_t, buffer);
+ msg.user_creds.name = push_string(&msg, name);
+ msg.user_creds.username = push_string(&msg, user);
+ msg.user_creds.password = push_string(&msg, pass);
+ return send_stroke_msg(&msg);
+}
+
+
static int set_loglevel(char *type, u_int level)
{
stroke_msg_t msg;
@@ -369,10 +408,14 @@ static void exit_usage(char *error)
printf(" where: START and optional END define the clients source IP\n");
printf(" Set loglevel for a logging type:\n");
printf(" stroke loglevel TYPE LEVEL\n");
- printf(" where: TYPE is any|dmn|mgr|ike|chd|job|cfg|knl|net|enc|lib\n");
+ printf(" where: TYPE is any|dmn|mgr|ike|chd|job|cfg|knl|net|asn|enc|tnc|imc|imv|pts|tls|lib\n");
printf(" LEVEL is -1|0|1|2|3|4\n");
printf(" Show connection status:\n");
printf(" stroke status\n");
+ printf(" Show extended status information:\n");
+ printf(" stroke statusall\n");
+ printf(" Show extended status information without blocking:\n");
+ printf(" stroke statusallnb\n");
printf(" Show list of authority and attribute certificates:\n");
printf(" stroke listcacerts|listocspcerts|listaacerts|listacerts\n");
printf(" Show list of end entity certificates, ca info records and crls:\n");
@@ -393,8 +436,15 @@ static void exit_usage(char *error)
printf(" stroke purgeike\n");
printf(" Export credentials to the console:\n");
printf(" stroke exportx509 DN\n");
+ printf(" Show current memory usage:\n");
+ printf(" stroke memusage\n");
printf(" Show leases of a pool:\n");
printf(" stroke leases [POOL [ADDRESS]]\n");
+ printf(" Set username and password for a connection:\n");
+ printf(" stroke user-creds NAME USERNAME [PASSWORD]\n");
+ printf(" where: NAME is a connection name added with \"stroke add\"\n");
+ printf(" USERNAME is the username\n");
+ printf(" PASSWORD is the optional password, you'll be asked to enter it if not given\n");
exit_error(error);
}
@@ -489,6 +539,7 @@ int main(int argc, char *argv[])
break;
case STROKE_STATUS:
case STROKE_STATUSALL:
+ case STROKE_STATUSALL_NOBLK:
res = show_status(token->kw, argc > 2 ? argv[2] : NULL);
break;
case STROKE_LIST_PUBKEYS:
@@ -501,6 +552,7 @@ int main(int argc, char *argv[])
case STROKE_LIST_CRLS:
case STROKE_LIST_OCSP:
case STROKE_LIST_ALGS:
+ case STROKE_LIST_PLUGINS:
case STROKE_LIST_ALL:
res = list(token->kw, argc > 2 && strcmp(argv[2], "--utc") == 0);
break;
@@ -530,6 +582,17 @@ int main(int argc, char *argv[])
res = leases(token->kw, argc > 2 ? argv[2] : NULL,
argc > 3 ? argv[3] : NULL);
break;
+ case STROKE_MEMUSAGE:
+ res = memusage();
+ break;
+ case STROKE_USER_CREDS:
+ if (argc < 4)
+ {
+ exit_usage("\"user-creds\" needs a connection name, "
+ "username and optionally a password");
+ }
+ res = user_credentials(argv[2], argv[3], argc > 4 ? argv[4] : NULL);
+ break;
default:
exit_usage(NULL);
}
diff --git a/src/stroke/stroke_keywords.c b/src/stroke/stroke_keywords.c
index b43f4b475..b5ca2e143 100644
--- a/src/stroke/stroke_keywords.c
+++ b/src/stroke/stroke_keywords.c
@@ -54,12 +54,12 @@ struct stroke_token {
stroke_keyword_t kw;
};
-#define TOTAL_KEYWORDS 37
+#define TOTAL_KEYWORDS 41
#define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 15
#define MIN_HASH_VALUE 2
-#define MAX_HASH_VALUE 42
-/* maximum key range = 41, duplicates = 0 */
+#define MAX_HASH_VALUE 44
+/* maximum key range = 43, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -75,32 +75,32 @@ hash (str, len)
{
static const unsigned char asso_values[] =
{
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 20, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 0, 23, 1,
- 1, 15, 43, 21, 43, 23, 43, 9, 0, 43,
- 43, 10, 2, 43, 6, 5, 1, 0, 43, 43,
- 2, 19, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 43, 43, 43, 43
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 15, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 0, 30, 1,
+ 1, 15, 45, 15, 45, 30, 45, 13, 0, 0,
+ 45, 9, 3, 45, 6, 18, 1, 0, 45, 45,
+ 5, 0, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45
};
register int hval = len;
@@ -132,10 +132,10 @@ static const struct stroke_token wordlist[] =
{"listall", STROKE_LIST_ALL},
{"delete", STROKE_DELETE},
{"listcrls", STROKE_LIST_CRLS},
- {"status", STROKE_STATUS},
+ {"rekey", STROKE_REKEY},
{"listaacerts", STROKE_LIST_AACERTS},
{"listcacerts", STROKE_LIST_CACERTS},
- {"statusall", STROKE_STATUSALL},
+ {"listplugins", STROKE_LIST_PLUGINS},
{"rereadall", STROKE_REREAD_ALL},
{"listcerts", STROKE_LIST_CERTS},
{"rereadcrls", STROKE_REREAD_CRLS},
@@ -144,32 +144,36 @@ static const struct stroke_token wordlist[] =
{"rereadcacerts", STROKE_REREAD_CACERTS},
{"leases", STROKE_LEASES},
{"unroute", STROKE_UNROUTE},
- {"listocsp", STROKE_LIST_OCSP},
- {"rereadsecrets", STROKE_REREAD_SECRETS},
+ {"listalgs", STROKE_LIST_ALGS},
+ {"status", STROKE_STATUS},
{"listacerts", STROKE_LIST_ACERTS},
{"route", STROKE_ROUTE},
+ {"statusall", STROKE_STATUSALL},
{"purgeocsp", STROKE_PURGE_OCSP},
- {"listocspcerts", STROKE_LIST_OCSPCERTS},
- {"listalgs", STROKE_LIST_ALGS},
- {"rekey", STROKE_REKEY},
+ {"statusallnb", STROKE_STATUSALL_NOBLK},
{"rereadocspcerts", STROKE_REREAD_OCSPCERTS},
+ {"user-creds", STROKE_USER_CREDS},
+ {"down-srcip", STROKE_DOWN_SRCIP},
{"purgecrls", STROKE_PURGE_CRLS},
+ {"listgroups", STROKE_LIST_GROUPS},
+ {"listocsp", STROKE_LIST_OCSP},
{"exportx509", STROKE_EXPORT_X509},
+ {"rereadsecrets", STROKE_REREAD_SECRETS},
+ {"loglevel", STROKE_LOGLEVEL},
{"purgeike", STROKE_PURGE_IKE},
+ {"listocspcerts", STROKE_LIST_OCSPCERTS},
+ {"memusage", STROKE_MEMUSAGE},
{"listcainfos", STROKE_LIST_CAINFOS},
- {"listpubkeys", STROKE_LIST_PUBKEYS},
- {"down-srcip", STROKE_DOWN_SRCIP},
- {"loglevel", STROKE_LOGLEVEL},
- {"listgroups", STROKE_LIST_GROUPS},
- {"purgecerts", STROKE_PURGE_CERTS}
+ {"purgecerts", STROKE_PURGE_CERTS},
+ {"listpubkeys", STROKE_LIST_PUBKEYS}
};
static const short lookup[] =
{
-1, -1, 0, 1, 2, 3, -1, 4, 5, 6, -1, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, -1, -1, 35,
- 36
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40
};
#ifdef __GNUC__
diff --git a/src/stroke/stroke_keywords.h b/src/stroke/stroke_keywords.h
index ff2ba36ef..554d071f3 100644
--- a/src/stroke/stroke_keywords.h
+++ b/src/stroke/stroke_keywords.h
@@ -29,6 +29,7 @@ typedef enum {
STROKE_LOGLEVEL,
STROKE_STATUS,
STROKE_STATUSALL,
+ STROKE_STATUSALL_NOBLK,
STROKE_LIST_PUBKEYS,
STROKE_LIST_CERTS,
STROKE_LIST_CACERTS,
@@ -40,6 +41,7 @@ typedef enum {
STROKE_LIST_CRLS,
STROKE_LIST_OCSP,
STROKE_LIST_ALGS,
+ STROKE_LIST_PLUGINS,
STROKE_LIST_ALL,
STROKE_REREAD_SECRETS,
STROKE_REREAD_CACERTS,
@@ -54,6 +56,8 @@ typedef enum {
STROKE_PURGE_IKE,
STROKE_EXPORT_X509,
STROKE_LEASES,
+ STROKE_MEMUSAGE,
+ STROKE_USER_CREDS,
} stroke_keyword_t;
#define STROKE_LIST_FIRST STROKE_LIST_PUBKEYS
diff --git a/src/stroke/stroke_keywords.txt b/src/stroke/stroke_keywords.txt
index dafd1ab08..1d7ab8a45 100644
--- a/src/stroke/stroke_keywords.txt
+++ b/src/stroke/stroke_keywords.txt
@@ -36,6 +36,7 @@ rekey, STROKE_REKEY
loglevel, STROKE_LOGLEVEL
status, STROKE_STATUS
statusall, STROKE_STATUSALL
+statusallnb, STROKE_STATUSALL_NOBLK
listpubkeys, STROKE_LIST_PUBKEYS
listcerts, STROKE_LIST_CERTS
listcacerts, STROKE_LIST_CACERTS
@@ -47,6 +48,7 @@ listcainfos, STROKE_LIST_CAINFOS
listcrls, STROKE_LIST_CRLS
listocsp, STROKE_LIST_OCSP
listalgs, STROKE_LIST_ALGS
+listplugins, STROKE_LIST_PLUGINS
listall, STROKE_LIST_ALL
rereadsecrets, STROKE_REREAD_SECRETS
rereadcacerts, STROKE_REREAD_CACERTS
@@ -61,3 +63,5 @@ purgecerts, STROKE_PURGE_CERTS
purgeike, STROKE_PURGE_IKE
exportx509, STROKE_EXPORT_X509
leases, STROKE_LEASES
+memusage, STROKE_MEMUSAGE
+user-creds, STROKE_USER_CREDS
diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h
index 9800d4319..434122511 100644
--- a/src/stroke/stroke_msg.h
+++ b/src/stroke/stroke_msg.h
@@ -65,8 +65,10 @@ enum list_flag_t {
LIST_OCSP = 0x0200,
/** list all supported algorithms */
LIST_ALGS = 0x0400,
+ /** list plugin information */
+ LIST_PLUGINS = 0x0800,
/** all list options */
- LIST_ALL = 0x07FF,
+ LIST_ALL = 0x0FFF,
};
typedef enum reread_flag_t reread_flag_t;
@@ -144,6 +146,7 @@ struct stroke_end_t {
char *id;
char *id2;
char *eap_id;
+ char *rsakey;
char *cert;
char *cert2;
char *ca;
@@ -194,6 +197,8 @@ struct stroke_msg_t {
STR_STATUS,
/* show verbose connection status */
STR_STATUS_ALL,
+ /* show verbose connection status, non-blocking variant */
+ STR_STATUS_ALL_NOBLK,
/* add a ca information record */
STR_ADD_CA,
/* delete ca information record */
@@ -212,6 +217,10 @@ struct stroke_msg_t {
STR_LEASES,
/* export credentials */
STR_EXPORT,
+ /* print memory usage details */
+ STR_MEMUSAGE,
+ /* set username and password for a connection */
+ STR_USER_CREDS,
/* more to come */
} type;
@@ -247,6 +256,7 @@ struct stroke_msg_t {
time_t inactivity;
int proxy_mode;
int install_policy;
+ int close_action;
u_int32_t reqid;
u_int32_t tfc;
@@ -333,6 +343,13 @@ struct stroke_msg_t {
char *pool;
char *address;
} leases;
+
+ /* data for STR_USER_CREDS */
+ struct {
+ char *name;
+ char *username;
+ char *password;
+ } user_creds;
};
char buffer[STROKE_BUF_LEN];
};
diff --git a/src/whack/Android.mk b/src/whack/Android.mk
new file mode 100644
index 000000000..bf5ec0e98
--- /dev/null
+++ b/src/whack/Android.mk
@@ -0,0 +1,30 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# copy-n-paste from Makefile.am
+LOCAL_SRC_FILES := \
+whack.c whack.h
+
+# build whack ------------------------------------------------------------------
+
+LOCAL_C_INCLUDES += \
+ $(libvstr_PATH) \
+ $(strongswan_PATH)/src/libstrongswan \
+ $(strongswan_PATH)/src/libfreeswan \
+ $(strongswan_PATH)/src/libhydra \
+ $(strongswan_PATH)/src/pluto
+
+LOCAL_CFLAGS := $(strongswan_CFLAGS)
+
+LOCAL_MODULE := whack
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_SHARED_LIBRARIES += libstrongswan libfreeswan
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/src/whack/Makefile.am b/src/whack/Makefile.am
index 316a83312..23374475e 100644
--- a/src/whack/Makefile.am
+++ b/src/whack/Makefile.am
@@ -1,6 +1,7 @@
ipsec_PROGRAMS = whack
-whack_SOURCES = whack.c whack.h
+whack_SOURCES = \
+whack.c whack.h
INCLUDES = \
-I$(top_srcdir)/src/libstrongswan \
@@ -12,5 +13,6 @@ whack_LDADD = \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
$(top_builddir)/src/libfreeswan/libfreeswan.a
-AM_CFLAGS = -DDEBUG
+AM_CFLAGS = -DDEBUG -DIPSEC_PIDDIR=\"${piddir}\"
+EXTRA_DIST = Android.mk
diff --git a/src/whack/Makefile.in b/src/whack/Makefile.in
index f62c2bfc0..fd768e995 100644
--- a/src/whack/Makefile.in
+++ b/src/whack/Makefile.in
@@ -168,6 +168,9 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
+attest_plugins = @attest_plugins@
+axis2c_CFLAGS = @axis2c_CFLAGS@
+axis2c_LIBS = @axis2c_LIBS@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -176,6 +179,7 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
@@ -192,11 +196,13 @@ host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
+imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
+ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -240,6 +246,7 @@ sharedstatedir = @sharedstatedir@
soup_CFLAGS = @soup_CFLAGS@
soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
+starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
@@ -250,7 +257,9 @@ top_srcdir = @top_srcdir@
urandom_device = @urandom_device@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-whack_SOURCES = whack.c whack.h
+whack_SOURCES = \
+whack.c whack.h
+
INCLUDES = \
-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libfreeswan \
@@ -261,7 +270,8 @@ whack_LDADD = \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
$(top_builddir)/src/libfreeswan/libfreeswan.a
-AM_CFLAGS = -DDEBUG
+AM_CFLAGS = -DDEBUG -DIPSEC_PIDDIR=\"${piddir}\"
+EXTRA_DIST = Android.mk
all: all-am
.SUFFIXES:
diff --git a/src/whack/whack.c b/src/whack/whack.c
index ac2d3ea40..a7945d6d8 100644
--- a/src/whack/whack.c
+++ b/src/whack/whack.c
@@ -176,7 +176,7 @@ static void help(void)
" \\\n "
" [--debug-control]"
" [--debug-lifecycle]"
- " [--debug-klips]"
+ " [--debug-kernel]"
" [--debug-dns]"
" \\\n "
" [--debug-natt]"
@@ -207,6 +207,7 @@ static void help(void)
" [--listcrls]"
" [--listocsp]"
" [--listcards]"
+ " [--listplugins]"
" [--listall]"
"\n\n"
"purge: whack"
@@ -379,6 +380,7 @@ enum {
LST_CRLS,
LST_OCSP,
LST_CARDS,
+ LST_PLUGINS,
LST_ALL,
# define LST_LAST LST_ALL /* last list option */
@@ -571,6 +573,7 @@ static const struct option long_opts[] = {
{ "listcrls", no_argument, NULL, LST_CRLS + OO },
{ "listocsp", no_argument, NULL, LST_OCSP + OO },
{ "listcards", no_argument, NULL, LST_CARDS + OO },
+ { "listplugins", no_argument, NULL, LST_PLUGINS + OO },
{ "listall", no_argument, NULL, LST_ALL + OO },
/* options for an end description */
@@ -797,12 +800,14 @@ static void check_end(whack_end_t *this, whack_end_t *that,
static void get_secret(int sock)
{
- const char *buf, *secret;
+ const char *buf = NULL, *secret;
int len;
fflush(stdout);
usleep(20000); /* give fflush time for flushing */
+#ifdef HAVE_GETPASS
buf = getpass("Enter: ");
+#endif
secret = (buf == NULL)? "" : buf;
/* send the secret to pluto */
@@ -1232,6 +1237,7 @@ int main(int argc, char **argv)
case LST_CRLS: /* --listcrls */
case LST_OCSP: /* --listocsp */
case LST_CARDS: /* --listcards */
+ case LST_PLUGINS: /* --listplugins */
msg.whack_list |= LELEM(c - LST_ALGS);
continue;
diff --git a/src/whack/whack.h b/src/whack/whack.h
index f8e6a9a88..c92eaf3cf 100644
--- a/src/whack/whack.h
+++ b/src/whack/whack.h
@@ -333,8 +333,9 @@ enum rc_type {
#define LIST_CRLS 0x0200 /* list all crls */
#define LIST_OCSP 0x0400 /* list all ocsp cache entries */
#define LIST_CARDS 0x0800 /* list all smartcard records */
+#define LIST_PLUGINS 0x1000 /* list all plugins with dependencies */
-#define LIST_ALL LRANGES(LIST_ALGS, LIST_CARDS) /* all list options */
+#define LIST_ALL LRANGES(LIST_ALGS, LIST_PLUGINS) /* all list options */
/* options of whack --reread*** command */