summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins')
-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_radius/radius_client.c186
-rw-r--r--src/libcharon/plugins/eap_radius/radius_client.h66
-rw-r--r--src/libcharon/plugins/eap_radius/radius_message.c457
-rw-r--r--src/libcharon/plugins/eap_radius/radius_message.h276
-rw-r--r--src/libcharon/plugins/eap_radius/radius_server.c219
-rw-r--r--src/libcharon/plugins/eap_radius/radius_server.h97
-rw-r--r--src/libcharon/plugins/eap_radius/radius_socket.c355
-rw-r--r--src/libcharon/plugins/eap_radius/radius_socket.h76
-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.c712
-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
273 files changed, 14493 insertions, 4277 deletions
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_radius/radius_client.c b/src/libcharon/plugins/eap_radius/radius_client.c
deleted file mode 100644
index 245308e59..000000000
--- a/src/libcharon/plugins/eap_radius/radius_client.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "radius_client.h"
-
-#include "eap_radius_plugin.h"
-#include "radius_server.h"
-
-#include <unistd.h>
-#include <errno.h>
-
-#include <daemon.h>
-#include <utils/host.h>
-#include <utils/linked_list.h>
-#include <threading/condvar.h>
-#include <threading/mutex.h>
-
-typedef struct private_radius_client_t private_radius_client_t;
-
-/**
- * Private data of an radius_client_t object.
- */
-struct private_radius_client_t {
-
- /**
- * Public radius_client_t interface.
- */
- radius_client_t public;
-
- /**
- * Selected RADIUS server
- */
- radius_server_t *server;
-
- /**
- * RADIUS servers State attribute
- */
- chunk_t state;
-
- /**
- * EAP MSK, from MPPE keys
- */
- chunk_t msk;
-};
-
-/**
- * Save the state attribute to include in further request
- */
-static void save_state(private_radius_client_t *this, radius_message_t *msg)
-{
- enumerator_t *enumerator;
- int type;
- chunk_t data;
-
- enumerator = msg->create_enumerator(msg);
- while (enumerator->enumerate(enumerator, &type, &data))
- {
- if (type == RAT_STATE)
- {
- free(this->state.ptr);
- this->state = chunk_clone(data);
- enumerator->destroy(enumerator);
- return;
- }
- }
- enumerator->destroy(enumerator);
- /* no state attribute found, remove state */
- chunk_free(&this->state);
-}
-
-METHOD(radius_client_t, request, radius_message_t*,
- private_radius_client_t *this, radius_message_t *req)
-{
- char virtual[] = {0x00,0x00,0x00,0x05};
- radius_socket_t *socket;
- radius_message_t *res;
-
- /* 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));
- /* 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);
- DBG1(DBG_CFG, "sending RADIUS %N to server '%s'", radius_message_code_names,
- req->get_code(req), this->server->get_name(this->server));
- 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));
- 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);
- return res;
- }
- this->server->put_socket(this->server, socket, FALSE);
- charon->bus->alert(charon->bus, ALERT_RADIUS_NOT_RESPONDING);
- return NULL;
-}
-
-METHOD(radius_client_t, get_msk, chunk_t,
- private_radius_client_t *this)
-{
- return this->msk;
-}
-
-METHOD(radius_client_t, destroy, void,
- private_radius_client_t *this)
-{
- this->server->destroy(this->server);
- chunk_clear(&this->msk);
- free(this->state.ptr);
- free(this);
-}
-
-/**
- * See header
- */
-radius_client_t *radius_client_create()
-{
- private_radius_client_t *this;
- enumerator_t *enumerator;
- radius_server_t *server;
- int current, best = -1;
-
- INIT(this,
- .public = {
- .request = _request,
- .get_msk = _get_msk,
- .destroy = _destroy,
- },
- );
-
- 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/libcharon/plugins/eap_radius/radius_client.h
deleted file mode 100644
index e4f3a7222..000000000
--- a/src/libcharon/plugins/eap_radius/radius_client.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup radius_client radius_client
- * @{ @ingroup eap_radius
- */
-
-#ifndef RADIUS_CLIENT_H_
-#define RADIUS_CLIENT_H_
-
-#include "radius_message.h"
-
-typedef struct radius_client_t radius_client_t;
-
-/**
- * RADIUS client functionality.
- *
- * To communicate with a RADIUS server, create a client and send messages over
- * it. The client allocates a socket from the best RADIUS server abailable.
- */
-struct radius_client_t {
-
- /**
- * Send a RADIUS request and wait for the response.
- *
- * The client fills in NAS-Identifier nad NAS-Port-Type
- *
- * @param msg RADIUS request message to send
- * @return response, NULL if timed out/verification failed
- */
- radius_message_t* (*request)(radius_client_t *this, radius_message_t *msg);
-
- /**
- * Get the EAP MSK after successful RADIUS authentication.
- *
- * @return MSK, allocated
- */
- chunk_t (*get_msk)(radius_client_t *this);
-
- /**
- * Destroy the client, release the socket.
- */
- void (*destroy)(radius_client_t *this);
-};
-
-/**
- * Create a RADIUS client.
- *
- * @return radius_client_t object
- */
-radius_client_t *radius_client_create();
-
-#endif /** RADIUS_CLIENT_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/radius_message.c b/src/libcharon/plugins/eap_radius/radius_message.c
deleted file mode 100644
index 23a29b772..000000000
--- a/src/libcharon/plugins/eap_radius/radius_message.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "radius_message.h"
-
-#include <daemon.h>
-#include <crypto/hashers/hasher.h>
-
-typedef struct private_radius_message_t private_radius_message_t;
-typedef struct rmsg_t rmsg_t;
-typedef struct rattr_t rattr_t;
-
-/**
- * RADIUS message header
- */
-struct rmsg_t {
- /** message code, radius_message_code_t */
- u_int8_t code;
- /** message identifier */
- u_int8_t identifier;
- /** length of Code, Identifier, Length, Authenticator and Attributes */
- u_int16_t length;
- /** message authenticator, MD5 hash */
- u_int8_t authenticator[HASH_SIZE_MD5];
- /** variable list of packed attributes */
- u_int8_t attributes[];
-} __attribute__((packed));
-
-/**
- * RADIUS message attribute.
- */
-struct rattr_t {
- /** attribute type, radius_attribute_type_t */
- u_int8_t type;
- /** length of the attriubte, including the Type, Length and Value fields */
- u_int8_t length;
- /** variable length attribute value */
- u_int8_t value[];
-} __attribute__((packed));
-
-/**
- * Private data of an radius_message_t object.
- */
-struct private_radius_message_t {
-
- /**
- * Public radius_message_t interface.
- */
- radius_message_t public;
-
- /**
- * message data, allocated
- */
- rmsg_t *msg;
-};
-
-ENUM_BEGIN(radius_message_code_names, RMC_ACCESS_REQUEST, RMC_ACCOUNTING_RESPONSE,
- "Access-Request",
- "Access-Accept",
- "Access-Reject",
- "Accounting-Request",
- "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(radius_attribute_type_names, RAT_USER_NAME, RAT_MIP6_HOME_LINK_PREFIX,
- "User-Name",
- "User-Password",
- "CHAP-Password",
- "NAS-IP-Address",
- "NAS-Port",
- "Service-Type",
- "Framed-Protocol",
- "Framed-IP-Address",
- "Framed-IP-Netmask",
- "Framed-Routing",
- "Filter-Id",
- "Framed-MTU",
- "Framed-Compression",
- "Login-IP-Host",
- "Login-Service",
- "Login-TCP-Port",
- "Unassigned",
- "Reply-Message",
- "Callback-Number",
- "Callback-Id",
- "Unassigned",
- "Framed-Route",
- "Framed-IPX-Network",
- "State",
- "Class",
- "Vendor-Specific",
- "Session-Timeout",
- "Idle-Timeout",
- "Termination-Action",
- "Called-Station-Id",
- "Calling-Station-Id",
- "NAS-Identifier",
- "Proxy-State",
- "Login-LAT-Service",
- "Login-LAT-Node",
- "Login-LAT-Group",
- "Framed-AppleTalk-Link",
- "Framed-AppleTalk-Network",
- "Framed-AppleTalk-Zone",
- "Acct-Status-Type",
- "Acct-Delay-Time",
- "Acct-Input-Octets",
- "Acct-Output-Octets",
- "Acct-Session-Id",
- "Acct-Authentic",
- "Acct-Session-Time",
- "Acct-Input-Packets",
- "Acct-Output-Packets",
- "Acct-Terminate-Cause",
- "Acct-Multi-Session-Id",
- "Acct-Link-Count",
- "Acct-Input-Gigawords",
- "Acct-Output-Gigawords",
- "Unassigned",
- "Event-Timestamp",
- "Egress-VLANID",
- "Ingress-Filters",
- "Egress-VLAN-Name",
- "User-Priority-Table",
- "CHAP-Challenge",
- "NAS-Port-Type",
- "Port-Limit",
- "Login-LAT-Port",
- "Tunnel-Type",
- "Tunnel-Medium-Type",
- "Tunnel-Client-Endpoint",
- "Tunnel-Server-Endpoint",
- "Acct-Tunnel-Connection",
- "Tunnel-Password",
- "ARAP-Password",
- "ARAP-Features",
- "ARAP-Zone-Access",
- "ARAP-Security",
- "ARAP-Security-Data",
- "Password-Retry",
- "Prompt",
- "Connect-Info",
- "Configuration-Token",
- "EAP-Message",
- "Message-Authenticator",
- "Tunnel-Private-Group-ID",
- "Tunnel-Assignment-ID",
- "Tunnel-Preference",
- "ARAP-Challenge-Response",
- "Acct-Interim-Interval",
- "Acct-Tunnel-Packets-Lost",
- "NAS-Port-Id",
- "Framed-Pool",
- "CUI",
- "Tunnel-Client-Auth-ID",
- "Tunnel-Server-Auth-ID",
- "NAS-Filter-Rule",
- "Unassigned",
- "Originating-Line-Info",
- "NAS-IPv6-Address",
- "Framed-Interface-Id",
- "Framed-IPv6-Prefix",
- "Login-IPv6-Host",
- "Framed-IPv6-Route",
- "Framed-IPv6-Pool",
- "Error-Cause",
- "EAP-Key-Name",
- "Digest-Response",
- "Digest-Realm",
- "Digest-Nonce",
- "Digest-Response-Auth",
- "Digest-Nextnonce",
- "Digest-Method",
- "Digest-URI",
- "Digest-Qop",
- "Digest-Algorithm",
- "Digest-Entity-Body-Hash",
- "Digest-CNonce",
- "Digest-Nonce-Count",
- "Digest-Username",
- "Digest-Opaque",
- "Digest-Auth-Param",
- "Digest-AKA-Auts",
- "Digest-Domain",
- "Digest-Stale",
- "Digest-HA1",
- "SIP-AOR",
- "Delegated-IPv6-Prefix",
- "MIP6-Feature-Vector",
- "MIP6-Home-Link-Prefix");
-
-/**
- * Attribute enumerator implementation
- */
-typedef struct {
- /** implements enumerator interface */
- enumerator_t public;
- /** currently pointing attribute */
- rattr_t *next;
- /** bytes left */
- int left;
-} attribute_enumerator_t;
-
-METHOD(enumerator_t, attribute_enumerate, bool,
- attribute_enumerator_t *this, int *type, chunk_t *data)
-{
- if (this->left == 0)
- {
- return FALSE;
- }
- if (this->left < sizeof(rattr_t) ||
- this->left < this->next->length)
- {
- DBG1(DBG_IKE, "RADIUS message truncated");
- return FALSE;
- }
- *type = this->next->type;
- data->ptr = this->next->value;
- data->len = this->next->length - sizeof(rattr_t);
- this->left -= this->next->length;
- this->next = ((void*)this->next) + this->next->length;
- return TRUE;
-}
-
-METHOD(radius_message_t, create_enumerator, enumerator_t*,
- private_radius_message_t *this)
-{
- attribute_enumerator_t *e;
-
- if (ntohs(this->msg->length) < sizeof(rmsg_t) + sizeof(rattr_t))
- {
- return enumerator_create_empty();
- }
- INIT(e,
- .public = {
- .enumerate = (void*)_attribute_enumerate,
- .destroy = (void*)free,
- },
- .next = (rattr_t*)this->msg->attributes,
- .left = ntohs(this->msg->length) - sizeof(rmsg_t),
- );
- return &e->public;
-}
-
-METHOD(radius_message_t, add, void,
- private_radius_message_t *this, radius_attribute_type_t type, chunk_t data)
-{
- rattr_t *attribute;
-
- data.len = min(data.len, 253);
- this->msg = realloc(this->msg,
- ntohs(this->msg->length) + sizeof(rattr_t) + data.len);
- attribute = ((void*)this->msg) + ntohs(this->msg->length);
- attribute->type = type;
- attribute->length = data.len + sizeof(rattr_t);
- memcpy(attribute->value, data.ptr, data.len);
- this->msg->length = htons(ntohs(this->msg->length) + attribute->length);
-}
-
-METHOD(radius_message_t, sign, void,
- private_radius_message_t *this, rng_t *rng, signer_t *signer)
-{
- char buf[HASH_SIZE_MD5];
-
- /* build Request-Authenticator */
- rng->get_bytes(rng, HASH_SIZE_MD5, this->msg->authenticator);
-
- /* 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);
-}
-
-METHOD(radius_message_t, verify, bool,
- private_radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
- hasher_t *hasher, signer_t *signer)
-{
- char buf[HASH_SIZE_MD5], res_auth[HASH_SIZE_MD5];
- enumerator_t *enumerator;
- int type;
- 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))
- {
- DBG1(DBG_CFG, "RADIUS Response-Authenticator verification failed");
- return FALSE;
- }
-
- /* verify Message-Authenticator attribute */
- enumerator = create_enumerator(this);
- while (enumerator->enumerate(enumerator, &type, &data))
- {
- if (type == RAT_MESSAGE_AUTHENTICATOR)
- {
- if (data.len != HASH_SIZE_MD5)
- {
- DBG1(DBG_CFG, "RADIUS Message-Authenticator invalid length");
- enumerator->destroy(enumerator);
- return FALSE;
- }
- memcpy(buf, data.ptr, data.len);
- memset(data.ptr, 0, data.len);
- if (signer->verify_signature(signer, msg,
- chunk_create(buf, sizeof(buf))))
- {
- /* restore Message-Authenticator */
- memcpy(data.ptr, buf, data.len);
- has_auth = TRUE;
- break;
- }
- else
- {
- DBG1(DBG_CFG, "RADIUS Message-Authenticator verification failed");
- enumerator->destroy(enumerator);
- return FALSE;
- }
- }
- else if (type == RAT_EAP_MESSAGE)
- {
- has_eap = TRUE;
- }
- }
- enumerator->destroy(enumerator);
- /* 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 */
- DBG1(DBG_CFG, "RADIUS Message-Authenticator attribute missing");
- return FALSE;
- }
- return TRUE;
-}
-
-METHOD(radius_message_t, get_code, radius_message_code_t,
- private_radius_message_t *this)
-{
- return this->msg->code;
-}
-
-METHOD(radius_message_t, get_identifier, u_int8_t,
- private_radius_message_t *this)
-{
- return this->msg->identifier;
-}
-
-METHOD(radius_message_t, set_identifier, void,
- private_radius_message_t *this, u_int8_t identifier)
-{
- this->msg->identifier = identifier;
-}
-
-METHOD(radius_message_t, get_authenticator, u_int8_t*,
- private_radius_message_t *this)
-{
- return this->msg->authenticator;
-}
-
-
-METHOD(radius_message_t, get_encoding, chunk_t,
- private_radius_message_t *this)
-{
- return chunk_create((u_char*)this->msg, ntohs(this->msg->length));
-}
-
-METHOD(radius_message_t, destroy, void,
- private_radius_message_t *this)
-{
- free(this->msg);
- free(this);
-}
-
-/**
- * Generic constructor
- */
-static private_radius_message_t *radius_message_create()
-{
- private_radius_message_t *this;
-
- INIT(this,
- .public = {
- .create_enumerator = _create_enumerator,
- .add = _add,
- .get_code = _get_code,
- .get_identifier = _get_identifier,
- .set_identifier = _set_identifier,
- .get_authenticator = _get_authenticator,
- .get_encoding = _get_encoding,
- .sign = _sign,
- .verify = _verify,
- .destroy = _destroy,
- },
- );
-
- return this;
-}
-
-/**
- * See header
- */
-radius_message_t *radius_message_create_request()
-{
- private_radius_message_t *this = radius_message_create();
-
- INIT(this->msg,
- .code = RMC_ACCESS_REQUEST,
- .identifier = 0,
- .length = htons(sizeof(rmsg_t)),
- );
-
- return &this->public;
-}
-
-/**
- * See header
- */
-radius_message_t *radius_message_parse_response(chunk_t data)
-{
- private_radius_message_t *this = radius_message_create();
-
- this->msg = malloc(data.len);
- memcpy(this->msg, data.ptr, data.len);
- if (data.len < sizeof(rmsg_t) ||
- ntohs(this->msg->length) != data.len)
- {
- DBG1(DBG_IKE, "RADIUS message has invalid length");
- destroy(this);
- return NULL;
- }
- return &this->public;
-}
-
diff --git a/src/libcharon/plugins/eap_radius/radius_message.h b/src/libcharon/plugins/eap_radius/radius_message.h
deleted file mode 100644
index 266839d3b..000000000
--- a/src/libcharon/plugins/eap_radius/radius_message.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2009 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup radius_message radius_message
- * @{ @ingroup eap_radius
- */
-
-#ifndef RADIUS_MESSAGE_H_
-#define RADIUS_MESSAGE_H_
-
-#include <library.h>
-
-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;
-
-/**
- * RADIUS Message Codes.
- */
-enum radius_message_code_t {
- RMC_ACCESS_REQUEST = 1,
- RMC_ACCESS_ACCEPT = 2,
- RMC_ACCESS_REJECT = 3,
- RMC_ACCOUNTING_REQUEST = 4,
- RMC_ACCOUNTING_RESPONSE = 5,
- RMC_ACCESS_CHALLENGE = 11,
-};
-
-/**
- * Enum names for radius_attribute_type_t.
- */
-extern enum_name_t *radius_message_code_names;
-
-/**
- * RADIUS Attribute Types.
- */
-enum radius_attribute_type_t {
- RAT_USER_NAME = 1,
- RAT_USER_PASSWORD = 2,
- RAT_CHAP_PASSWORD = 3,
- RAT_NAS_IP_ADDRESS = 4,
- RAT_NAS_PORT = 5,
- RAT_SERVICE_TYPE = 6,
- RAT_FRAMED_PROTOCOL = 7,
- RAT_FRAMED_IP_ADDRESS = 8,
- RAT_FRAMED_IP_NETMASK = 9,
- RAT_FRAMED_ROUTING = 10,
- RAT_FILTER_ID = 11,
- RAT_FRAMED_MTU = 12,
- RAT_FRAMED_COMPRESSION = 13,
- RAT_LOGIN_IP_HOST = 14,
- RAT_LOGIN_SERVICE = 15,
- RAT_LOGIN_TCP_PORT = 16,
- RAT_REPLY_MESSAGE = 18,
- RAT_CALLBACK_NUMBER = 19,
- RAT_CALLBACK_ID = 20,
- RAT_FRAMED_ROUTE = 22,
- RAT_FRAMED_IPX_NETWORK = 23,
- RAT_STATE = 24,
- RAT_CLASS = 25,
- RAT_VENDOR_SPECIFIC = 26,
- RAT_SESSION_TIMEOUT = 27,
- RAT_IDLE_TIMEOUT = 28,
- RAT_TERMINATION_ACTION = 29,
- RAT_CALLED_STATION_ID = 30,
- RAT_CALLING_STATION_ID = 31,
- RAT_NAS_IDENTIFIER = 32,
- RAT_PROXY_STATE = 33,
- RAT_LOGIN_LAT_SERVICE = 34,
- RAT_LOGIN_LAT_NODE = 35,
- RAT_LOGIN_LAT_GROUP = 36,
- RAT_FRAMED_APPLETALK_LINK = 37,
- RAT_FRAMED_APPLETALK_NETWORK = 38,
- RAT_FRAMED_APPLETALK_ZONE = 39,
- RAT_ACCT_STATUS_TYPE = 40,
- RAT_ACCT_DELAY_TIME = 41,
- RAT_ACCT_INPUT_OCTETS = 42,
- RAT_ACCT_OUTPUT_OCTETS = 43,
- RAT_ACCT_SESSION_ID = 44,
- RAT_ACCT_AUTHENTIC = 45,
- RAT_ACCT_SESSION_TIME = 46,
- RAT_ACCT_INPUT_PACKETS = 47,
- RAT_ACCT_OUTPUT_PACKETS = 48,
- RAT_ACCT_TERMINATE_CAUSE = 49,
- RAT_ACCT_MULTI_SESSION_ID = 50,
- RAT_ACCT_LINK_COUNT = 51,
- RAT_ACCT_INPUT_GIGAWORDS = 52,
- RAT_ACCT_OUTPUT_GIGAWORDS = 53,
- RAT_EVENT_TIMESTAMP = 55,
- RAT_EGRESS_VLANID = 56,
- RAT_INGRESS_FILTERS = 57,
- RAT_EGRESS_VLAN_NAME = 58,
- RAT_USER_PRIORITY_TABLE = 59,
- RAT_CHAP_CHALLENGE = 60,
- RAT_NAS_PORT_TYPE = 61,
- RAT_PORT_LIMIT = 62,
- RAT_LOGIN_LAT_PORT = 63,
- RAT_TUNNEL_TYPE = 64,
- RAT_TUNNEL_MEDIUM_TYPE = 65,
- RAT_TUNNEL_CLIENT_ENDPOINT = 66,
- RAT_TUNNEL_SERVER_ENDPOINT = 67,
- RAT_ACCT_TUNNEL_CONNECTION = 68,
- RAT_TUNNEL_PASSWORD = 69,
- RAT_ARAP_PASSWORD = 70,
- RAT_ARAP_FEATURES = 71,
- RAT_ARAP_ZONE_ACCESS = 72,
- RAT_ARAP_SECURITY = 73,
- RAT_ARAP_SECURITY_DATA = 74,
- RAT_PASSWORD_RETRY = 75,
- RAT_PROMPT = 76,
- RAT_CONNECT_INFO = 77,
- RAT_CONFIGURATION_TOKEN = 78,
- RAT_EAP_MESSAGE = 79,
- RAT_MESSAGE_AUTHENTICATOR = 80,
- RAT_TUNNEL_PRIVATE_GROUP_ID = 81,
- RAT_TUNNEL_ASSIGNMENT_ID = 82,
- RAT_TUNNEL_PREFERENCE = 83,
- RAT_ARAP_CHALLENGE_RESPONSE = 84,
- RAT_ACCT_INTERIM_INTERVAL = 85,
- RAT_ACCT_TUNNEL_PACKETS_LOST = 86,
- RAT_NAS_PORT_ID = 87,
- RAT_FRAMED_POOL = 88,
- RAT_CUI = 89,
- RAT_TUNNEL_CLIENT_AUTH_ID = 90,
- RAT_TUNNEL_SERVER_AUTH_ID = 91,
- RAT_NAS_FILTER_RULE = 92,
- RAT_UNASSIGNED = 93,
- RAT_ORIGINATING_LINE_INFO = 94,
- RAT_NAS_IPV6_ADDRESS = 95,
- RAT_FRAMED_INTERFACE_ID = 96,
- RAT_FRAMED_IPV6_PREFIX = 97,
- RAT_LOGIN_IPV6_HOST = 98,
- RAT_FRAMED_IPV6_ROUTE = 99,
- RAT_FRAMED_IPV6_POOL = 100,
- RAT_ERROR_CAUSE = 101,
- RAT_EAP_KEY_NAME = 102,
- RAT_DIGEST_RESPONSE = 103,
- RAT_DIGEST_REALM = 104,
- RAT_DIGEST_NONCE = 105,
- RAT_DIGEST_RESPONSE_AUTH = 106,
- RAT_DIGEST_NEXTNONCE = 107,
- RAT_DIGEST_METHOD = 108,
- RAT_DIGEST_URI = 109,
- RAT_DIGEST_QOP = 110,
- RAT_DIGEST_ALGORITHM = 111,
- RAT_DIGEST_ENTITY_BODY_HASH = 112,
- RAT_DIGEST_CNONCE = 113,
- RAT_DIGEST_NONCE_COUNT = 114,
- RAT_DIGEST_USERNAME = 115,
- RAT_DIGEST_OPAQUE = 116,
- RAT_DIGEST_AUTH_PARAM = 117,
- RAT_DIGEST_AKA_AUTS = 118,
- RAT_DIGEST_DOMAIN = 119,
- RAT_DIGEST_STALE = 120,
- RAT_DIGEST_HA1 = 121,
- RAT_SIP_AOR = 122,
- RAT_DELEGATED_IPV6_PREFIX = 123,
- RAT_MIP6_FEATURE_VECTOR = 124,
- RAT_MIP6_HOME_LINK_PREFIX = 125,
-};
-
-/**
- * Enum names for radius_attribute_type_t.
- */
-extern enum_name_t *radius_attribute_type_names;
-
-/**
- * A RADIUS message, contains attributes.
- */
-struct radius_message_t {
-
- /**
- * Create an enumerator over contained RADIUS attributes.
- *
- * @return enumerator over (int type, chunk_t data)
- */
- enumerator_t* (*create_enumerator)(radius_message_t *this);
-
- /**
- * Add a RADIUS attribute to the message.
- *
- * @param type type of attribute to add
- * @param attribute data, gets cloned
- */
- void (*add)(radius_message_t *this, radius_attribute_type_t type,
- chunk_t data);
-
- /**
- * Get the message type (code).
- *
- * @return message code
- */
- radius_message_code_t (*get_code)(radius_message_t *this);
-
- /**
- * Get the message identifier.
- *
- * @return message identifier
- */
- u_int8_t (*get_identifier)(radius_message_t *this);
-
- /**
- * Set the message identifier.
- *
- * @param identifier message identifier
- */
- void (*set_identifier)(radius_message_t *this, u_int8_t identifier);
-
- /**
- * Get the 16 byte authenticator.
- *
- * @return pointer to the Authenticator field
- */
- u_int8_t* (*get_authenticator)(radius_message_t *this);
-
- /**
- * Get the RADIUS message in its encoded form.
- *
- * @return chunk pointing to internal RADIUS message.
- */
- chunk_t (*get_encoding)(radius_message_t *this);
-
- /**
- * Calculate and add the Message-Authenticator attribute to the message.
- *
- * @param rng RNG to create Request-Authenticator
- * @param signer HMAC-MD5 signer with secret set
- */
- void (*sign)(radius_message_t *this, rng_t *rng, signer_t *signer);
-
- /**
- * Verify the integrity of a received RADIUS response.
- *
- * @param req_auth 16 byte Authenticator of the corresponding request
- * @param secret shared RADIUS secret
- * @param hasher hasher to verify Response-Authenticator
- * @param signer signer to verify Message-Authenticator attribute
- */
- bool (*verify)(radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
- hasher_t *hasher, signer_t *signer);
-
- /**
- * Destroy the message.
- */
- void (*destroy)(radius_message_t *this);
-};
-
-/**
- * Create an empty RADIUS request message (RMT_ACCESS_REQUEST).
- *
- * @return radius_message_t object
- */
-radius_message_t *radius_message_create_request();
-
-/**
- * Parse and verify a recevied RADIUS response.
- *
- * @param data received message data
- * @return radius_message_t object, NULL if length invalid
- */
-radius_message_t *radius_message_parse_response(chunk_t data);
-
-#endif /** RADIUS_MESSAGE_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/radius_server.c b/src/libcharon/plugins/eap_radius/radius_server.c
deleted file mode 100644
index 3baf39807..000000000
--- a/src/libcharon/plugins/eap_radius/radius_server.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "radius_server.h"
-
-#include <threading/mutex.h>
-#include <threading/condvar.h>
-#include <utils/linked_list.h>
-
-typedef struct private_radius_server_t private_radius_server_t;
-
-/**
- * Private data of an radius_server_t object.
- */
-struct private_radius_server_t {
-
- /**
- * Public radius_server_t interface.
- */
- radius_server_t public;
-
- /**
- * list of radius sockets, as radius_socket_t
- */
- linked_list_t *sockets;
-
- /**
- * Total number of sockets, in list + currently in use
- */
- int socket_count;
-
- /**
- * mutex to lock sockets list
- */
- mutex_t *mutex;
-
- /**
- * condvar to wait for sockets
- */
- condvar_t *condvar;
-
- /**
- * Server name
- */
- char *name;
-
- /**
- * NAS-Identifier
- */
- chunk_t nas_identifier;
-
- /**
- * Preference boost for this server
- */
- int preference;
-
- /**
- * Is the server currently reachable
- */
- bool reachable;
-
- /**
- * Retry counter for unreachable servers
- */
- int retry;
-
- /**
- * reference count
- */
- refcount_t ref;
-};
-
-METHOD(radius_server_t, get_socket, radius_socket_t*,
- private_radius_server_t *this)
-{
- radius_socket_t *skt;
-
- this->mutex->lock(this->mutex);
- while (this->sockets->remove_first(this->sockets, (void**)&skt) != SUCCESS)
- {
- this->condvar->wait(this->condvar, this->mutex);
- }
- this->mutex->unlock(this->mutex);
- return skt;
-}
-
-METHOD(radius_server_t, put_socket, void,
- private_radius_server_t *this, radius_socket_t *skt, bool result)
-{
- this->mutex->lock(this->mutex);
- this->sockets->insert_last(this->sockets, skt);
- this->mutex->unlock(this->mutex);
- this->condvar->signal(this->condvar);
- this->reachable = result;
-}
-
-METHOD(radius_server_t, get_nas_identifier, chunk_t,
- private_radius_server_t *this)
-{
- return this->nas_identifier;
-}
-
-METHOD(radius_server_t, get_preference, int,
- private_radius_server_t *this)
-{
- int pref;
-
- if (this->socket_count == 0)
- { /* don't have sockets, huh? */
- return -1;
- }
- /* calculate preference between 0-100 + boost */
- pref = this->preference;
- pref += this->sockets->get_count(this->sockets) * 100 / this->socket_count;
- if (this->reachable)
- { /* reachable server get a boost: pref = 110-210 + boost */
- return pref + 110;
- }
- /* Not reachable. Increase preference randomly to let it retry from
- * time to time, especially if other servers have high load. */
- this->retry++;
- if (this->retry % 128 == 0)
- { /* every 64th request gets 210, same as unloaded reachable */
- return pref + 110;
- }
- if (this->retry % 32 == 0)
- { /* every 32th request gets 190, wins against average loaded */
- return pref + 90;
- }
- if (this->retry % 8 == 0)
- { /* every 8th request gets 110, same as server under load */
- return pref + 10;
- }
- /* other get ~100, less than fully loaded */
- return pref;
-}
-
-METHOD(radius_server_t, get_name, char*,
- private_radius_server_t *this)
-{
- return this->name;
-}
-
-METHOD(radius_server_t, get_ref, radius_server_t*,
- private_radius_server_t *this)
-{
- ref_get(&this->ref);
- return &this->public;
-}
-
-
-METHOD(radius_server_t, destroy, void,
- private_radius_server_t *this)
-{
- if (ref_put(&this->ref))
- {
- this->mutex->destroy(this->mutex);
- this->condvar->destroy(this->condvar);
- this->sockets->destroy_offset(this->sockets,
- offsetof(radius_socket_t, destroy));
- free(this);
- }
-}
-
-/**
- * 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)
-{
- private_radius_server_t *this;
- radius_socket_t *socket;
-
- INIT(this,
- .public = {
- .get_socket = _get_socket,
- .put_socket = _put_socket,
- .get_nas_identifier = _get_nas_identifier,
- .get_preference = _get_preference,
- .get_name = _get_name,
- .get_ref = _get_ref,
- .destroy = _destroy,
- },
- .reachable = TRUE,
- .nas_identifier = chunk_create(nas_identifier, strlen(nas_identifier)),
- .socket_count = sockets,
- .sockets = linked_list_create(),
- .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
- .condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
- .name = name,
- .preference = preference,
- .ref = 1,
- );
-
- while (sockets--)
- {
- socket = radius_socket_create(address, port,
- chunk_create(secret, strlen(secret)));
- if (!socket)
- {
- destroy(this);
- return NULL;
- }
- this->sockets->insert_last(this->sockets, socket);
- }
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_radius/radius_server.h b/src/libcharon/plugins/eap_radius/radius_server.h
deleted file mode 100644
index c59361c49..000000000
--- a/src/libcharon/plugins/eap_radius/radius_server.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup radius_server radius_server
- * @{ @ingroup eap_radius
- */
-
-#ifndef RADIUS_SERVER_H_
-#define RADIUS_SERVER_H_
-
-typedef struct radius_server_t radius_server_t;
-
-#include "radius_socket.h"
-
-/**
- * RADIUS server configuration.
- */
-struct radius_server_t {
-
- /**
- * Get a RADIUS socket from the pool to communicate with this server.
- *
- * @return RADIUS socket
- */
- radius_socket_t* (*get_socket)(radius_server_t *this);
-
- /**
- * Release a socket to the pool after use.
- *
- * @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);
-
- /**
- * Get the NAS-Identifier to use with this server.
- *
- * @return NAS-Identifier, internal data
- */
- chunk_t (*get_nas_identifier)(radius_server_t *this);
-
- /**
- * Get the preference of this server.
- *
- * 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);
-
- /**
- * Get the name of the RADIUS server.
- *
- * @return server name
- */
- char* (*get_name)(radius_server_t *this);
-
- /**
- * Increase reference count of this server.
- *
- * @return this
- */
- radius_server_t* (*get_ref)(radius_server_t *this);
-
- /**
- * Destroy a radius_server_t.
- */
- void (*destroy)(radius_server_t *this);
-};
-
-/**
- * Create a radius_server instance.
- *
- * @param name server name
- * @param address server address
- * @param port server port
- * @param nas_identifier NAS-Identifier to use with this server
- * @param secret secret to use with this server
- * @param sockets number of sockets to create in pool
- * @param preference preference boost for this server
- */
-radius_server_t *radius_server_create(char *name, char *address, u_int16_t port,
- char *nas_identifier, char *secret, int sockets, int preference);
-
-#endif /** RADIUS_SERVER_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/radius_socket.c b/src/libcharon/plugins/eap_radius/radius_socket.c
deleted file mode 100644
index b3229c288..000000000
--- a/src/libcharon/plugins/eap_radius/radius_socket.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "radius_socket.h"
-
-#include <errno.h>
-#include <unistd.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;
-
-/**
- * Private data of an radius_socket_t object.
- */
-struct private_radius_socket_t {
-
- /**
- * Public radius_socket_t interface.
- */
- radius_socket_t public;
-
- /**
- * socket file descriptor
- */
- int fd;
-
- /**
- * Server address
- */
- char *address;
-
- /**
- * Server port
- */
- u_int16_t port;
-
- /**
- * current RADIUS identifier
- */
- u_int8_t identifier;
-
- /**
- * hasher to use for response verification
- */
- hasher_t *hasher;
-
- /**
- * HMAC-MD5 signer to build Message-Authenticator attribute
- */
- signer_t *signer;
-
- /**
- * random number generator for RADIUS request authenticator
- */
- rng_t *rng;
-
- /**
- * RADIUS secret
- */
- chunk_t secret;
-};
-
-/**
- * Check or establish RADIUS connection
- */
-static bool check_connection(private_radius_socket_t *this)
-{
- if (this->fd == -1)
- {
- host_t *server;
-
- server = host_create_from_dns(this->address, AF_UNSPEC, this->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)
- {
- 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),
- *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;
- return FALSE;
- }
- server->destroy(server);
- }
- return TRUE;
-}
-
-METHOD(radius_socket_t, request, radius_message_t*,
- private_radius_socket_t *this, radius_message_t *request)
-{
- chunk_t data;
- int i;
-
- /* set Message Identifier */
- request->set_identifier(request, this->identifier++);
- /* sign the request */
- request->sign(request, this->rng, this->signer);
-
- if (!check_connection(this))
- {
- return NULL;
- }
-
- data = request->get_encoding(request);
- /* timeout after 2, 3, 4, 5 seconds */
- for (i = 2; i <= 5; i++)
- {
- radius_message_t *response;
- bool retransmit = FALSE;
- struct timeval tv;
- char buf[4096];
- fd_set fds;
- int res;
-
- if (send(this->fd, data.ptr, data.len, 0) != data.len)
- {
- DBG1(DBG_CFG, "sending RADIUS message failed: %s", strerror(errno));
- return NULL;
- }
- tv.tv_sec = i;
- tv.tv_usec = 0;
-
- while (TRUE)
- {
- FD_ZERO(&fds);
- FD_SET(this->fd, &fds);
- res = select(this->fd + 1, &fds, NULL, NULL, &tv);
- /* TODO: updated tv to time not waited. Linux does this for us. */
- if (res < 0)
- { /* failed */
- DBG1(DBG_CFG, "waiting for RADIUS message failed: %s",
- strerror(errno));
- break;
- }
- if (res == 0)
- { /* timeout */
- DBG1(DBG_CFG, "retransmitting RADIUS message");
- retransmit = TRUE;
- break;
- }
- res = recv(this->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));
- if (response)
- {
- if (response->verify(response,
- request->get_authenticator(request), this->secret,
- this->hasher, this->signer))
- {
- return response;
- }
- response->destroy(response);
- }
- DBG1(DBG_CFG, "received invalid RADIUS message, ignored");
- }
- if (!retransmit)
- {
- break;
- }
- }
- DBG1(DBG_CFG, "RADIUS server is not responding");
- return NULL;
-}
-
-/**
- * Decrypt a MS-MPPE-Send/Recv-Key
- */
-static chunk_t decrypt_mppe_key(private_radius_socket_t *this, u_int16_t salt,
- chunk_t C, radius_message_t *request)
-{
- chunk_t A, R, P, seed;
- u_char *c, *p;
-
- /**
- * 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)
- */
-
- if (C.len % HASH_SIZE_MD5 || C.len < HASH_SIZE_MD5)
- {
- return chunk_empty;
- }
-
- A = chunk_create((u_char*)&salt, sizeof(salt));
- R = chunk_create(request->get_authenticator(request), HASH_SIZE_MD5);
- P = chunk_alloca(C.len);
- p = P.ptr;
- c = C.ptr;
-
- seed = chunk_cata("cc", R, A);
-
- while (c < C.ptr + C.len)
- {
- /* b(i) = MD5(S + c(i-1)) */
- this->hasher->get_hash(this->hasher, this->secret, NULL);
- this->hasher->get_hash(this->hasher, seed, p);
-
- /* p(i) = b(i) xor c(1) */
- memxor(p, c, HASH_SIZE_MD5);
-
- /* prepare next round */
- seed = chunk_create(c, HASH_SIZE_MD5);
- c += HASH_SIZE_MD5;
- p += HASH_SIZE_MD5;
- }
-
- /* remove truncation, first byte is key length */
- if (*P.ptr >= P.len)
- { /* decryption failed? */
- return chunk_empty;
- }
- return chunk_clone(chunk_create(P.ptr + 1, *P.ptr));
-}
-
-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;
- enumerator_t *enumerator;
- chunk_t data, send = chunk_empty, recv = chunk_empty;
- int type;
-
- enumerator = response->create_enumerator(response);
- while (enumerator->enumerate(enumerator, &type, &data))
- {
- if (type == RAT_VENDOR_SPECIFIC &&
- data.len > sizeof(*mppe_key))
- {
- mppe_key = (void*)data.ptr;
- if (ntohl(mppe_key->id) == VENDOR_ID_MICROSOFT &&
- mppe_key->length == data.len - sizeof(mppe_key->id))
- {
- data = chunk_create(mppe_key->key, data.len - sizeof(*mppe_key));
- if (mppe_key->type == MS_MPPE_SEND_KEY)
- {
- send = decrypt_mppe_key(this, mppe_key->salt, data, request);
- }
- if (mppe_key->type == MS_MPPE_RECV_KEY)
- {
- recv = decrypt_mppe_key(this, mppe_key->salt, data, request);
- }
- }
- }
- }
- enumerator->destroy(enumerator);
- if (send.ptr && recv.ptr)
- {
- return chunk_cat("mm", recv, send);
- }
- chunk_clear(&send);
- chunk_clear(&recv);
- return chunk_empty;
-}
-
-METHOD(radius_socket_t, destroy, void,
- private_radius_socket_t *this)
-{
- DESTROY_IF(this->hasher);
- DESTROY_IF(this->signer);
- DESTROY_IF(this->rng);
- if (this->fd != -1)
- {
- close(this->fd);
- }
- free(this);
-}
-
-/**
- * See header
- */
-radius_socket_t *radius_socket_create(char *address, u_int16_t port,
- chunk_t secret)
-{
- private_radius_socket_t *this;
-
- INIT(this,
- .public = {
- .request = _request,
- .decrypt_msk = _decrypt_msk,
- .destroy = _destroy,
- },
- .address = address,
- .port = port,
- .fd = -1,
- );
-
- 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");
- destroy(this);
- return NULL;
- }
- this->secret = secret;
- this->signer->set_key(this->signer, secret);
- /* we use a random identifier, helps if we restart often */
- this->identifier = random();
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_radius/radius_socket.h b/src/libcharon/plugins/eap_radius/radius_socket.h
deleted file mode 100644
index 2875008eb..000000000
--- a/src/libcharon/plugins/eap_radius/radius_socket.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup radius_socket radius_socket
- * @{ @ingroup eap_radius
- */
-
-#ifndef RADIUS_SOCKET_H_
-#define RADIUS_SOCKET_H_
-
-typedef struct radius_socket_t radius_socket_t;
-
-#include "radius_message.h"
-
-#include <utils/host.h>
-
-/**
- * RADIUS socket to a server.
- */
-struct radius_socket_t {
-
- /**
- * Send a RADIUS request, wait for response.
- *
- * The socket fills in RADIUS Message identifier, builds a
- * Request-Authenticator and calculates the Message-Authenticator
- * attribute.
- * The received response gets verified using the Response-Identifier
- * and the Message-Authenticator attribute.
- *
- * @param request request message
- * @return response message, NULL if timed out
- */
- radius_message_t* (*request)(radius_socket_t *this,
- radius_message_t *request);
-
- /**
- * Decrypt the MSK encoded in a messages MS-MPPE-Send/Recv-Key.
- *
- * @param request associated RADIUS request message
- * @param response RADIUS response message containing attributes
- * @return allocated MSK, empty chunk if none found
- */
- chunk_t (*decrypt_msk)(radius_socket_t *this, radius_message_t *request,
- radius_message_t *response);
-
- /**
- * Destroy a radius_socket_t.
- */
- void (*destroy)(radius_socket_t *this);
-};
-
-/**
- * Create a radius_socket instance.
- *
- * @param address server name
- * @param port server port
- * @param secret RADIUS secret
- */
-radius_socket_t *radius_socket_create(char *address, u_int16_t port,
- chunk_t secret);
-
-#endif /** RADIUS_SOCKET_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/plugins/tnc_tnccs/tnc_tnccs_manager.c b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.c
new file mode 100644
index 000000000..64ed160d9
--- /dev/null
+++ b/src/libcharon/plugins/tnc_tnccs/tnc_tnccs_manager.c
@@ -0,0 +1,712 @@
+/*
+ * 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_manager.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 <utils/linked_list.h>
+#include <threading/rwlock.h>
+
+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;
+
+/**
+ * TNCCS constructor entry
+ */
+struct tnccs_entry_t {
+
+ /**
+ * TNCCS protocol type
+ */
+ tnccs_type_t type;
+
+ /**
+ * constructor function to create instance
+ */
+ tnccs_constructor_t constructor;
+};
+
+/**
+ * TNCCS connection entry
+ */
+struct tnccs_connection_entry_t {
+
+ /**
+ * TNCCS connection ID
+ */
+ TNC_ConnectionID id;
+
+ /**
+ * TNCCS protocol type
+ */
+ tnccs_type_t type;
+
+ /**
+ * TNCCS instance
+ */
+ tnccs_t *tnccs;
+
+ /**
+ * TNCCS send message function
+ */
+ tnccs_send_message_t send_message;
+
+ /**
+ * TNCCS request handshake retry flag
+ */
+ bool *request_handshake_retry;
+
+ /**
+ * collection of IMV recommendations
+ */
+ recommendations_t *recs;
+};
+
+/**
+ * private data of tnc_tnccs_manager
+ */
+struct private_tnc_tnccs_manager_t {
+
+ /**
+ * public functions
+ */
+ tnccs_manager_t public;
+
+ /**
+ * list of TNCCS protocol entries
+ */
+ linked_list_t *protocols;
+
+ /**
+ * rwlock to lock the TNCCS protocol entries
+ */
+ rwlock_t *protocol_lock;
+
+ /**
+ * connection ID counter
+ */
+ TNC_ConnectionID connection_id;
+
+ /**
+ * list of TNCCS connection entries
+ */
+ linked_list_t *connections;
+
+ /**
+ * rwlock to lock TNCCS connection entries
+ */
+ rwlock_t *connection_lock;
+
+};
+
+METHOD(tnccs_manager_t, add_method, void,
+ private_tnc_tnccs_manager_t *this, tnccs_type_t type,
+ tnccs_constructor_t constructor)
+{
+ tnccs_entry_t *entry;
+
+ entry = malloc_thing(tnccs_entry_t);
+ entry->type = type;
+ entry->constructor = constructor;
+
+ this->protocol_lock->write_lock(this->protocol_lock);
+ this->protocols->insert_last(this->protocols, entry);
+ this->protocol_lock->unlock(this->protocol_lock);
+}
+
+METHOD(tnccs_manager_t, remove_method, void,
+ private_tnc_tnccs_manager_t *this, tnccs_constructor_t constructor)
+{
+ enumerator_t *enumerator;
+ tnccs_entry_t *entry;
+
+ this->protocol_lock->write_lock(this->protocol_lock);
+ enumerator = this->protocols->create_enumerator(this->protocols);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (constructor == entry->constructor)
+ {
+ this->protocols->remove_at(this->protocols, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->protocol_lock->unlock(this->protocol_lock);
+}
+
+METHOD(tnccs_manager_t, create_instance, tnccs_t*,
+ private_tnc_tnccs_manager_t *this, tnccs_type_t type, bool is_server)
+{
+ enumerator_t *enumerator;
+ tnccs_entry_t *entry;
+ tnccs_t *protocol = NULL;
+
+ this->protocol_lock->read_lock(this->protocol_lock);
+ enumerator = this->protocols->create_enumerator(this->protocols);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (type == entry->type)
+ {
+ protocol = entry->constructor(is_server);
+ if (protocol)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->protocol_lock->unlock(this->protocol_lock);
+
+ return protocol;
+}
+
+METHOD(tnccs_manager_t, create_connection, TNC_ConnectionID,
+ 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 (!tnc->imvs)
+ {
+ DBG1(DBG_TNC, "no IMV manager available!");
+ free(entry);
+ return 0;
+ }
+ entry->recs = tnc->imvs->create_recommendations(tnc->imvs);
+ *recs = entry->recs;
+ }
+ else
+ {
+ /* we assume a TNC Client */
+ if (!tnc->imcs)
+ {
+ DBG1(DBG_TNC, "no IMC manager available!");
+ free(entry);
+ return 0;
+ }
+ entry->recs = NULL;
+ }
+ this->connection_lock->write_lock(this->connection_lock);
+ entry->id = ++this->connection_id;
+ this->connections->insert_last(this->connections, entry);
+ this->connection_lock->unlock(this->connection_lock);
+
+ DBG1(DBG_TNC, "assigned TNCCS Connection ID %u", entry->id);
+ return entry->id;
+}
+
+METHOD(tnccs_manager_t, remove_connection, void,
+ private_tnc_tnccs_manager_t *this, TNC_ConnectionID id, bool is_server)
+{
+ enumerator_t *enumerator;
+ tnccs_connection_entry_t *entry;
+
+ if (is_server)
+ {
+ if (tnc->imvs)
+ {
+ tnc->imvs->notify_connection_change(tnc->imvs, id,
+ TNC_CONNECTION_STATE_DELETE);
+ }
+ }
+ else
+ {
+ if (tnc->imcs)
+ {
+ tnc->imcs->notify_connection_change(tnc->imcs, id,
+ TNC_CONNECTION_STATE_DELETE);
+ }
+ }
+
+ this->connection_lock->write_lock(this->connection_lock);
+ enumerator = this->connections->create_enumerator(this->connections);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (id == entry->id)
+ {
+ this->connections->remove_at(this->connections, enumerator);
+ if (entry->recs)
+ {
+ entry->recs->destroy(entry->recs);
+ }
+ free(entry);
+ DBG1(DBG_TNC, "removed TNCCS Connection ID %u", id);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->connection_lock->unlock(this->connection_lock);
+}
+
+METHOD(tnccs_manager_t, request_handshake_retry, TNC_Result,
+ 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;
+
+ if (id == TNC_CONNECTIONID_ANY)
+ {
+ DBG2(DBG_TNC, "%s %u requests handshake retry for all connections "
+ "(reason: %u)", is_imc ? "IMC":"IMV", reason);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "%s %u requests handshake retry for Connection ID %u "
+ "(reason: %u)", is_imc ? "IMC":"IMV", imcv_id, id, reason);
+ }
+ this->connection_lock->read_lock(this->connection_lock);
+ enumerator = this->connections->create_enumerator(this->connections);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (id == TNC_CONNECTIONID_ANY || id == entry->id)
+ {
+ *entry->request_handshake_retry = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->connection_lock->unlock(this->connection_lock);
+
+ return TNC_RESULT_SUCCESS;
+}
+
+METHOD(tnccs_manager_t, send_message, TNC_Result,
+ 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;
+
+ if (msg_vid == TNC_VENDORID_ANY || msg_subtype == TNC_SUBTYPE_ANY)
+ {
+ DBG1(DBG_TNC, "not sending message of invalid type 0x%02x/0x%08x",
+ msg_vid, msg_subtype);
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+
+ this->connection_lock->read_lock(this->connection_lock);
+ enumerator = this->connections->create_enumerator(this->connections);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (id == entry->id)
+ {
+ tnccs = entry->tnccs;
+ send_message = entry->send_message;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->connection_lock->unlock(this->connection_lock);
+
+ if (tnccs && send_message)
+ {
+ 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_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;
+ recommendations_t *recs = NULL;
+
+ this->connection_lock->read_lock(this->connection_lock);
+ enumerator = this->connections->create_enumerator(this->connections);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (id == entry->id)
+ {
+ recs = entry->recs;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->connection_lock->unlock(this->connection_lock);
+
+ if (recs)
+ {
+ recs->provide_recommendation(recs, imv_id, rec, eval);
+ return TNC_RESULT_SUCCESS;
+ }
+ 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_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;
+ 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;
+
+ /* 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;
+ }
+
+ this->connection_lock->read_lock(this->connection_lock);
+ enumerator = this->connections->create_enumerator(this->connections);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (id == entry->id)
+ {
+ entry_found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->connection_lock->unlock(this->connection_lock);
+
+ if (!entry_found)
+ {
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+
+ switch (attribute_id)
+ {
+ case TNC_ATTRIBUTEID_PREFERRED_LANGUAGE:
+ {
+ 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;
+ }
+ 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:
+ {
+ 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);
+ }
+ 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;
+ }
+}
+
+METHOD(tnccs_manager_t, set_attribute, TNC_Result,
+ 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 (is_imc || id == TNC_CONNECTIONID_ANY ||
+ (attribute_id != TNC_ATTRIBUTEID_REASON_STRING &&
+ attribute_id != TNC_ATTRIBUTEID_REASON_LANGUAGE))
+ {
+ return TNC_RESULT_INVALID_PARAMETER;
+ }
+
+ this->connection_lock->read_lock(this->connection_lock);
+ enumerator = this->connections->create_enumerator(this->connections);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (id == entry->id)
+ {
+ recs = entry->recs;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->connection_lock->unlock(this->connection_lock);
+
+ if (recs)
+ {
+ chunk_t attribute = { buffer, buffer_len };
+
+ if (attribute_id == TNC_ATTRIBUTEID_REASON_STRING)
+ {
+ return recs->set_reason_string(recs, imcv_id, attribute);
+ }
+ else
+ {
+ return recs->set_reason_language(recs, imcv_id, attribute);
+ }
+ }
+ return TNC_RESULT_INVALID_PARAMETER;
+}
+
+METHOD(tnccs_manager_t, destroy, void,
+ private_tnc_tnccs_manager_t *this)
+{
+ this->protocols->destroy_function(this->protocols, free);
+ this->protocol_lock->destroy(this->protocol_lock);
+ this->connections->destroy_function(this->connections, free);
+ this->connection_lock->destroy(this->connection_lock);
+ free(this);
+}
+
+/*
+ * See header
+ */
+tnccs_manager_t *tnc_tnccs_manager_create()
+{
+ private_tnc_tnccs_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .add_method = _add_method,
+ .remove_method = _remove_method,
+ .create_instance = _create_instance,
+ .create_connection = _create_connection,
+ .remove_connection = _remove_connection,
+ .request_handshake_retry = _request_handshake_retry,
+ .send_message = _send_message,
+ .provide_recommendation = _provide_recommendation,
+ .get_attribute = _get_attribute,
+ .set_attribute = _set_attribute,
+ .destroy = _destroy,
+ },
+ .protocols = linked_list_create(),
+ .connections = linked_list_create(),
+ .protocol_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ .connection_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
+
+ return &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;